我使用在线发现的各种例子来学习d3j。
我一直试图用双Y轴和X轴绘制图表。左侧的Y轴将绘制相对于X轴的条图表,右侧的Y轴将针对X轴绘制线图表。条形图完全按照要求绘制,但折线图没有。 X轴是日期(2015-10-15 04:10)。以this为例。
我写的代码
var margin = {top: 50, right: 50, bottom: 100, left: 50},
width = 900 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%m/%d/%Y %H:%M:%S").parse;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var yTxnVol = d3.scale.linear().range([height, 0]);
var yResTime = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(yTxnVol)
.orient("left")
var yAxis2 = d3.svg.axis()
.scale(yResTime)
.orient("right")
.ticks(10);
var svg = d3.selectAll("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 + ")");
d3.csv("../res/data.csv", function(error, data) {
data.forEach(function(d) {
d.AVRG_RESP_TIME = +d.AVRG_RESP_TIME;
d.TXN_VOL = +d.TXN_VOL;
});
x.domain(data.map(function(d) { return d.TYM; }));
yTxnVol.domain([0, d3.max(data, function(d) { return d.TXN_VOL+50; })]);
yResTime.domain([0, d3.max(data, function(d) { return d.AVRG_RESP_TIME+50; })]);
var minDate = d3.min(data, function(d){return d.TYM});
var maxDate = d3.max(data, function(d){ return d.TYM});
var xScale = d3.time.scale().range([0,width]);//.domain([minDate, maxDate]);
xScale.domain(d3.extent(data, function(d) { return new Date(d.TYM); }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
svg.append("g")
.attr("class","y axis")
.attr("transform","translate("+width+ ", 0)")
.call(yAxis2)
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.attr("class", "yhover")
.attr("x", function(d) { return x(d.TYM); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return yTxnVol(d.TXN_VOL); })
.attr("height", function(d) { return height - yTxnVol(d.TXN_VOL); })
var line = d3.svg.line()
.x(function(d) { return xScale(new Date(d.TYM));})
.y(function(d) { return d.AVRG_RESP_TIME; });
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
});
输出尝试将其设置为有意义的折线图。格式化日期时出现NaN错误。
有人可以帮助我制作一个合适的折线图吗?
csv数据样本
TYM,AVRG_RESP_TIME,TXN_VOL
2015-10-15 04:00:00,11,170
2015-10-15 04:10:00,18,220
2015-10-15 04:20:00,28,251
2015-10-15 05:00:19,19
答案 0 :(得分:1)
首先,修复您的csv文件。格式不正确,逗号后不应有空格。
其次,您正在尝试为您的xAxis混合有序量表和时间刻度。这不会起作用。对于您的用例,只需坚持时间。
以下是使用解释性注释重新编写代码:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<script>
var margin = {
top: 50,
right: 50,
bottom: 100,
left: 50
},
width = 900 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
// x scale should be time and only time
var x = d3.time.scale().range([0, width]);
var yTxnVol = d3.scale.linear().range([height, 0]);
var yResTime = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(yTxnVol)
.orient("left")
var yAxis2 = d3.svg.axis()
.scale(yResTime)
.orient("right")
.ticks(10);
var svg = d3.selectAll("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 + ")");
//d3.csv("data.csv", function(error, data) {
var data = [{"TYM":"2015-10-15 04:00:00","AVRG_RESP_TIME":"12","TXN_VOL":"170"},{"TYM":"2015-10-15 04:10:00","AVRG_RESP_TIME":"18","TXN_VOL":"220"},{"TYM":"2015-10-15 04:20:00","AVRG_RESP_TIME":"28","TXN_VOL":"251"},{"TYM":"2015-10-15 05:00:00","AVRG_RESP_TIME":"19","TXN_VOL":"100"}];
// just make TYM a date and keep it as a date
data.forEach(function(d) {
d.TYM = parseDate(d.TYM);
d.AVRG_RESP_TIME = +d.AVRG_RESP_TIME;
d.TXN_VOL = +d.TXN_VOL;
});
// get our min and max date in milliseconds
// set a padding around our domain of 15%
var minDate = d3.min(data, function(d){
return d.TYM;
}).getTime();
var maxDate = d3.max(data, function(d){
return d.TYM;
}).getTime();
var padDate = (maxDate - minDate) * .15;
x.domain([new Date(minDate - padDate), new Date(maxDate + padDate)]);
yTxnVol.domain([0, d3.max(data, function(d) {
return d.TXN_VOL + 50;
})]);
yResTime.domain([0, d3.max(data, function(d) {
return d.AVRG_RESP_TIME + 50;
})]);
// set an intelligent bar width
var barWidth = (width / x.ticks().length) - 20;
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ", 0)")
.call(yAxis2)
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.attr("class", "yhover")
.attr("x", function(d) {
// center bar on time
return x(d.TYM) - (barWidth / 2);
})
.attr("width", barWidth)
.attr("y", function(d) {
return yTxnVol(d.TXN_VOL);
})
.attr("height", function(d) {
return height - yTxnVol(d.TXN_VOL);
})
.style("fill","orange");
var line = d3.svg.line()
.x(function(d) {
return x(d.TYM);
})
.y(function(d) {
return d.AVRG_RESP_TIME;
});
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line)
.style("fill","none")
.style("stroke","steelblue")
.style("stoke-width","3px");
// });
</script>
</body>
</html>
答案 1 :(得分:0)
填充黑色的折线图的问题是由于css不正确。新的css属性。
.line {
fill: none;
stroke: darkgreen;
stroke-width: 2.5px;
}
对于我将其格式化为(%Y-%m-%d%H:%M)格式的日期并且它有效。