【问题标题】:How to draw a dynamic line chart based on an infotable?如何根据信息表绘制动态折线图?
【发布时间】:2020-02-26 09:48:17
【问题描述】:

我想使用 d3.js 基于信息表绘制动态折线图。我已将信息表中的信息转换为两个数组:一个一维数组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 中的数组数量也会增加,我必须在折线图上绘制相应的线。

我该怎么做呢?非常感谢任何帮助!

【问题讨论】:

    标签: javascript arrays d3.js


    【解决方案1】:

    不要使用 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>

    【讨论】:

    • 感谢您的帮助,我确实想过,但不知道如何使用正确的语法来实现它。但是,您似乎错过了我关于折线图需要动态的观点。我现在在数据集中有 10 个点,但其中 5 个点用于一条线,而另外 5 个用于另一条线,因为它们代表不同的数据字段。因此,应该绘制两条线,而不是一条线上的所有 10 个点。我是否必须将数据数组拆分为多个数据字段?如果是这样,我该怎么做?
    • 是的,你必须这样做。但这是一个不同的问题,因此请将其作为一个新问题发布,并附上相关细节。顺便说一句,你不需要那个 D3 标签,因为它只是一个 JS 问题。
    猜你喜欢
    • 2015-04-20
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    相关资源
    最近更新 更多