使用 d3.entries 键值对绘制多条折线图

我想使用 d3.js 绘制多折线图。我在控制台中打印我的数据结构,它看起来像这样:


0:

  key: student1

  value: Array(50)

       0: {date : 2017-09-11 11:51,score:50}

       1: {date : 2017-09-11 12:53,score:90}

       ...


0:

  key: student2

  value: Array(50)

       0: {date : 2017-09-11 11:51,score:20}

       1: {date : 2017-09-11 12:53,score:30}

       ...

并将所有学生放在由不同线表示的同一图表中。X轴是日期,Y轴是学生成绩。


但似乎我在定义 X 和 Y 域时遇到问题,我无法通过 d.value.date 获取日期和分值。


犯罪嫌疑人X
浏览 232回答 1
1回答

阿波罗的战车

您无法通过说来获得date和value评分,d.value.date因为这些值嵌套在另一个对象中。您可以展平这些对象以尝试获取域。离开这个例子,如果你代表你的结构是这样的:data = [&nbsp; &nbsp; {student: 'student1', date : '2017-09-11 11:51', score: 50},&nbsp; &nbsp; {student: 'student1', date : '2017-09-11 12:53', score: 90},&nbsp; &nbsp; ...&nbsp; &nbsp; {student: 'student2', date : '2017-09-11 11:51', score: 20},&nbsp; &nbsp; {student: 'student2', date : '2017-09-11 12:53', score: 30},&nbsp; &nbsp; ...]您可以尝试像这样定义轴:var parseDate = d3.timeParse("%Y-%m-%d %H:%M");var x = d3.scaleTime().range([0, width]);&nbsp;&nbsp;var y = d3.scaleLinear().range([height, 0]);data.forEach(function(d) {&nbsp; &nbsp; d.date = parseDate(d.date);&nbsp; &nbsp; d.score = +d.score;});x.domain(d3.extent(data, function(d) { return d.date; }));y.domain([0, d3.max(data, function(d) { return d.score; })]);我已经修改了 d3noob 的示例以使用此数据(添加了更多数据点):// Set the dimensions of the canvas / graphvar margin = {&nbsp; &nbsp; top: 30,&nbsp; &nbsp; right: 20,&nbsp; &nbsp; bottom: 70,&nbsp; &nbsp; left: 50&nbsp; },&nbsp; width = 600 - margin.left - margin.right,&nbsp; height = 300 - margin.top - margin.bottom;// Parse the date / timevar parseDate = d3.timeParse("%Y-%m-%d %H:%M");// Set the rangesvar x = d3.scaleTime().range([0, width]);var y = d3.scaleLinear().range([height, 0]);// Define the linevar priceline = d3.line()&nbsp; .x(function(d) {&nbsp; &nbsp; return x(d.date);&nbsp; })&nbsp; .y(function(d) {&nbsp; &nbsp; return y(d.score);&nbsp; });// Adds the svg canvasvar svg = d3.select("body")&nbsp; .append("svg")&nbsp; .attr("width", width + margin.left + margin.right)&nbsp; .attr("height", height + margin.top + margin.bottom)&nbsp; .append("g")&nbsp; .attr("transform",&nbsp; &nbsp; "translate(" + margin.left + "," + margin.top + ")");// Get the datavar data = [&nbsp; {&nbsp; &nbsp; student: 'student1',&nbsp; &nbsp; date: '2017-09-11 11:45',&nbsp; &nbsp; score: 60&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student1',&nbsp; &nbsp; date: '2017-09-11 11:51',&nbsp; &nbsp; score: 50&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student1',&nbsp; &nbsp; date: '2017-09-11 12:53',&nbsp; &nbsp; score: 90&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student1',&nbsp; &nbsp; date: '2017-09-11 12:57',&nbsp; &nbsp; score: 97&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student2',&nbsp; &nbsp; date: '2017-09-11 11:22',&nbsp; &nbsp; score: 10&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student2',&nbsp; &nbsp; date: '2017-09-11 11:31',&nbsp; &nbsp; score: 15&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student2',&nbsp; &nbsp; date: '2017-09-11 11:33',&nbsp; &nbsp; score: 20&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student2',&nbsp; &nbsp; date: '2017-09-11 11:38',&nbsp; &nbsp; score: 30&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student2',&nbsp; &nbsp; date: '2017-09-11 12:51',&nbsp; &nbsp; score: 45&nbsp; },&nbsp; {&nbsp; &nbsp; student: 'student2',&nbsp; &nbsp; date: '2017-09-11 12:59',&nbsp; &nbsp; score: 40&nbsp; }]data.forEach(function(d) {&nbsp; d.date = parseDate(d.date);&nbsp; d.price = +d.price;});// Scale the range of the datax.domain(d3.extent(data, function(d) {&nbsp; return d.date;}));y.domain([0, d3.max(data, function(d) {&nbsp; return d.score;})]);// Nest the entries by symbolvar dataNest = d3.nest()&nbsp; .key(function(d) {&nbsp; &nbsp; return d.student;&nbsp; })&nbsp; .entries(data);// set the colour scalevar color = d3.scaleOrdinal(d3.schemeCategory10);legendSpace = width / dataNest.length; // spacing for the legend// Loop through each symbol / keydataNest.forEach(function(d, i) {&nbsp; svg.append("path")&nbsp; &nbsp; .attr("class", "line")&nbsp; &nbsp; .style("stroke", function() { // Add the colours dynamically&nbsp; &nbsp; &nbsp; return d.color = color(d.key);&nbsp; &nbsp; })&nbsp; &nbsp; .attr("id", 'tag' + d.key.replace(/\s+/g, '')) // assign an ID&nbsp; &nbsp; .attr("d", priceline(d.values));&nbsp; // Add the Legend&nbsp; svg.append("text")&nbsp; &nbsp; .attr("x", (legendSpace / 2) + i * legendSpace) // space legend&nbsp; &nbsp; .attr("y", height + (margin.bottom / 2) + 5)&nbsp; &nbsp; .attr("class", "legend") // style the legend&nbsp; &nbsp; .style("fill", function() { // Add the colours dynamically&nbsp; &nbsp; &nbsp; return d.color = color(d.key);&nbsp; &nbsp; })&nbsp; &nbsp; .on("click", function() {&nbsp; &nbsp; &nbsp; // Determine if current line is visible&nbsp;&nbsp; &nbsp; &nbsp; var active = d.active ? false : true,&nbsp; &nbsp; &nbsp; &nbsp; newOpacity = active ? 0 : 1;&nbsp; &nbsp; &nbsp; // Hide or show the elements based on the ID&nbsp; &nbsp; &nbsp; d3.select("#tag" + d.key.replace(/\s+/g, ''))&nbsp; &nbsp; &nbsp; &nbsp; .transition().duration(100)&nbsp; &nbsp; &nbsp; &nbsp; .style("opacity", newOpacity);&nbsp; &nbsp; &nbsp; // Update whether or not the elements are active&nbsp; &nbsp; &nbsp; d.active = active;&nbsp; &nbsp; })&nbsp; &nbsp; .text(d.key);});// Add the X Axissvg.append("g")&nbsp; .attr("class", "axis")&nbsp; .attr("transform", "translate(0," + height + ")")&nbsp; .call(d3.axisBottom(x));// Add the Y Axissvg.append("g")&nbsp; .attr("class", "axis")&nbsp; .call(d3.axisLeft(y));body { font: 12px Arial;}path {&nbsp;&nbsp; &nbsp; stroke: steelblue;&nbsp; &nbsp; stroke-width: 2;&nbsp; &nbsp; fill: none;}.axis path,.axis line {&nbsp; &nbsp; fill: none;&nbsp; &nbsp; stroke: grey;&nbsp; &nbsp; stroke-width: 1;&nbsp; &nbsp; shape-rendering: crispEdges;}.legend {&nbsp; &nbsp; font-size: 16px;&nbsp; &nbsp; font-weight: bold;&nbsp; &nbsp; text-anchor: middle;}<script src="https://d3js.org/d3.v5.min.js"></script>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript