D3 ...加载具有多个Y值的字典数组的最佳(推荐)方法

时间:2018-10-24 08:03:41

标签: d3.js

我有以下格式的数据(将其简化为仅包含两个值和3个数据点);

data = [
{
    "date": "23-10-2018 13:16:55",
    "temperature": 30,
    "humidity": 46
},   {
    "date": "23-10-2018 13:15:25",
    "temperature": 29,
    "humidity": 45
},  {
    "date": "23-10-2018 13:14:55",
    "temperature": 28,
    "humidity": 44
}].

我想针对每个参数(温度,湿度)与日期生成多个折线图。以下代码不适用于y生成器,因为value变量未传递到生成器函数内部。在D3v5(最新版本)中解决此问题的最佳/推荐方法是什么,尽管我非常喜欢D3,但不是D3的专家。任何帮助表示赞赏。


        `enter code here`

        var values = [temperature,humidity];
        for (var p = 0; p < values.length; p++) {

            var value = values[p];

            var parseDate = d3.timeParse("%Y-%m-%d %H:%M:%S");

            var shiftX = p * 350 +  30;
            var shiftY = 0;

            //D3 generators

            var y = d3.scaleLinear()
                    .domain([0,d3.max(data,function(d){
                        **return d.value;**
                    })])
                    .range([height,0]);
            var x = d3.scaleTime()
                    .domain(d3.extent(data,function(d){
                        var date = parseDate(d.date);
                        //console.log(d.date);

                        return date;
                    }))
                    .range([0,width]);

            var yAxis = d3.axisLeft(y).ticks(6).tickPadding(10).tickSize(10);
            var xAxis = d3.axisBottom(x).ticks(6).tickPadding(3).tickSize(10);


            var line = d3.line()
                    .x(function(d){ return x(parseDate(d.date)); })
                    .y(function(d){ return **y(d.value)**; });

        }

2 个答案:

答案 0 :(得分:1)

实际上@ rioV8是正确的,您需要通过键访问数据点来创建每一行,在这种情况下,键必须是字符串。

这是一个正在运行的示例,具有以下主要更改:

  1. 更改数据点以获得更多效果
  2. values重命名为更具表现力的名称topics
  3. 为图表添加了边距
  4. 更正的日期匹配模式
  5. 轴仅需绘制一次,通过同时检查两个主题即可计算出最大y值。如果您有更多主题,则逻辑上几乎不需要进行调整。
  6. 在实际绘制每个主题的行期间,需要将数据缩放到坐标系。

文件 index.html

<!doctype html>
<html>
  <head>
      <title>nested bars</title>
      <meta charset="utf-8">
      <style>
          svg.graphchart {
              border: 1px solid gray;
              background-color: lightyellow;
          }
          svg.graphchart text {
              font-style: normal;
              font-weight: normal;
              font-family: monospace;
              font-size: 10px;
              stroke: none;
          }
      </style>
    </head>
    <body>
        <svg class="graphchart" width="600" height="300"></svg>
    </body>
    <script src="node_modules/d3/dist/d3.js"></script>
    <script src="./graphchart.js"></script>
</html>

文件 graphchart.js

/** Variables **/

// changed data for more effect
var data = [
    {
       "date": "23-10-2018 13:14:55",
       "temperature": 8,
       "humidity": 14
   }, {
        "date": "23-10-2018 13:15:25",
        "temperature": 29,
        "humidity": 2
    }, {
        "date": "23-10-2018 13:16:55",
        "temperature": 10,
        "humidity": 20
    }
];

// which topics do we want to see
var topics = ['temperature', 'humidity'];

// svg specifics
var svg = d3.select('svg.graphchart');

// little margin
var margin = 40;
var width = svg.attr('width') - 2 * margin;
var height = svg.attr('height') - 2 * margin;

// the chart group
var chart = svg.append('g')
    .attr('transform', `translate(${margin}, ${margin})`);

// some colors for the lines
var colors = d3.schemeAccent;


/** Helpers **/

// needed to adjust date pattern
var parseDate = d3.timeParse("%d-%m-%Y %H:%M:%S");


/** Axes: need only be drawn once **/

// x axis
var xScale = d3.scaleTime()
    .domain(d3.extent(data, function(d){
        var date = parseDate(d.date);
        console.log(d.date);
        return date;
    }))
    .range([0, width]);
var xAxis = d3.axisBottom(xScale)
    .ticks(6)
    .tickPadding(3)
    .tickSize(10);
chart.append('g')
    .attr('stroke', 'gray')
    .attr('stroke-width', 1)
    .attr('transform', `translate(0,${height})`)
    .call(d3.axisBottom(xScale));

// y axis
var yScale = d3.scaleLinear()
    .domain([ 0, d3.max(data, function(d){
        return Math.max(d.temperature, d.humidity);
    })])
    .range([height, 0]);
var yAxis = d3.axisLeft(yScale)
    .ticks(6)
    .tickPadding(10)
    .tickSize(10);
chart.append('g')
    .attr('stroke', 'gray')
    .attr('stroke-width', 1)
    .call(yAxis);


/** render lines **/

// render one line
function renderLine(topic, color) {
    var line = d3.line()
        .x(function(d) { return xScale(parseDate(d.date)); })
        .y(function(d) { return yScale(d[topic]); });
    chart.append('path')
        .datum(data)
        .attr('stroke', color)
        .attr('fill', 'none')
        .attr('stroke-width', 2)
        .attr('d', line);
}
// render each line
topics.forEach(function(topic, i) {
    renderLine(topic, colors[i % colors.length]);
});

无论如何,这只是处理任务的一种方法。熟悉d3的推荐方法是在https://bl.ocks.org查阅声音文档和许多示例,然后使用它。

答案 1 :(得分:0)

使用按字符串建立对象索引

CreateMap<Entity, EntityResponse>(); is enough.