D3JS从数组数据绘制折线图(数据未定义错误)

时间:2020-04-24 18:41:52

标签: d3.js

我正在尝试从以下数组中绘制图形,但是控制台告诉我数组未传递给line函数

我收到以下错误: “ 0:无法获取未定义或空引用的属性'x'” 从控制台日志中

代码如下:

const svgHeight = 400;
const svgWidth = 400;
const margin = {left:50, right:20, top:20, bottom:30};
const h = svgHeight - margin.top - margin.bottom;
const w = svgWidth - margin.right - margin.left;

document.addEventListener("DOMContentLoaded", function(event){
          drawChart();
});

function drawChart(){
        const svg = d3.select("body")
                      .append("svg")
                      .attr("height",svgHeight)
                      .attr("width",svgWidth);

        const xscale = d3.scaleLinear()
              .range([0,w])
              .domain([0,50]);

        const yscale = d3.scaleLinear()
                  .range([h,0])
                  .domain([0,30]);

        const xaxis = d3.axisBottom().scale(xscale);
        const yaxis = d3.axisRight().scale(yscale);

        var rh100line = d3.line()
                      .x(function(d,i){
                        console.log(d[i]);
                        return xscale(d[i].x);
                      })
                      .y(function(d,i){
                        return yscale((622*1*d[i].y)/(101.325-1*d[i].y));
                      })
                      .curve(d3.curveMonotoneX);

        svg.append("g")
          .attr("class","axis")
          .attr("transform","translate(0," + h + ")")
          .call(xaxis);

        svg.append("g")
          .attr("class","axis")      
          .call(yaxis);

        svg.append("path")
            .data(tp1)
            .attr("class","line")
            .attr("d", rh100line);

}

数组存储在tp1中:

var tp1 = [{x:0.01, y:0.61165},
    {x:1, y:0.65709},
    {x:2, y:0.70599},
    {x:3, y:0.75808},
    {x:4, y:0.81355},
    {x:5, y:0.87258},
    {x:6, y:0.93536},
    {x:7, y:1.00210},
    {x:8, y:1.07300},
    {x:9, y:1.14830},
    {x:10, y:1.22820},
    {x:11, y:1.31300},
    {x:12, y:1.40280},
    {x:13, y:1.49810},
    {x:14, y:1.59900},
    {x:15, y:1.70580},
    {x:16, y:1.81880},
    {x:17, y:1.93840},
    {x:18, y:2.06470},
    {x:19, y:2.19830},
    {x:20, y:2.33930},
    {x:21, y:2.48820},
    {x:22, y:2.64530},
    {x:23, y:2.81110},
    {x:24, y:2.98580},
    {x:25, y:3.16990},
    {x:26, y:3.36390},
    {x:27, y:3.56810},
    {x:28, y:3.78310},
    {x:29, y:4.00920},
    {x:30, y:4.24700},
    {x:31, y:4.49690},
    {x:32, y:4.75960},
    {x:33, y:5.03540},
    {x:34, y:5.32510},
    {x:35, y:5.62900},
    {x:36, y:5.94790},
    {x:37, y:6.28230},
    {x:38, y:6.63280},
    {x:39, y:7.00020},
    {x:40, y:7.38490},
    {x:41, y:7.78780},
    {x:42, y:8.20960},
    {x:43, y:8.65080},
    {x:44, y:9.11240},
    {x:45, y:9.59500},
    {x:46, y:10.09900},
    {x:47, y:10.62700},
    {x:48, y:11.17700},
    {x:49, y:11.75200},
    {x:50, y:12.35200}]

1 个答案:

答案 0 :(得分:0)

这里有两个问题,让我们从将数据绑定到行开始。

您有一个数据数组,其中包含路径的点(单数路径)。您不希望数据数组中的每个项目都与DOM中的元素相对应。因此,我们需要重组您对.data()的使用。如果您想为数据数组中的每一项创建一个点,那么.data()会很棒,但是您只有一行。解决此问题的一种方法是使用:

