如何根据信息表绘制动态折线图?

时间:2019-10-31 03:20:52

标签: javascript arrays d3.js

我想使用d3.js根据信息表绘制动态折线图。我已经将infotable中的信息转换为两个数组:一个一维数组xValueArray: [0, 10, 20, 30, 40]和一个二维数组yValueArray: [[0, 20, 30, 40, 50], [0, 200, 250, 400, 450]]。我的逻辑是,我可以获得一个xValueArray映射到yValueArray中的两个数组的数据集,以表示x和y坐标。因此,我使用了map函数来制作数据集。

    var result = xValueArray.map(function (x, i) { 
        return [x, yValueArray[0][i]];
    });
    console.log(result); //returns [[0,0], [10,20], [20,30], [30,40], [40, 50]]

    var data = result.map(function(d) {
        return {
          x: d[0],
          y: d[1]
        };
    });
    console.log(data); //returns [[x:0, y:0], [x:10, y:20], [x:20, y:30], [x:30, y:40], [x:40, y:50]]

    //************* Plotting of graph ***************   
    var lineFunction = d3.line()
        .x(function(d) {return x(d.x); })
        .y(function(d) {return y(d.y); })
        .curve(d3.curveLinear);

    //plot line
    var path1 = g.append("path")
        .attr("class", "path1")
        .attr("id", "blueLine")
        .attr("d", lineFunction(data))
        .attr("stroke", "blue")
        .attr("stroke-width", 2)
        .attr("fill", "none")
        .attr("clip-path", "url(#clip)");

折线图将被很好地绘制,只有一个线被绘制,因为我仅将yValueArray中的第一个数组映射到xValueArray。但是,我想使图表动态,这意味着我希望根据用户在信息表中输入的数据字段数来绘制折线图。在这种情况下,数据字段的数目为2,因为yValueArray中有2个数组。如果数据字段的数量增加,则yValueArray中的数组的数量也会增加,因此我必须在折线图上绘制相应的线。

我应该如何去做?任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:3)

与其使用x数组作为映射y值的基础,不如用其他方法:

const yValueArray = [
  [0, 20, 30, 40, 50],
  [0, 200, 250, 400, 450]
];

const xValueArray = [0, 10, 20, 30, 40];

const data = yValueArray.map(data =>
  data.map((d, i) => ({
    x: xValueArray[i],
    y: d
  }))
);

console.log(data);

这将适用于您在yValueArray上有多少个内部数组。

然后在您的输入选择中使用该数据:

const yValueArray = [
  [0, 20, 30, 40, 50],
  [0, 200, 250, 400, 450]
];

const xValueArray = [0, 10, 20, 30, 40];

const data = yValueArray.map(data =>
  data.map((d, i) => ({
    x: xValueArray[i],
    y: d
  }))
);

const x = d3.scaleLinear();
const y = d3.scaleLinear();

const lineFunction = d3.line()
  .x(function(d) {
    return x(d.x);
  })
  .y(function(d) {
    return y(d.y);
  })
  .curve(d3.curveLinear);

const path1 = d3.select("svg").selectAll(null)
  .data(data)
  .enter()
  .append("path")
  .attr("d", lineFunction)
  .attr("stroke", "blue")
  .attr("stroke-width", 2)
  .attr("fill", "none");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="300" height="400"></svg>