我试图稳定这个图表 - 我试图比较日期对象 - 但后来遇到了夏季时差的问题 - 我不确定为什么数据的变化打破了图表 - 我得到了一个未定义的问题。
//工作js小提琴 http://jsfiddle.net/Qh9X5/10379/
//破坏js小提琴 http://jsfiddle.net/Qh9X5/10380/
- 所以当将额外的数据添加到图表时 - 它会创建一个未定义的错误
, {
"text-start": "Text9",
"date-start": "2012-05-01",
"text-end": "Text10",
"date-end": "2012-05-03"
}
我起初认为可能需要强制yAxis显示1天的增量 - .ticks(d3.time.days(min,max).length),好像中间可能不存在坐标天。
这是工作表的代码
var data = [{
"text-start": "Text1",
"date-start": "2012-04-21",
"text-end": "Text2",
"date-end": "2012-04-26"
}, {
"text-start": "Text3",
"date-start": "2012-04-22",
"text-end": "Text4",
"date-end": "2012-04-25"
}, {
"text-start": "Text5",
"date-start": "2012-04-26",
"text-end": "Text6",
"date-end": "2012-04-28"
}, {
"text-start": "Text7",
"date-start": "2012-04-21",
"text-end": "Text8",
"date-end": "2012-04-23"
}];
var margin = {
top: 40,
right: 40,
bottom: 40,
left: 60
},
width = 600,
height = 500;
function colores_google(n) {
var colores_g = ["#e9168a", "#f8dd2f", "#448875", "#c3bd75", "#2b2d39", "#311854", "#553814", "#f7b363", "#89191d", "#c12f34", "#2b2a2c", "#c5b8a6", "#57585b"];
return colores_g[n % colores_g.length];
}
var y = d3.time.scale().range([height - margin.top - margin.bottom, 0]);
var arrayofDates = [];
$.each(data, function(index, value) {
arrayofDates.push(value["date-start"]);
arrayofDates.push(value["date-end"]);
});
var parseDate = d3.time.format("%m/%d/%Y").parse;
var min = new Date(d3.min(arrayofDates.map(d=>d)));
var max = new Date(d3.max(arrayofDates.map(d=>d)));
y.domain([min,max]);
var chart = d3.select('#timelines').append('svg')
.attr('class', 'chart')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
//http://stackoverflow.com/questions/22722952/how-can-i-get-the-d3-js-axis-ticks-and-positions-as-an-array
var axisArray = [];
var yAxis = d3.svg.axis()
.scale(y)
.orient('left')
.tickPadding(1);
chart.append('g')
.attr('class', 'y axis')
.call(yAxis)
.selectAll(".tick").each(function(data) {
var tick = d3.select(this);
// pull the transform data out of the tick
var transform = d3.transform(tick.attr("transform")).translate;
// passed in "data" is the value of the tick, transform[0] holds the X value
//console.log("each tick", data, transform);
var month = data.getMonth() + 1;
if (month < 10) {
month = "0" + month;
}
var datestring = data.getFullYear() + "-" + month + "-" + data.getDate();
var obj = {
"data": datestring,
"transform": transform
}
axisArray.push(obj);
});
var links = chart.append('g')
.attr('class', 'links')
.attr("transform", "translate(0,0)");
function getRadius(d) {
var count = 2;
var ratio = count * 2.8;
if (count == 1) {
ratio = 10;
}
return ratio;
}
function getPos(date) {
var trans;
$.each(axisArray, function(index, value) {
var a = value.data;
var b = date;
//console.log("a", a)
//console.log("b", b)
if (a == b) {
//console.log("value", value.transform)
//if (a.getTime() === b.getTime()) {
trans = value.transform;
}
});
return trans;
}
var distanceBetween = 70;
var paths = links.selectAll("path")
.data(data);
paths.enter()
.append("path")
.attr("class", "link")
.attr("d", function(d, i) {
var sx = 0;
var tx = 0;
//console.log("d", d);
var posEnd = getPos(d["date-start"]);
var posStart = getPos(d["date-end"]);
var sy = posStart[1];
var ty = posEnd[1];
var dx = 0,
dy = getRadius(d) + 15 + (distanceBetween * i),
dr = 10 //Math.sqrt(dx * dx + dy * dy);
return "M" + sx + "," + sy + "A" + dr + "," + dr + " 0 0,1 " + tx + "," + ty;
})
.attr('stroke-width', 1.2)
.attr("stroke", function(d, i) {
//console.log("d", i);
return colores_google(i);
})
答案 0 :(得分:3)
- 稳定的固定版本 http://jsfiddle.net/4v3Ldk93/2/
我设法修复了它:http://jsfiddle.net/4v3Ldk93/
错误是因为:
console.log("pos", posEnd, posStart)
返回:
pos undefined [0, 256.6666564941406]
posEnd未定义。因此,您无法获得posEnd[1];
undefined
。这正是控制台错误:无法获取未定义的属性1。
这是因为,在getPos中,axisArray的最小值是:{ data: "2012-04-22" }
这不是您的日期转换问题,而是因为:.selectAll(".tick").each(function(data) {
仅接收4月22日作为第一个日期。
如果你没问题,可以通过在两端添加一天填充来修复它。在最小和最大定义之后添加这两行:
min.setDate(min.getDate() - 1);
max.setDate(max.getDate() + 1);
如果您不喜欢结束时的额外一天,您实际上只需要在最短的日期修复此问题。你可以这样做:
min.setDate(min.getDate() - 1);
我的猜测是域被设置为(min,max);意味着它包括上边界,但不包括下边界。但是这并非100%确定,除了更改有效的事实。
然后,你在几个月前修正0,但在你的日子里没有做同样的事情:
var day = data.getDate();
if (day < 10) day = "0" + day;
通过这两项修改,它对我有用。
虽然我不确定为什么这会影响您的“工作版本”,而不是“破损版本”,但这些更改也会使工作版本正常运行:http://jsfiddle.net/Ljrg9v2v/
同时将.ticks(d3.time.days(min,max).length)添加到yAxis以确保时间轴有1天的增量。
我希望这会有所帮助。