.data([pointsOnPathArray]) // here we pass an array containing one item (the path data) 
                           // as opposed to an array containing many items

或者,我们可以使用以下命令设置附加路径​​的绑定基准:

.datum(pointsOnPathArray) // here we bind the path data directly to the appended path.

在这种情况下,使用.datum()可能更惯用,因为您没有使用selectAll()或enter()语句。

现在,行生成器的x和y的访问器函数。对于路径数据数组中的每个点,我们想用什么来绘制x和y?

    var rh100line = d3.line()
                  .x(function(d){
                     return xscale(d.x);
                  })
                  .y(function(d){
                    return yscale((622*1*d.y)/(101.325-1*d.y));
                  })
                  .curve(d3.curveMonotoneX);

不需要使用索引,d已经指向该点,而不是包含所有点的数组。

这是工作中的那些变化:

var tp1 = [{x:0.01, y:0.61165},
    {x:1, y:0.65709},
    {x:2, y:0.70599},
    {x:3, y:0.75808},
    {x:4, y:0.81355},
    {x:5, y:0.87258},
    {x:6, y:0.93536},
    {x:7, y:1.00210},
    {x:8, y:1.07300},
    {x:9, y:1.14830},
    {x:10, y:1.22820},
    {x:11, y:1.31300},
    {x:12, y:1.40280},
    {x:13, y:1.49810},
    {x:14, y:1.59900},
    {x:15, y:1.70580},
    {x:16, y:1.81880},
    {x:17, y:1.93840},
    {x:18, y:2.06470},
    {x:19, y:2.19830},
    {x:20, y:2.33930},
    {x:21, y:2.48820},
    {x:22, y:2.64530},
    {x:23, y:2.81110},
    {x:24, y:2.98580},
    {x:25, y:3.16990},
    {x:26, y:3.36390},
    {x:27, y:3.56810},
    {x:28, y:3.78310},
    {x:29, y:4.00920},
    {x:30, y:4.24700},
    {x:31, y:4.49690},
    {x:32, y:4.75960},
    {x:33, y:5.03540},
    {x:34, y:5.32510},
    {x:35, y:5.62900},
    {x:36, y:5.94790},
    {x:37, y:6.28230},
    {x:38, y:6.63280},
    {x:39, y:7.00020},
    {x:40, y:7.38490},
    {x:41, y:7.78780},
    {x:42, y:8.20960},
    {x:43, y:8.65080},
    {x:44, y:9.11240},
    {x:45, y:9.59500},
    {x:46, y:10.09900},
    {x:47, y:10.62700},
    {x:48, y:11.17700},
    {x:49, y:11.75200},
    {x:50, y:12.35200}]

const svgHeight = 400;
const svgWidth = 400;
const margin = {left:50, right:20, top:20, bottom:30};
const h = svgHeight - margin.top - margin.bottom;
const w = svgWidth - margin.right - margin.left;

document.addEventListener("DOMContentLoaded", function(event){
          drawChart();
});

function drawChart(){
        const svg = d3.select("body")
                      .append("svg")
                      .attr("height",svgHeight)
                      .attr("width",svgWidth);

        const xscale = d3.scaleLinear()
              .range([0,w])
              .domain([0,50]);

        const yscale = d3.scaleLinear()
                  .range([h,0])
                  .domain([0,30]);

        const xaxis = d3.axisBottom().scale(xscale);
        const yaxis = d3.axisRight().scale(yscale);

        var rh100line = d3.line()
                      .x(function(d){
                        return xscale(d.x);
                      })
                      .y(function(d){
                        return yscale((622*1*d.y)/(101.325-1*d.y));
                      })
                      .curve(d3.curveMonotoneX);

        svg.append("g")
          .attr("class","axis")
          .attr("transform","translate(0," + h + ")")
          .call(xaxis);

        svg.append("g")
          .attr("class","axis")      
          .call(yaxis);

        svg.append("path")
            .datum(tp1)
            .attr("class","line")
            .attr("d", rh100line);

}
path {
  fill: none;
  stroke:black;
  stroke-width:1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>