为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

犯罪嫌疑人X 2022-05-26 14:21:09
我想使用 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 获取日期和分值。
查看完整描述

1 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

您无法通过说来获得date和value评分,d.value.date因为这些值嵌套在另一个对象中。您可以展平这些对象以尝试获取域。离开这个例子,如果你代表你的结构是这样的:


data = [

    {student: 'student1', date : '2017-09-11 11:51', score: 50},

    {student: 'student1', date : '2017-09-11 12:53', score: 90},

    ...

    {student: 'student2', date : '2017-09-11 11:51', score: 20},

    {student: 'student2', date : '2017-09-11 12:53', score: 30},

    ...

]

您可以尝试像这样定义轴:


var parseDate = d3.timeParse("%Y-%m-%d %H:%M");

var x = d3.scaleTime().range([0, width]);  

var y = d3.scaleLinear().range([height, 0]);


data.forEach(function(d) {

    d.date = parseDate(d.date);

    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 / graph

var margin = {

    top: 30,

    right: 20,

    bottom: 70,

    left: 50

  },

  width = 600 - margin.left - margin.right,

  height = 300 - margin.top - margin.bottom;


// Parse the date / time

var parseDate = d3.timeParse("%Y-%m-%d %H:%M");


// Set the ranges

var x = d3.scaleTime().range([0, width]);

var y = d3.scaleLinear().range([height, 0]);


// Define the line

var priceline = d3.line()

  .x(function(d) {

    return x(d.date);

  })

  .y(function(d) {

    return y(d.score);

  });


// Adds the svg canvas

var svg = d3.select("body")

  .append("svg")

  .attr("width", width + margin.left + margin.right)

  .attr("height", height + margin.top + margin.bottom)

  .append("g")

  .attr("transform",

    "translate(" + margin.left + "," + margin.top + ")");


// Get the data

var data = [

  {

    student: 'student1',

    date: '2017-09-11 11:45',

    score: 60

  },

  {

    student: 'student1',

    date: '2017-09-11 11:51',

    score: 50

  },

  {

    student: 'student1',

    date: '2017-09-11 12:53',

    score: 90

  },

  {

    student: 'student1',

    date: '2017-09-11 12:57',

    score: 97

  },

  {

    student: 'student2',

    date: '2017-09-11 11:22',

    score: 10

  },

  {

    student: 'student2',

    date: '2017-09-11 11:31',

    score: 15

  },

  {

    student: 'student2',

    date: '2017-09-11 11:33',

    score: 20

  },

  {

    student: 'student2',

    date: '2017-09-11 11:38',

    score: 30

  },

  {

    student: 'student2',

    date: '2017-09-11 12:51',

    score: 45

  },

  {

    student: 'student2',

    date: '2017-09-11 12:59',

    score: 40

  }

]


data.forEach(function(d) {

  d.date = parseDate(d.date);

  d.price = +d.price;

});


// Scale the range of the data

x.domain(d3.extent(data, function(d) {

  return d.date;

}));

y.domain([0, d3.max(data, function(d) {

  return d.score;

})]);


// Nest the entries by symbol

var dataNest = d3.nest()

  .key(function(d) {

    return d.student;

  })

  .entries(data);


// set the colour scale

var color = d3.scaleOrdinal(d3.schemeCategory10);


legendSpace = width / dataNest.length; // spacing for the legend


// Loop through each symbol / key

dataNest.forEach(function(d, i) {


  svg.append("path")

    .attr("class", "line")

    .style("stroke", function() { // Add the colours dynamically

      return d.color = color(d.key);

    })

    .attr("id", 'tag' + d.key.replace(/\s+/g, '')) // assign an ID

    .attr("d", priceline(d.values));


  // Add the Legend

  svg.append("text")

    .attr("x", (legendSpace / 2) + i * legendSpace) // space legend

    .attr("y", height + (margin.bottom / 2) + 5)

    .attr("class", "legend") // style the legend

    .style("fill", function() { // Add the colours dynamically

      return d.color = color(d.key);

    })

    .on("click", function() {

      // Determine if current line is visible 

      var active = d.active ? false : true,

        newOpacity = active ? 0 : 1;

      // Hide or show the elements based on the ID

      d3.select("#tag" + d.key.replace(/\s+/g, ''))

        .transition().duration(100)

        .style("opacity", newOpacity);

      // Update whether or not the elements are active

      d.active = active;

    })

    .text(d.key);


});


// Add the X Axis

svg.append("g")

  .attr("class", "axis")

  .attr("transform", "translate(0," + height + ")")

  .call(d3.axisBottom(x));


// Add the Y Axis

svg.append("g")

  .attr("class", "axis")

  .call(d3.axisLeft(y));

body { font: 12px Arial;}


path { 

    stroke: steelblue;

    stroke-width: 2;

    fill: none;

}


.axis path,

.axis line {

    fill: none;

    stroke: grey;

    stroke-width: 1;

    shape-rendering: crispEdges;

}


.legend {

    font-size: 16px;

    font-weight: bold;

    text-anchor: middle;

}

<script src="https://d3js.org/d3.v5.min.js"></script>


查看完整回答
反对 回复 2022-05-26
  • 1 回答
  • 0 关注
  • 231 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信