我正在制作一个可视化,显示给定城市中音乐会最常见的流派。目前我正在使用 d3 面积图显示数据。
为了使可视化在主题上更加合适,我想我应该尝试使其看起来类似于音频波形,而这正是我遇到的一个绊脚石。
目前我仍在使用在 x 轴上镜像的面积图,当数据分布在相当长的时间内时,这对于某些城市来说看起来不错。然而,当看着一个有很多事件的大城市时,它看起来不太正确。
我想我想做的是在面积图的边界内绘制较小的矩形,首先我想我可以使用面积SVG作为 mask ,但是矩形的顶部最终会倾斜......
还考虑过为每个数据点制作一个包含多个条形的条形图,但我认为这会导致每个点之间发生很大的变化。我希望仍然保留从面积/折线图获得的数据点之间的倾斜。
有人有什么建议吗?我的目标是获得如下所示的可视化效果:
最佳答案
一种方法是使用数据不用于创建图表,而是用于创建锯齿状线性刻度 x -> y。接下来,生成所需数量的矩形,并将它们的索引映射到 x 位置。剩下的很简单——检查索引,将它们映射到 x,将获得的 x 映射到 y,然后就完成了。
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
var data = [{
x: 1,
y: 2
}, {
x: 5,
y: 10
}, {
x: 15,
y: 5
}, {
x: 20,
y: 13
}, {
x: 25,
y: 4
}];
var rectCount = 8;
var yScale = d3.scaleLinear()
.domain(data.map(function(d){ return d.x; }))
.range(data.map(function(d){ return d.y; }));
var xScale = d3.scaleBand()
.domain(d3.range(rectCount))
.paddingInner(0.5)
.range([d3.min(data, function(d) {return d.x; }),
d3.max(data, function(d) {return d.x; })]);
var svg = d3.select("body").append("svg")
.attr("width", 100)
.attr("height", 100)
.attr('viewBox', '-5 -20 35 40');
var chartData = d3.range(rectCount).map(function(i){
var x = xScale(i);
var width = xScale.bandwidth();
var y = yScale(x);
var height = y*2;
return {
x: x,
y: y,
width: width,
height: height
};
});
svg.selectAll('rect')
.data(chartData)
.enter()
.append('rect')
.attr('x', function(d) { return d.x; })
.attr('y', function(d) { return -d.y; })
.attr('width', function(d) { return d.width; })
.attr('height', function(d) { return d.height; })
</script>
</body>
关于javascript - 使用 d3 模拟音频波形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54864881/