在nvd3结构中使用d3和json的多线图

时间:2015-10-04 12:13:51

标签: javascript jquery canvas d3.js svg

我尝试使用d3和json格式的数据创建多线图。出于某种原因,我的代码不起作用。我还没能找到我做错的地方。搜索过网络并阅读了很多例子,但都无济于事。我可能会盯着我对代码视而不见。

在这个例子中,我只是试图绘制两条线,但是线条的数量是未知的。所以我无法对其进行硬编码。有没有人对我做错的地方有任何提示?

Jsfiddle链接到代码。 http://jsfiddle.net/6qrcmsnj/3/

这也是代码。

var w = 700;
var h = 600;
var pad = 80;

var time_format = d3.time.format("%I:%M:%S");

var gd = example_data(4);


var xScale = d3.time.scale()
    .domain(d3.extent(gd[0].data, function(d) { return d[0]; }))
    .range([pad, w - pad]);

var yScale = d3.scale.linear()
    .domain([0, d3.max(gd[0].data, function(d) { return d[1]; })*2])
    .range([h - pad, pad]);

var canvas = d3.select("body")
    .append("svg")
        .attr("class", "chart")
        .attr("width", w)
        .attr("height", h);

var xaxis = d3.svg.axis()
    .scale(xScale)
    .orient("bottom")
    .tickFormat(time_format);

var yaxis = d3.svg.axis()
    .scale(yScale)
    .orient("left");

var line = d3.svg.line()
    .x(function(d) { return xScale(d[0]); })
    .y(function(d) { return yScale(d[1]); })
    .interpolate("linear");

// Just for a grey background.
canvas.append("rect")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("fill", "#E8E8E8");

// Add x-axis.
canvas.append("g")
    .attr("class", "axis")
    .attr("transform","translate(0," + (h - pad) + ")")
    .call(xaxis)
    .selectAll("text")
        .style("text-anchor", "end")
        .attr("dx", "-.8em")
        .attr("dy", ".15em")
        .attr("transform", function(d) {
                return "rotate(-65)"
                });

// Add y-axis
canvas.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + pad + ", 0)")
    .call(yaxis);

// Add line
canvas.selectAll("path")
    .data(gd)
    .enter().append("path")
    .attr("d", line(gd.data))
    .attr("stroke", "black")
    .attr("stroke-width", 1)
    .attr("fill", "none");

function example_data(val) {

    if (val == "4") {
        return [
            { "label" : "Data_1", "data" : [ [ 1404438592000, 21.09 ], [ 1404438593000, 10.85 ], [ 1404438594000, 15.74 ], [ 1404438595000, 20.86 ], [ 1404438596000, 10.83 ], [ 1404438597000, 8.92 ], [ 1404438598000, 23.68 ], [ 1404438599000, 20.68 ], [ 1404438600000, 14.68 ], [ 1404438601000, 4.65 ]] }, 
            { "label" : "Data_2", "data" : [ [ 1404438592000, 3.219 ], [ 1404438593000, 1.641 ], [ 1404438594000, 6.68 ], [ 1404438595000, 2.543 ], [ 1404438596000, 8.522 ], [ 1404438597000, 4.616 ], [ 1404438598000, 9.703 ], [ 1404438599000, 3.737 ], [ 1404438600000, 8.752 ], [ 1404438601000, 1.791 ]]}
        ];
    }           
}

3 个答案:

答案 0 :(得分:1)

我将你的jsfiddle复制到一个可以在下面查看的堆栈片段。循环遍历数据,为每个帖子创建一条线。

var total = 11;
var $pictures = $('.inner-pics');
var delta = 500;
var curent = 1;

