【问题标题】:How to load data to D3 chart from JSON when there are only tuples只有元组时如何将数据从 JSON 加载到 D3 图表
【发布时间】:2018-11-14 14:07:13
【问题描述】:

我有一个如下所示的 JSON 文件:

编辑:我使用日期作为键,而不是我之前输入的整数。

"2005-12-01": 120,
"2005-10-01": 32,

现在我需要使用第一列作为 X 轴,另一列作为 Y 轴。 在示例中,它们通过元素名称引用值,例如:

const line = d3.line()
    .x(d => x(d.date))
    .y(d => y(d.value));

我在这里做不到。

【问题讨论】:

    标签: javascript json d3.js


    【解决方案1】:

    您必须将键映射到具有键/值对的对象数组,然后使用它来设置域并画线。

    // The number of datapoints
    var json = {
      "2005-12-01": 120,
      "2005-10-01": 32,
      "2005-08-01": 20,
      "2005-06-01": 123
    };
    
    var data = Object.keys(json).map(function (k) { 
      return {date: new Date(k), value: +json[k]};
    });
    

    其余代码与绘制简单折线图相同。

    我使用来自您问题的 JSON 作为输入数据创建了一个示例 d3 折线图的分支。 (除了数据映射几乎不需要改变任何行)

    <!DOCTYPE html>
    <meta charset="utf-8">
    
    <style type="text/css">
    .line {
        fill: none;
        stroke: #ffab00;
        stroke-width: 3;
    }
    </style>
    <body>
    </body>
    
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>
    
    // 2. Use the margin convention practice 
    var margin = {top: 50, right: 50, bottom: 50, left: 50}
      , width = window.innerWidth - margin.left - margin.right // Use the window's width 
      , height = window.innerHeight - margin.top - margin.bottom; // Use the window's height
    
    // The number of datapoints
    var json = {
    "2005-12-01": 120,
    "2005-10-01": 32,
    "2005-08-01": 20,
    "2005-06-01": 123
    };
    
    var data = Object.keys(json).map(function (k) { return {date: new Date(k), value: +json[k]};});
    
    // 5. X scale will use the index of our data
    var xScale = d3.scaleTime()
        .domain(d3.extent(data, d => d.date)) // input
        .range([0, width]); // output
    
    // 6. Y scale will use the randomly generate number 
    var yScale = d3.scaleLinear()
        .domain(d3.extent(data, d => d.value)) // input 
        .range([height, 0]); // output 
    
    // 7. d3's line generator
    var line = d3.line()
        .x(function(d, i) { return xScale(d.date); }) // set the x values for the line generator
        .y(function(d) { return yScale(d.value); }) // set the y values for the line generator 
        .curve(d3.curveMonotoneX) // apply smoothing to the line
    
    // 1. Add the SVG to the page and employ #2
    var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    // 3. Call the x axis in a group tag
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom
    
    // 4. Call the y axis in a group tag
    svg.append("g")
        .attr("class", "y axis")
        .call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft
    
    // 9. Append the path, bind the data, and call the line generator 
    svg.append("path")
        .datum(data) // 10. Binds data to the line 
        .attr("class", "line") // Assign a class for styling 
        .attr("d", line); // 11. Calls the line generator 
    
    </script>

    【讨论】:

    • 谢谢,我想弄清楚,你在哪里设置域?像 x.domain(d3.extent...) 之类的东西
    • 是的,查看sn-p中的代码。它的域设置为.domain(d3.extent(data, d =&gt; d.date))
    • @Ah,谢谢,我正在使用另一个示例,代码有点不同:( 需要玩一会儿
    • 我不断收到 Error: attribute d: Expected number, "MNaN,150CNaN,NaN,..." 错误,我猜它与日期有关?
    • 我明白了,这是 Parsetime 的问题,我离开了旧格式。再次感谢!
    【解决方案2】:

    遍历 JSON 的键并创建新对象

    data = Object.keys(data).map(k => { return {x:+k, value: data[k]}; });
    

    也许你需要对数组进行排序

    data.sort( (a,b) => a.x - b.x );
    

    var data = {"0": 120,
    "1": 32,
    "2": 234,
    "3": 43};
    
    data = Object.keys(data).map(k => { return {x:+k, value: data[k]}; });
    
    console.log(data);

    【讨论】:

    • @JohnV 不是 NaN,而是一个小的语法错误,忘记了)
    • 是的,我也修复了,但我仍然得到 NaN。可能是我的键是 YYYY-MM-DD 格式的日期吗?
    • 是的,我把它作为一个例子,我不知道它是否重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 2015-11-29
    相关资源
    最近更新 更多