如何将x轴值正确排列到图表中的垂直线?目前他们没有正确对齐。
var data = [
{
"due": 89.99,
"datestr": "2012-12-01 00:00:00",
"paid": 89.99
},
{
"due": 89.99,
"datestr": "2013-01-01 00:00:00",
"paid": 101.25
},
{
"due": 109.99,
"datestr": "2013-02-01 00:00:00",
"paid": 143.69
},
{
"due": 109.99,
"datestr": "2013-03-01 00:00:00",
"paid": 130.65
},
{
"due": 139.99,
"datestr": "2013-04-01 00:00:00",
"paid": 150.25
},
{
"due": 149.99,
"datestr": "2013-05-01 00:00:00",
"paid": 139.99
},
{
"due": 149.99,
"datestr": "2013-06-01 00:00:00",
"paid": 139.99
},
{
"due": 89.99,
"datestr": "2013-07-01 00:00:00",
"paid": 139.99
}
];
//Load values into new arrays
var amtDue = new Array();
var amtPaid = new Array();
for(var i=0; i < data.length; i++) {
amtDue[i] = data[i].due;
amtPaid[i] = data[i].paid;
}
// Margins, width and height.
var margin = {top: 20, right: 20, bottom: 60, left: 50},
width = 1000,
height = 400,
padding = 100;
// Scales.
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var due = d3.scale.linear().range([0, width]);
var paid = d3.scale.linear().range([0, width]);
//Domains
x.domain([d3.min(data, function(d) { return d.date; }), d3.max(data, function(d) { return d.date;})]);
y.domain([50, 300]);
due.domain([0, amtDue.length]);
paid.domain([0, amtPaid.length]);
// Construct our SVG object.
var svg = d3.select(".system-efficiency").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 + ")");
// X-axis MONTHS.
var xAxis = d3.svg.axis()
.scale(x)
.orient("top")
.tickSize(-height)
.tickFormat(d3.time.format('%b'));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(100," + 0 + ")")
.call(xAxis);
//X-axis Due Date
var dDate = d3.svg.axis()
.scale(due)
.orient("bottom")
.tickSize(0)
.tickFormat(function(d, i) {return amtDue[i];});
svg.append("g")
.attr("class", "damount axis")
.attr("transform", "translate(100," + (height) + ")")
.call(dDate);
//X-axis Paid Date
var pDate = d3.svg.axis()
.scale(paid)
.orient("bottom")
.tickSize(0)
.tickFormat(function(d, i) {return amtPaid[i];});
svg.append("g")
.attr("class", "pamount axis")
.attr("transform", "translate(100," + (height+20) + ")")
.call(pDate);
//Y-axis
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(0);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + 0 + ",0)")
.call(yAxis);
// Date parsing.
var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S");
data.forEach(function(d) {
d.date = parseDate.parse(d.datestr);
d.close = +d.close;
});
// Set scale domains.
x.domain(d3.extent(data, function(d) { return d.date; }));
//y.domain([0, d3.max(data, function(d) { return d.due; })]);
// Call x-axis.
d3.select(".x.axis")
//.transition().duration(1000)
.call(xAxis);
// Draw bars for amount due.
var bars = svg.selectAll("rect")
.data(data, function(d) { return d.datestr; });
bars.exit().remove();
// bars.transition().duration(1000)
// .attr("x", function(d) { return x(d.date); })
// .attr("width", width / data.length)
// .attr("y", function(d) { return y(d.due); })
// .attr("height", function(d) { return height - y(d.due);});
bars.enter().append("rect")
.attr("class", "duebar")
.attr("width", width/data.length)
.attr("x", function(d, i) { return i * (width / data.length); })
.attr("y", height)
.attr("height", 0)
.transition().duration(1000)
.attr("y", function(d) { return y(d.due); })
.attr("height", function(d) { return (y(d.due)+3)-y(d.due);});
// Line function.
var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.paid); });
// Draw line.
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
这是fiddle。
答案 0 :(得分:2)
在这里小提琴:http://jsfiddle.net/henbox/hbmwbnx6/
使用您当前的方法,这是可以修复的。首先,您有8个数据值(Dec&#39; 12到7月和#39; 13)。将d3.time.scale()
与该日期域一起使用将为您提供8个月的&#39;勾选,但是比例分为7个相等的间隙&#39;在蜱之间。
因此,要排列d3.scale.linear()
比例,您应该使用:
due.domain([0, amtDue.length - 1]);
而不是:
due.domain([0, amtDue.length]);
因为数组长度从1开始计数,而不是0。
另请注意,我从您的代码中删除了多个横向translate
我之所以这样说只是一种解决方法,那就是&#34;到期的条数&#34;几个月没有正确排队。这是因为条形宽度相等(使用.attr("width", width/(data.length -1))
)但是月份(d3.time
标度)的长度不相等:
解决方法是使用x
(时间)刻度来定义条宽
<强>更新强>
通过从数据中获取当前日期和之前的日期值,这里是对条形宽度问题的(略微hacky)解决方案的更新:http://jsfiddle.net/henbox/hbmwbnx6/1/
代码是:
// The first date from your data - don't hardcode!
var previousdate = new Date("2012-12-01 00:00:00")
bars.enter().append("rect")
.attr("class", "duebar")
.attr("width", function(d, i) {
widthval = x(d.date) - (x(previousdate));
previousdate = d.date;
return widthval;
})
.attr("x", function(d, i) {
xval = x(previousdate);
previousdate = d.date;
console.log(previousdate);
return xval;
})
...
请注意,此代码突出显示了另一个问题:条形图显示在两个日期之间显示数据,但实际显示特定时间点的数据。 12月&12;&#39;到期金额&#39;值未显示,而Jan&#13; 13值在图表中显示为为12月和1月之间的条。您需要决定如何显示此