D3.js结合了条形图和折线图 [英] D3.js combining bar and line chart

查看:83
本文介绍了D3.js结合了条形图和折线图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过将条形图与折线图组合来创建多系列图表。当我使用 rangeBands()来设置输出范围时,该行开始在第一个条的开头绘制,并在最后一个条的开头结束图表。我应该更改什么,以便该行从第一个刻度开始并在最后一个刻度结束?

I want to create a multiple series chart, by combining a bar with a line chart. When I use the rangeBands() for setting the output range, the line begins to be drawn at the beginning of the first bar, and ends at the beginning of the last bar from the chart. What should I change so the line begins over the fist tick and ends over the last tick?

var data = [{ date: '1-May-12', close: 58.13, open: 7.41 }, { date: '2-May-12', close: 53.98, open: 45.55 }, { date: '3-May-12', close: 67.00, open: 11.78}];

var margin = { top: 30, right: 40, bottom: 30, left: 50 },
	width = 600 - margin.left - margin.right,
	height = 270 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").parse;

var x = d3.scale.ordinal().rangeBands([0, width], .09); // <-- to change the width of the columns, change the .09 at the end to whatever
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x)
	.orient("bottom")
	.tickFormat(d3.time.format("%d-%b-%y"));

var yAxisLeft = d3.svg.axis().scale(y)
	.orient("left");

var valueline = d3.svg.line()
	.x(function (d) { return x(d.date); })
	.y(function (d) { return y(d.open); });

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 + ")");

// Get the data
data.forEach(function (d) {
	d.date = parseDate(d.date);
	d.close = +d.close;
	d.open = +d.open;
});

// Scale the range of the data
x.domain(data.map(function (d) { return d.date; }));
y.domain([0, d3.max(data, function (d) { return d.close; })]);

// Add the X Axis
svg.append("g")
		.attr("class", "x axis")
		.attr("transform", "translate(0," + height + ")")
		.call(xAxis);

// Add the Y Axis
svg.append("g")
		.attr("class", "y axis")
		.style("fill", "steelblue")
		.call(yAxisLeft);

// Draw the bars
svg.selectAll("bar")
		.data(data)
		.enter()
		.append("rect")
		.style("fill", "#99ffcc")
		.attr("x", function (d) { return x(d.date); })
		.attr("width", x.rangeBand())
		.attr("y", function (d) { return y(d.close); })
		.attr("height", function (d) { return height - y(d.close); });

// Add the valueline path
svg.append("path")
		.attr("d", valueline(data));

body {
  font: 12px Arial;
}
path {
  stroke: red;
  stroke-width: 2;
  fill: none;
}
.axis path,
.axis line {
  fill: none;
  stroke: grey;
  stroke-width: 1;
  shape-rendering: crispEdges;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

推荐答案

将行函数x存取器调整为测距范围的一半:

Adjust the line functions x accessor by half the rangeband:

var valueline = d3.svg.line()
    .x(function (d) { return x(d.date) + x.rangeBand()/2; })
    .y(function (d) { return y(d.open); });






完整代码:


Full Code:

var data = [{ date: '1-May-12', close: 58.13, open: 7.41 }, { date: '2-May-12', close: 53.98, open: 45.55 }, { date: '3-May-12', close: 67.00, open: 11.78}];

var margin = { top: 30, right: 40, bottom: 30, left: 50 },
	width = 600 - margin.left - margin.right,
	height = 270 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").parse;

var x = d3.scale.ordinal().rangeBands([0, width], .09); // <-- to change the width of the columns, change the .09 at the end to whatever
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x)
	.orient("bottom")
	.tickFormat(d3.time.format("%d-%b-%y"));

var yAxisLeft = d3.svg.axis().scale(y)
	.orient("left");

var valueline = d3.svg.line()
	.x(function (d) { return x(d.date) + x.rangeBand()/2; })
	.y(function (d) { return y(d.open); });

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 + ")");

// Get the data
data.forEach(function (d) {
	d.date = parseDate(d.date);
	d.close = +d.close;
	d.open = +d.open;
});

// Scale the range of the data
x.domain(data.map(function (d) { return d.date; }));
y.domain([0, d3.max(data, function (d) { return d.close; })]);

// Add the X Axis
svg.append("g")
		.attr("class", "x axis")
		.attr("transform", "translate(0," + height + ")")
		.call(xAxis);

// Add the Y Axis
svg.append("g")
		.attr("class", "y axis")
		.style("fill", "steelblue")
		.call(yAxisLeft);

// Draw the bars
svg.selectAll("bar")
		.data(data)
		.enter()
		.append("rect")
		.style("fill", "#99ffcc")
		.attr("x", function (d) { return x(d.date); })
		.attr("width", x.rangeBand())
		.attr("y", function (d) { return y(d.close); })
		.attr("height", function (d) { return height - y(d.close); });

// Add the valueline path
svg.append("path")
		.attr("d", valueline(data));

body {
  font: 12px Arial;
}
path {
  stroke: red;
  stroke-width: 2;
  fill: none;
}
.axis path,
.axis line {
  fill: none;
  stroke: grey;
  stroke-width: 1;
  shape-rendering: crispEdges;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

这篇关于D3.js结合了条形图和折线图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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