Javascript比较日期 - d3.js图表​​中的错误

时间:2017-04-19 21:45:51

标签: javascript jquery d3.js

我试图稳定这个图表 - 我试图比较日期对象 - 但后来遇到了夏季时差的问题 - 我不确定为什么数据的变化打破了图表 - 我得到了一个未定义的问题。

//工作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);
  })

1 个答案:

答案 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天的增量。

我希望这会有所帮助。