D3JS从数组数据绘制折线图(数据未定义错误) [英] D3JS Plotting Line Graph From Array Data (Data is undefined error)

查看:52
本文介绍了D3JS从数组数据绘制折线图(数据未定义错误)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to plot out a graph from the following array, however the console is telling me that the array is not passed to the line function

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

I am receiving the following error: "0: Unable to get property 'x' of undefined or null reference" from the console log

代码如下:

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}]

推荐答案

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

There are two issues here, let's start with binding data to the line.

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

You have a data array that contains points of a path, a singular path. You don't want each item in the data array to correspond to an element in the DOM. So we need to restructure your use of .data(). .data() would be great if you wanted to create one point for every item in the data array, but you only have one line. One way to fix this is to use:

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

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

Or, we can set the bound datum for the appended path with:

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

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

The use of .datum() would probably be more idiomatic in this case as you aren't using selectAll() or enter() statements.

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

Now the accessor function for x and y for the line generator. For each point in the path data array, what do we want to use to plot x and 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 已经指向该点,而不是包含所有点的数组.

There is no need to use an index, d refers to the point already, not the array containing all the points.

这是工作中的那些变化:

Here's those changes at work:

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>

这篇关于D3JS从数组数据绘制折线图(数据未定义错误)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