for (var i = 1; i < total; i++) {
    $('#slideshow .inner-pics').append('<div class="slide-' + i + '">');
    $('#slideshow .inner-pics div:last').append('<img src="http://lorempixel.com/500/300/food/' + i + '" />');
    $('#slideshow .inner-pics div:last').append('<b>Slide ' + i + '</b>'); //add text to slide
    $('#slideshow .inner-pics').append('</div>');
    $('.circle').append('<i class="fa fa-circle">-</i>');
}

function slideAnimationLeft() {
    if(curent<=1) return false;
    curent --;
    $pictures.animate({
        'margin-left': "+="+delta
    }, 1000);
};

function slideAnimationRight() {
    if(curent>=total) return false;
    curent ++;
    $pictures.animate({
        'margin-left': "-="+delta
    }, 1000);
};

$('.left >').click(function (e) {
    e.preventDefault();
    slideAnimationLeft();
});
$('.right >').click(function (e) {
    e.preventDefault();
    slideAnimationRight();
});

&#13;
&#13;
for(var i = 0; i < gd.length; i++)
{
   canvas.append("path")
   .data([gd[i].data])
   .attr("d", line).attr("class", "line" + i);
}
&#13;
var w = 700;
var h = 600;
var pad = 80;

var time_format = d3.time.format("%I:%M:%S");

var gd = example_data(4);
var xScale = d3.time.scale()
  .domain(d3.extent(gd[0].data, function(d) {
    return d[0];
  }))
  .range([pad, w - pad]);

var yScale = d3.scale.linear()
  .domain([0, d3.max(gd[0].data, function(d) {
    return d[1];
  }) * 2])
  .range([h - pad, pad]);

var canvas = d3.select("body")
  .append("svg")
  .attr("class", "chart")
  .attr("width", w)
  .attr("height", h);

var xaxis = d3.svg.axis()
  .scale(xScale)
  .orient("bottom")
  .tickFormat(time_format);

var yaxis = d3.svg.axis()
  .scale(yScale)
  .orient("left");

var line = d3.svg.line()
  .x(function(d) {
    return xScale(d[0]);
  })
  .y(function(d) {
    return yScale(d[1]);
  })
  .interpolate("linear");

// Just for a grey background.
canvas.append("rect")
  .attr("width", "100%")
  .attr("height", "100%")
  .attr("fill", "#E8E8E8");

// Add x-axis.
canvas.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0," + (h - pad) + ")")
  .call(xaxis)
  .selectAll("text")
  .style("text-anchor", "end")
  .attr("dx", "-.8em")
  .attr("dy", ".15em")
  .attr("transform", function(d) {
    return "rotate(-65)"
  });

// Add y-axis
canvas.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(" + pad + ", 0)")
  .call(yaxis);

for (var i = 0; i < gd.length; i++) {

  // Add line
  canvas.append("path")
    .data([gd[i].data])
    .attr("d", line).attr("class", "line" + i);

}

function example_data(val) {

  if (val == "4") {
    return [{
      "label": "Data_1",
      "data": [
        [1404438592000, 21.09],
        [1404438593000, 10.85],
        [1404438594000, 15.74],
        [1404438595000, 20.86],
        [1404438596000, 10.83],
        [1404438597000, 8.92],
        [1404438598000, 23.68],
        [1404438599000, 20.68],
        [1404438600000, 14.68],
        [1404438601000, 4.65]
      ]
    }, {
      "label": "Data_2",
      "data": [
        [1404438592000, 3.219],
        [1404438593000, 1.641],
        [1404438594000, 6.68],
        [1404438595000, 2.543],
        [1404438596000, 8.522],
        [1404438597000, 4.616],
        [1404438598000, 9.703],
        [1404438599000, 3.737],
        [1404438600000, 8.752],
        [1404438601000, 1.791]
      ]
    }];
  }
}
&#13;
.axis path,
.axis line {
  fill: none;
  stroke: black;
  shape-rendering: crispEdges;
}
.line0 {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}
.line1 {
  fill: none;
  stroke: red;
  stroke-width: 1.5px;
}
&#13;
&#13;
&#13;

