多条线d3 [英] multiple lines d3

查看:161
本文介绍了多条线d3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用d3做一个简单的情节。它工作正常,当我只绘制一条线时,但我想让我的代码更通用。



我的数据是这种格式(注意,2套数据可能不包含相同的点数,并且时间在我的两组测量之间不完全同步):


var data = [ {key:kmm03,value:[{time:1364108443000,mesure:1.6299999952316284},{time:1364108503000,mesure:1.100000023841858},{time:1364108563000, mesure:1.159999966621399},
{key:kmm04,value:[{time:1364108416000,mesure:2.690000057220459},{time:1364108476000,mesure: 3.319999933242798},{time:1364108536000,mesure:3.140000104904175},{time:1364108596000,mesure:2.9800000190734863}}]


现在我尝试这样绘制,但我不能得到svg行来dispay:

  var margin = {top:20,right:40,bottom:20,left:40}; 
var width = 780 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;


var time_scale = d3.time.scale()
//.domain(time_extent)
.domain([1364108443000,1364112559000])
.range([0,width]);

var mesure_scale = d3.scale.linear()
.domain([0,10])
.range([height,0]);

var vis = d3.select(#box1)
.append(svg:svg)
.attr(width,width + margin.left + margin.right)
.attr(height,height + margin.top + margin.bottom)
.attr(transform,translate(+ margin.left +,+ margin .top +));



var time_axis = d3.svg.axis()
.scale(time_scale)
.orient(bottom);
var mesure_axis = d3.svg.axis()
.scale(mesure_scale)
.orient(left);

var set_axis_t = vis.append(svg:g)
.attr(transform,translate(0,+ height +))
。 call(time_axis);

var set_axis_m = vis.append(svg:g)
.attr(transform,translate(0,0))
.call(mesure_axis) ;


var line = d3.svg.line()
.x(function(d){return time_scale(d.time);})
.y (function(d){return mesure_scale(d.mesure);});

var group = vis.selectAll('path')
.data(data)
.enter()。append('path')
.attr d,line);


解决方案

d3 selection.data()需要一个元素数组。在你的代码中,数据var是两个对象的数组。当你在d上调用line时,d3在每个元素中寻找时间和度量属性。这些不存在,因此不附加路径。



要呈现的金额和时间值在每个对象的value属性中向下嵌套一层。 p>

要绘制这些,请将 .attr('d',line)更改为 .attr (d,function(d){return line(d.value);});



这是一个工作版本。为了使它工作,我做了一些其他的变化:



1-缺少值数组的闭括号



2- .selectAll('path')对数据不起作用,因为它与轴中的路径元素冲突。为了解决这个问题,我分配了类visline的数据路径并使用 .selectAll('。visline')来访问它们


I'm trying to do a simple plot with d3. It works fine when I plot only one line at time but I would like to make my code more generic.

My data are in this format (note that the 2 set of data may not contain the same amount of point and the time is not perfectly synchronize between my 2 sets of measure):

var data = [{key: "kmm03", value:[{"time":1364108443000,"mesure":"1.6299999952316284"},{"time":1364108503000,"mesure":"1.100000023841858"},{"time":1364108563000,"mesure":"1.159999966621399"}}, {key: "kmm04", value:[{"time":1364108416000,"mesure":"2.690000057220459"},{"time":1364108476000,"mesure":"3.319999933242798"},{"time":1364108536000,"mesure":"3.140000104904175"},{"time":1364108596000,"mesure":"2.9800000190734863"}}]

Now I try to plot it like this but I cannot get the svg lines to dispay:

    var margin = {top: 20, right: 40, bottom: 20, left: 40};
    var width = 780 - margin.left - margin.right,
    height = 250 - margin.top - margin.bottom;


    var time_scale = d3.time.scale()
        //.domain(time_extent)
        .domain([1364108443000, 1364112559000])
        .range([0, width]);

    var mesure_scale = d3.scale.linear()
        .domain([0,10])
        .range([height, 0]);

    var vis = d3.select("#box1")
    .append("svg:svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");



    var time_axis = d3.svg.axis()
        .scale(time_scale)
        .orient("bottom");
    var mesure_axis = d3.svg.axis()
        .scale(mesure_scale)
        .orient("left");

    var set_axis_t = vis.append("svg:g")
      .attr("transform", "translate(0, " + height +")")
      .call(time_axis);

    var set_axis_m = vis.append("svg:g")
    .attr("transform", "translate(0, 0)")
    .call(mesure_axis);


    var line = d3.svg.line()
        .x(function(d){return time_scale(d.time);})
        .y(function(d){return mesure_scale(d.mesure);});

    var group = vis.selectAll('path')
       .data(data)
       .enter().append('path')
       .attr("d", line);

解决方案

d3 selection.data() takes an array of elements. In your code the data var is an array of two objects. When you call line on d, d3 looks for time and measure properties in each element. These don't exist so no paths are appended.

The amount and time values you want to render are nested one layer down in the value property of each object.

To draw these, change the .attr('d', line) to .attr("d", function(d) {return line(d.value);});

Here is a working version. To make it work I made a few other changes:

1- closing brackets of the value arrays were missing

2- .selectAll('path') was not working for the data because it was conflicting with the path elements in the axes. To address this, I assigned the data paths the class visline and use .selectAll('.visline') to access them

这篇关于多条线d3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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