【问题标题】:D3.js just drawing a vertical line not actually graphingD3.js 只是画一条垂直线而不是实际绘图
【发布时间】:2017-07-26 05:26:33
【问题描述】:

我一直在搜索我的一堆帖子和教程,试图找出 d3,我想我已经找到了大部分,但这不是画线,我不知道为什么。这是一个简单的d3.line() 图表。数据必须转换为适合.line() 的格式,而且确实如此。我还在控制台中确认该数据的格式为

[{time: 1881, temp: -10} , {time: 1882, temp: -9 } ...]

如果有人可以帮助我解决这个问题,我将不胜感激。 d3 v4 还有什么好的教程吗?

    var width = 500;
    var height = 500;
    var margin = 25;
    var axisLength = width - 2 * margin;


    var svg = d3.select("body")
      .append("svg")
        .attr("width", width)
        .attr("height", height)
      .style("border", "1px solid");



     // 5. X scale will use the index of our data
     var xScale = d3.scaleTime()
        .domain(d3.extent([new Date(1881,0,1),new Date(2015,0,1)]))
        .range([0, width]); // output

    // 6. Y scale will use the randomly generate number 
    var yScale = d3.scaleLinear()
        .domain(d3.extent(tempArrMap["Glob"], function(d) {return d;})) 
        .range([height, 0]); // output 

    var xAxis = d3.axisBottom(xScale);
    var yAxis = d3.axisLeft(yScale);

    svg.append("g")
          .classed("x-axis", true)
          .attr("transform", function() {
            return "translate(" + margin + "," + (height - margin) + ")";
          })
        .call(xAxis);




    var yrsCol = getCol(tempData,0)
    var globCol = getCol(tempData,1);


    var LineData = { x:yrsCol, y:globCol};

    function fn(data){
        var out = data.y.map(function (_, idx) {
           return { time: data.x[idx], temp: data.y[idx] }; 
    });
       return out;
    }

     svg.append("g")
         .classed("y-axis", true)
          .attr("transform", function() {
       return "translate(" + margin + "," + margin + ")";
      })
     .call(yAxis);

    var inLineData = fn(LineData);

inLineData 现在的形式适合d3.line() 是形式中的对象数组。我已经通过控制台确认数据的有效性。

[{time: 1881, temp: -10} , {time: 1882, temp: -9 } ...]

    var line = d3.line()
          .x(function(d) { return xScale(d.time); })
          .y(function(d) { return yScale(d.temp); });

    svg.append("path")
      .attr("d", line(inLineData))
      .attr("fill", "none")
      .attr("stroke", "red")
      .attr("transform", function() {
        return "translate(" + margin + "," + margin + ")";
      });

【问题讨论】:

  • Yourtime 属性不是日期,而只是数字。你必须解析它们。

标签: javascript d3.js data-visualization


【解决方案1】:

在您的 sn-p 中,您似乎缺少 D3 生命周期方法,尤其是 enter()。

http://synthesis.sbecker.net/articles/2012/07/09/learning-d3-part-2

但是让我们先说,我们只有一个空白页,没有 段落。我们如何在页面上获得新的段落,代表 数据?输入 .enter()。当我们在现有选择上调用 enter() 时, 我们切换到一个子选择,代表尚未成为的数据 映射到一个元素,因为在 页面来表示所有当前数据集。换句话说,如果有 我们数据集中的数据比页面上的元素多,“输入” 子选择代表尚未添加的元素。

Bostock 本人在条形图上进行了易于遵循的演练。这可能有助于消除您的实现中缺少的任何混淆。

https://bost.ocks.org/mike/bar/

又是那个讨厌的 enter()。

由于我们知道选择是空的,返回的更新并退出 selections 也是空的,我们只需要处理 enter 选择 它表示没有现有元素的新数据。我们 通过附加到输入实例化这些缺失的元素 选择。

var barEnter = barUpdate.enter().append("div");

【讨论】:

  • 这不是 OP 的问题:您可以在没有输入选择的情况下附加路径。
  • 很公平。我对 D3 很轻,它只是我碰巧注意到丢失的第一件事,我在每个 D3 项目中都看到过它……那么错误是什么?但是,该示例中似乎缺少代码...在此 sn-p 中使用了 tempArrMap 变量但未定义。
  • 解析日期。 OP 正在将数字传递给时间尺度。
  • 不确定这如何破坏他们的应用程序......他们解析为 Time 对象。 var xScale = d3.scaleTime() .domain(d3.extent([new Date(1881,0,1),new Date(2015,0,1)])) .range([0, width]); // 输出未定义的 xScale 函数 r(n){return(o||(o=i(a,c,f?eu(t):t,s)))(+n)} new Date(1881, 0, 1) 1881 年 1 月 1 日星期六 00:00:00 GMT-0800 (PST)....而且粘贴得不太好..
  • 秤不解析任何东西。您必须将日期对象传递给时间刻度,而不是数字。