我正在从JSON文件构建表。该表有多个列,其中包含不同年份的值。我希望最后一栏是显示趋势的迷你图。我有工作表的代码。我有代码可用于迷你图。但是我无法终生获得迷你图出现在桌子内。
我在StackOverflow上发现了类似的问题,答案非常好:
Inline D3 sparklines in a table alongside text
不幸的是,我无法理解如何获取数据以这种方式使用。任何帮助是极大的赞赏。
代码在下面,并且是here as a plunker。
<!DOCTYPE html>
<html>
<head>
<style>
body{
font-family:Arial, sans-serif;
font-size:14px;
}
table{
border-spacing:0;
padding:0;
}
th{
text-align:left;
font-weight:normal !important;
border-top:1px solid #ddd;
border-left:1px solid #ddd;
border-bottom:1px solid #ddd;
height:25px;
padding-left:5px;
width: 50px;
}
td{
border:1px solid #ddd;
width:30px !important;
height:25px;
padding-left:5px;
}
tr.row-odd,
.row-odd{
background: #eee;
}
#sparks{
float:left;
width:20%;
}
.sparkline{
height:25px;
width:200px;
}
.Sparkline{
width:200px !important;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<div id="indcontent">
</div>
<div id="sparks"></div>
<script>
var data;
d3.json("data.json", function(json) {
jsonData = json;
json.forEach(function(d) {
d.value = Math.round((+d.value + 0.00001) * 1000) / 1000;
d.year = +d.year;
});
// add years for select indicator
var nestyr = d3.nest()
.key(function(d) { return d.year; })
.sortKeys(d3.ascending)
.map(json);
var yearstring = Object.keys(nestyr);
// //////////////////////////
var width = 200, height = 25;
var graph = d3.select("#sparks")
var minInd = d3.min(json, function(d) { return d.value;} )
var maxInd = d3.max(json, function(d) { return d.value;} )
xScale = d3.scale.linear().range([0, width - 10]).domain(d3.extent(json, function(d) { return d.year; })),
yScale = d3.scale.linear().range([height, 0]).domain([minInd,maxInd]),
xAxis = d3.svg.axis().scale(xScale).tickFormat(d3.format('0f')),
yAxis = d3.svg.axis().scale(yScale).orient("left");
var type = d3.nest()
.key(function(d) { return d.state; })
.sortKeys(d3.ascending)
.entries(json);
var line = d3.svg.line()
.x(function(d){return xScale(d.year);})
.y(function(d){return yScale(d.value);});
// this adds the sparklines below the chart, where they are showing up now.
var indi = graph.selectAll("svg")
.data(type)
.enter().append("svg")
.attr("class", function(d, i){
if (i++ % 2 === 0){return 'row-even sparkline ' + d.key}
else {return 'row-odd sparkline ' + d.key}});
indi.append("path")
.attr("d", function(d){ d.line = this; return line(d.values); })
.attr("stroke-width", 1)
.attr("stroke", "#c00000")
.attr("fill", "none");
var tableData = [],
states = {};
json.forEach(function (d) {
var state = states[d.state];
if (!state) {
tableData.push(state = states[d.state] = {});
}
state[d.year] = d.value,
states[d.state].State = d.state;
});
console.log("tableData", tableData)
yearstring.unshift("State");
yearstring.push("Sparkline");
updateGraph(data);
// render the table(s)
tabulate(tableData, yearstring);
}); // close json
function updateGraph(data) {
// add years for select indicator
var nestyr = d3.nest()
.key(function(d) { return d.year; })
.sortKeys(d3.ascending)
.map(jsonData);
var yearstring = Object.keys(nestyr);
minyear = d3.min(yearstring);
maxyear = d3.max(yearstring);
};
function tabulate(newData, columns) {
var type = d3.nest()
.key(function(d) { return d.state; })
.sortKeys(d3.ascending)
.entries(jsonData);
var table = d3.select('#indcontent').append('table')
var thead = table.append('thead')
var tbody = table.append('tbody');
// append the header row
thead.append('tr')
.selectAll('th')
.data(columns).enter()
.append('th')
.text(function (column) { return column; });
// create a row for each object in the data
var rows = tbody.selectAll('tr')
.data(newData)
.enter()
.append('tr');
// add stripes to the table
rows.attr("class", function(d, i){ if (i++ % 2 === 0){return 'row-even'}else {return 'row-odd'}});
// create a cell in each row for each column
var cells = rows.selectAll('td')
.data(function (row) {
return columns.map(function (column) {
return {column: column, value: row[column]};
});
})
.enter()
.append('td')
.attr("class", function (d,i) { return columns[i]; })
.html(function (d) { return d.value; });
// Here's where I'm attempting to add the sparklines inside the table cells. This isn't doing anything right now.
rows.selectAll("td.Sparkline")
.data(function(d,i){type[i]})
.enter()
.append("svg")
.attr("class", "spark")
.attr("height", 25)
.attr("width", 200);
var isit = d3.selectAll(".spark")
.append("path")
.attr("d", function(d){ d.line = this; return line(d.values); })
.attr("stroke-width", 1)
.attr("stroke", "#c00000")
.attr("fill", "none");
return table;
};
</script>
</body>
</html>
最佳答案
我在您的代码中发现的小错误如下。
您错过了数据绑定函数中的return语句,并且返回类型是对象而不是数组。
新的svg元素被追加到行而不是td元素。
变量line
超出范围。它应该已经在外面声明了。
如下所示创建火花线。
代码:
rows.selectAll("td.Sparkline")
.selectAll(".spark")
.data(function(d,i){ return [type[i]] })
.enter()
.append("svg")
.attr("class", "spark")
.attr("height", 25)
.attr("width", 200)
.append("path")
.attr("d", function(d,i){ d.line = this; return line(d.values); });
.attr("stroke-width", 1)
.attr("stroke", "#c00000")
.attr("fill", "none");
var json = [{
"state": "Alabama",
"value": 2,
"year": 2003
}, {
"state": "Alabama",
"value": 0,
"year": 2004
}, {
"state": "Alabama",
"value": 6,
"year": 2005
}, {
"state": "Alabama",
"value": 2,
"year": 2006
}, {
"state": "Alabama",
"value": 4,
"year": 2007
}, {
"state": "Alabama",
"value": 4,
"year": 2008
}, {
"state": "Alaska",
"value": 0,
"year": 2003
}, {
"state": "Alaska",
"value": 1,
"year": 2004
}, {
"state": "Alaska",
"value": 2,
"year": 2005
}, {
"state": "Alaska",
"value": 1,
"year": 2006
}, {
"state": "Alaska",
"value": 2,
"year": 2007
}, {
"state": "Alaska",
"value": 5,
"year": 2008
}, {
"state": "Arizona",
"value": 6,
"year": 2003
}, {
"state": "Arizona",
"value": 4,
"year": 2004
}, {
"state": "Arizona",
"value": 5,
"year": 2005
}, {
"state": "Arizona",
"value": 7,
"year": 2006
}, {
"state": "Arizona",
"value": 3,
"year": 2007
}, {
"state": "Arizona",
"value": 8,
"year": 2008
}, {
"state": "Arkansas",
"value": null,
"year": 2003
}, {
"state": "Arkansas",
"value": 0,
"year": 2004
}, {
"state": "Arkansas",
"value": 1,
"year": 2005
}, {
"state": "Arkansas",
"value": 3,
"year": 2006
}, {
"state": "Arkansas",
"value": 1,
"year": 2007
}, {
"state": "Arkansas",
"value": null,
"year": 2008
}, {
"state": "California",
"value": 10,
"year": 2003
}, {
"state": "California",
"value": 12,
"year": 2004
}, {
"state": "California",
"value": 9,
"year": 2005
}, {
"state": "California",
"value": 5,
"year": 2006
}, {
"state": "California",
"value": 8,
"year": 2007
}, {
"state": "California",
"value": 3,
"year": 2008
}, {
"state": "Colorado",
"value": 2,
"year": 2003
}, {
"state": "Colorado",
"value": 12,
"year": 2004
}, {
"state": "Colorado",
"value": 12,
"year": 2005
}, {
"state": "Colorado",
"value": 11,
"year": 2006
}, {
"state": "Colorado",
"value": 7,
"year": 2007
}, {
"state": "Colorado",
"value": 2,
"year": 2008
}, {
"state": "Connecticut",
"value": 0,
"year": 2003
}, {
"state": "Connecticut",
"value": 5,
"year": 2004
}, {
"state": "Connecticut",
"value": 4,
"year": 2005
}, {
"state": "Connecticut",
"value": 4,
"year": 2006
}, {
"state": "Connecticut",
"value": 3,
"year": 2007
}, {
"state": "Connecticut",
"value": 5,
"year": 2008
}, {
"state": "Delaware",
"value": 1,
"year": 2003
}, {
"state": "Delaware",
"value": 1,
"year": 2004
}, {
"state": "Delaware",
"value": 1,
"year": 2005
}, {
"state": "Delaware",
"value": 5,
"year": 2006
}, {
"state": "Delaware",
"value": 2,
"year": 2007
}, {
"state": "Delaware",
"value": 4,
"year": 2008
}];
var data, line;
//d3.json("data.json", function(json) {
jsonData = json;
json.forEach(function(d) {
d.value = Math.round((+d.value + 0.00001) * 1000) / 1000;
d.year = +d.year;
});
// add years for select indicator
var nestyr = d3.nest()
.key(function(d) {
return d.year;
})
.sortKeys(d3.ascending)
.map(json);
var yearstring = Object.keys(nestyr);
// //////////////////////////
var width = 200,
height = 25;
var graph = d3.select("#sparks")
var minInd = d3.min(json, function(d) {
return d.value;
})
var maxInd = d3.max(json, function(d) {
return d.value;
})
xScale = d3.scale.linear().range([0, width - 10]).domain(d3.extent(json, function(d) {
return d.year;
})),
yScale = d3.scale.linear().range([height, 0]).domain([minInd, maxInd]),
xAxis = d3.svg.axis().scale(xScale).tickFormat(d3.format('0f')),
yAxis = d3.svg.axis().scale(yScale).orient("left");
var type = d3.nest()
.key(function(d) {
return d.state;
})
.sortKeys(d3.ascending)
.entries(json);
line = d3.svg.line()
.x(function(d) {
return xScale(d.year);
})
.y(function(d) {
return yScale(d.value);
});
// this adds the sparklines below the chart, where they are showing up now.
var indi = graph.selectAll("svg")
.data(type)
.enter().append("svg")
.attr("class", function(d, i) {
if (i++ % 2 === 0) {
return 'row-even sparkline ' + d.key
} else {
return 'row-odd sparkline ' + d.key
}
});
indi.append("path")
.attr("d", function(d) {
d.line = this;
return line(d.values);
})
.attr("stroke-width", 1)
.attr("stroke", "#c00000")
.attr("fill", "none");
var tableData = [],
states = {};
json.forEach(function(d) {
var state = states[d.state];
if (!state) {
tableData.push(state = states[d.state] = {});
}
state[d.year] = d.value,
states[d.state].State = d.state;
});
console.log("tableData", tableData)
yearstring.unshift("State");
yearstring.push("Sparkline");
updateGraph(data);
// render the table(s)
tabulate(tableData, yearstring);
//}); // close json
function updateGraph(data) {
// add years for select indicator
var nestyr = d3.nest()
.key(function(d) {
return d.year;
})
.sortKeys(d3.ascending)
.map(jsonData);
var yearstring = Object.keys(nestyr);
minyear = d3.min(yearstring);
maxyear = d3.max(yearstring);
};
function tabulate(newData, columns) {
var type = d3.nest()
.key(function(d) {
return d.state;
})
.sortKeys(d3.ascending)
.entries(jsonData);
var table = d3.select('#indcontent').append('table')
var thead = table.append('thead')
var tbody = table.append('tbody');
// append the header row
thead.append('tr')
.selectAll('th')
.data(columns).enter()
.append('th')
.text(function(column) {
return column;
});
// create a row for each object in the data
var rows = tbody.selectAll('tr')
.data(newData)
.enter()
.append('tr');
// add stripes to the table
rows.attr("class", function(d, i) {
if (i++ % 2 === 0) {
return 'row-even'
} else {
return 'row-odd'
}
});
// create a cell in each row for each column
var cells = rows.selectAll('td')
.data(function(row) {
return columns.map(function(column) {
return {
column: column,
value: row[column]
};
});
})
.enter()
.append('td')
.attr("class", function(d, i) {
return columns[i];
})
.html(function(d) {
return d.value;
});
// Here's where I'm attempting to add the sparklines inside the table cells. This isn't doing anything right now.
rows.selectAll("td.Sparkline")
.selectAll(".spark")
.data(function(d, i) {
return [type[i]]
})
.enter()
.append("svg")
.attr("class", "spark")
.attr("height", 25)
.attr("width", 200)
.append("path")
.attr("d", function(d, i) {
d.line = this;
return line(d.values);
})
.attr("stroke-width", 1)
.attr("stroke", "#c00000")
.attr("fill", "none");
return table;
};
body {
font-family: Arial, sans-serif;
font-size: 14px;
}
table {
border-spacing: 0;
padding: 0;
}
th {
text-align: left;
font-weight: normal !important;
border-top: 1px solid #ddd;
border-left: 1px solid #ddd;
border-bottom: 1px solid #ddd;
height: 25px;
padding-left: 5px;
width: 50px;
}
td {
border: 1px solid #ddd;
width: 30px !important;
height: 25px;
padding-left: 5px;
}
tr.row-odd,
.row-odd {
background: #eee;
}
#sparks {
float: left;
width: 20%;
}
.sparkline {
height: 25px;
width: 200px;
}
.Sparkline {
width: 200px !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="indcontent">
</div>
<div id="sparks"></div>