答案 1 :(得分:1)

@LarThoren方法肯定会有用,但是d3我们希望避免显式循环。你的版本遗漏了两件事:

canvas.selectAll(".series") //<-- don't selectAll with "path", there are other paths in the axis and you selection needs to be more specific
  .data(gd)
  .enter()
  .append("path")
  .attr("d", function(d){ //<-- gd is out of scope here, you need to use the accessor function
    return line(d.data);
  }) 
  .attr("class", "series")
  .attr("stroke", "black")
  .attr("stroke-width", 1)
  .attr("fill", "none");

完整的工作代码:

var w = 700;
var h = 600;
var pad = 80;

var time_format = d3.time.format("%I:%M:%S");

var gd = example_data(4);
	
var xScale = d3.time.scale()
	.domain(d3.extent(gd[0].data, function(d) { return d[0]; }))
	.range([pad, w - pad]);

var yScale = d3.scale.linear()
	.domain([0, d3.max(gd[0].data, function(d) { return d[1]; })*2])
	.range([h - pad, pad]);

var canvas = d3.select("body")
	.append("svg")
		.attr("class", "chart")
		.attr("width", w)
		.attr("height", h);

var xaxis = d3.svg.axis()
	.scale(xScale)
	.orient("bottom")
	.tickFormat(time_format);

var yaxis = d3.svg.axis()
	.scale(yScale)
	.orient("left");

var line = d3.svg.line()
	.x(function(d) { return xScale(d[0]); })
	.y(function(d) { return yScale(d[1]); })
	.interpolate("linear");

// Just for a grey background.
canvas.append("rect")
	.attr("width", "100%")
	.attr("height", "100%")
	.attr("fill", "#E8E8E8");

// Add x-axis.
canvas.append("g")
	.attr("class", "axis")
	.attr("transform","translate(0," + (h - pad) + ")")
	.call(xaxis)
	.selectAll("text")
		.style("text-anchor", "end")
		.attr("dx", "-.8em")
		.attr("dy", ".15em")
		.attr("transform", function(d) {
				return "rotate(-65)"
				});

// Add y-axis
canvas.append("g")
	.attr("class", "axis")
	.attr("transform", "translate(" + pad + ", 0)")
	.call(yaxis);

// Add line
canvas.selectAll(".series")
	.data(gd)
	.enter()
	.append("path")
	.attr("d", function(d){
    	return line(d.data);
	})
	.attr("class", "series")
	.attr("stroke", "black")
	.attr("stroke-width", 1)
	.attr("fill", "none");

function example_data(val) {
	
	if (val == "4") {
		return [
			{ "label" : "Data_1", "data" : [ [ 1404438592000, 21.09 ], [ 1404438593000, 10.85 ], [ 1404438594000, 15.74 ], [ 1404438595000, 20.86 ], [ 1404438596000, 10.83 ], [ 1404438597000, 8.92 ], [ 1404438598000, 23.68 ], [ 1404438599000, 20.68 ], [ 1404438600000, 14.68 ], [ 1404438601000, 4.65 ]] }, 
			{ "label" : "Data_2", "data" : [ [ 1404438592000, 3.219 ], [ 1404438593000, 1.641 ], [ 1404438594000, 6.68 ], [ 1404438595000, 2.543 ], [ 1404438596000, 8.522 ], [ 1404438597000, 4.616 ], [ 1404438598000, 9.703 ], [ 1404438599000, 3.737 ], [ 1404438600000, 8.752 ], [ 1404438601000, 1.791 ]]}
		];
	}			
}
.axis path,
.axis line {
	fill: none;
	stroke: black;
	shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

答案 2 :(得分:1)

两个变化

.attr("d", line(gd.data))

应该是

.attr("d", function (d) { return line(d.data) })

首先

和路径然后添加轴。它应该工作。基本上selectAll(&#39; path&#39;)从轴元素中拾取路径元素。