javascript - D3条形图和面积图的组合
问题描述
我想知道是否有可能以下面屏幕截图中显示的方式实现combination of area
and bar chart
?
除了使两者之间的区域可点击以进行其他操作。如果您可以指导我查看一些示例以了解如何实现相同目标,那将非常有帮助。
解决方案
在下面的示例中,我结合了一个简单的条形图(例如在这个著名的 bl.lock 中)和中间的一些多边形。我想它也可以通过path
.
const data = [
{ letter: "a", value: 9 },
{ letter: "b", value: 6 },
{ letter: "c", value: 3 },
{ letter: "d", value: 8 }
];
const svg = d3.select("#chart");
const margin = { top: 20, right: 20, bottom: 30, left: 40 };
const width = +svg.attr("width") - margin.left - margin.right;
const height = +svg.attr("height") - margin.top - margin.bottom;
const xScale = d3.scaleBand()
.rangeRound([0, width]).padding(0.5)
.domain(data.map(d => d.letter));
const yScale = d3.scaleLinear()
.rangeRound([height, 0])
.domain([0, 10]);
const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(xScale));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(yScale));
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", d => xScale(d.letter))
.attr("y", d => yScale(d.value))
.attr("width", xScale.bandwidth())
.attr("height", d => height - yScale(d.value));
// Add polygons
g.selectAll(".area")
.data(data)
.enter().append("polygon")
.attr("class", "area")
.attr("points", (d,i,nodes) => {
if (i < nodes.length - 1) {
const dNext = d3.select(nodes[i + 1]).datum();
const x1 = xScale(d.letter) + xScale.bandwidth();
const y1 = height;
const x2 = x1;
const y2 = yScale(d.value);
const x3 = xScale(dNext.letter);
const y3 = yScale(dNext.value);
const x4 = x3;
const y4 = height;
return `${x1},${y1} ${x2},${y2} ${x3},${y3} ${x4},${y4} ${x1},${y1}`;
}
})
.on("click", (d,i,nodes) => {
const dNext = d3.select(nodes[i + 1]).datum();
const pc = Math.round((dNext.value - d.value) / d.value * 100.0);
alert(`${d.letter} to ${dNext.letter}: ${pc > 0 ? '+' : ''}${pc} %`);
});
.bar {
fill: steelblue;
}
.area {
fill: lightblue;
}
.area:hover {
fill: sandybrown;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg width="400" height="300" id="chart"></svg>
推荐阅读
- r - 断开 R 中的所有 MySQL 连接
- arrays - Excel公式:使用条件计算数组元素
- javascript - 将引导类添加到 JS 类
- angular - 我在 Angular4 中的订阅中的数据为空
- excel - Excel VBA 用户窗体退出
- java - 为什么这会在运行时导致 ArrayIndexOutOfBoundsException?
- android - 如何使用 GridView 变量从 onCreateView 类到片段中的另一个类?
- wpf - Wpf 应用程序作为单个可执行文件
- ios - 在 iOS 中运行 UI 测试时如何在应用程序中打断点?
- github - 成功克隆并推送了一个分叉的 repo,在 Github 上无法读取