我正在尝试使用d3创建仪表板。我正在把子弹图和迷你图放在桌子上。我已经能够毫无困难地放置项目符号图,但是我无法获得折线图的路径。我的数据是嵌套的,下面的内容正确地附加了svg和路径,但是路径为空。我尝试了多种更新模式,但看不到为什么无法通过以下路径获取任何数据。
任何帮助或建议,我们感激不尽。谢谢。
data = [{data:{data1:[{index:1, value:5},{index:2, value:9}]}}]
sparkScaleY = d3.scaleLinear()
.domain([0,10])
.range([10,0])
sparkScaleX = d3.scaleLinear()
.domain([0,10])
.range([0,15])
line = d3.line()
.x(function(d) { return sparkScaleX (d.index); })
.y(function(d) { return sparkScaleY (d.value); });
rows = d3.select("tbody")
.selectAll("tr")
.data(data)
.enter()
.append("tr")
spark = rows.append('td')
.append('svg')
.attr("class", "spark-svg")
.attr("width", 15)
.attr("height", 10)
.append('path')
spark
.attr("class", "spark-path")
function update(data){
sparkSvg = d3.selectAll(".spark-svg")
.data(data)
sparkPath = sparkSvg.selectAll('.spark-path')
.data(function(d){return [d.data.data1]})
.enter()
.append('path')
.classed("new", true)
sparkPath.attr('d', line)
sparkPath
.attr('d', line)
.classed("new",false)
sparkPath.exit().remove()
}
update(data)
<table>
<tbody>
</tbody>
</table>
<script src="https://d3js.org/d3.v5.min.js">
为澄清起见,更新之间的行数,列数,svg和路径数保持不变。
答案 0 :(得分:2)
如果表结构是恒定的(行,列,svgs和迷你图(路径)的数量相同),那么我们可以稍微简化一下代码。在您的示例中,您正在更新,输入和退出更新功能。如果在创建表后不进入或退出任何内容,则无需执行此操作。
您已经在更新功能之前添加了行,列,svg和路径,因此我们在更新功能中所需的只是一个更新选择-让我们简化一点:
// Add rows once, same as before:
rows = d3.select("tbody")
.selectAll("tr")
.data(data)
.enter()
.append("tr")
// Add sparkline cell,svg, and path once, same as before:
var spark = rows.append('td')
.append('svg')
.attr("class", "spark-svg")
.attr("width", 15)
.attr("height", 10)
.append('path')
.attr("class", "spark-path")
// Only update, no need for entering/exiting if table structure doesn't change, only data:
function update(data){
spark // use existing selection
.data(data) // assign new data
.attr('d', function(d) {
return line(d.data.data1); // draw new data
})
}
这看起来像:
data = [{data:{data1:[{index:1, value:5},{index:4, value:9},{index:7,value:4},{index:10,value:8}]}}]
sparkScaleY = d3.scaleLinear()
.domain([0,10])
.range([10,0])
sparkScaleX = d3.scaleLinear()
.domain([0,10])
.range([0,15])
line = d3.line()
.x(function(d) { return sparkScaleX (d.index); })
.y(function(d) { return sparkScaleY (d.value); });
// Add rows once:
rows = d3.select("tbody")
.selectAll("tr")
.data(data)
.enter()
.append("tr")
// Add title cell:
rows.append("td")
.text(function(d) {
return Object.keys(d.data)[0];
})
// Add sparkline cell,svg, and path once:
var spark = rows.append('td')
.append('svg')
.attr("class", "spark-svg")
.attr("width", 15)
.attr("height", 10)
.append('path')
.attr("class", "spark-path")
// Only update, no need for entering/exiting if table structure doesn't change, only data:
function update(data){
spark // use the existing selection
.data(data)
.attr('d', function(d) {
return line(d.data.data1);
})
}
update(data)
path {
stroke-width: 2;
stroke:black;
fill: none;
}
<script src="https://d3js.org/d3.v5.min.js"></script><table>
<tbody>
</tbody>
</table>
还有一些动态数据
var data = generate();
sparkScaleY = d3.scaleLinear()
.domain([0,10])
.range([10,0])
sparkScaleX = d3.scaleLinear()
.domain([0,10])
.range([0,15])
line = d3.line()
.x(function(d) { return sparkScaleX (d.index); })
.y(function(d) { return sparkScaleY (d.value); });
// Add rows once:
rows = d3.select("tbody")
.selectAll("tr")
.data(data)
.enter()
.append("tr")
// Add title cell:
rows.append("td")
.text(function(d) {
return d.name;
})
// Add sparkline cell,svg, and path once:
var spark = rows.append('td')
.append('svg')
.attr("class", "spark-svg")
.attr("width", 15)
.attr("height", 10)
.append('path')
.attr("class", "spark-path")
var spark2 = rows.append('td')
.append('svg')
.attr("class", "spark-svg")
.attr("width", 15)
.attr("height", 10)
.append('path')
.attr("class", "spark-path2")
.style("stroke","steelblue");
// Only update, no need for entering/exiting if table structure doesn't change, only data:
function update(data){
spark
.data(data)
.transition()
.attr('d', function(d) {
return line(d.spark1);
})
spark2
.data(data)
.transition()
.attr('d', function(d) {
return line(d.spark2);
})
}
update(generate());
d3.interval(function(elapsed) {
update(generate());
}, 2000);
function generate() {
return d3.range(10).map(function(d) {
return {
name: "row"+d,
spark1: d3.range(10).map(function(d) {
return {index: d, value: Math.random()*10}
}),
spark2: d3.range(10).map(function(d) {
return {index: d, value: Math.random()*10}
})
}
})
}
path {
stroke-width: 2;
stroke:black;
fill: none;
}
<script src="https://d3js.org/d3.v5.min.js"></script><table>
<tbody>
</tbody>
</table>