对于柱形图,解析具有D3误差的x轴

时间:2013-07-31 14:45:41

标签: parsing d3.js

我是D3的新手,在解析正轴和负值条形图的x轴时遇到问题,如下所示:http://bl.ocks.org/mbostock/2368837

不是显示实际年份,而是重复'1970',即时间码开始计算的时间。我认为这可能是一个错误,其中年份没有转换为字符串,但它似乎不是一个简单的d3timescale,因为条形图需要序数轴。

    var data = [
    {"date":19990101,"change":123000},
    {"date":19990102,"change":409000},
    {"date":19990103,"change":108000},
    {"date":19990104,"change":373000},
    {"date":19990105,"change":213000},
    {"date":19990106,"change":263000},
    {"date":19990107,"change":293000},
    {"date":19990108,"change":191000},
    {"date":19990109,"change":203000},
    {"date":19990110,"change":403000},
    {"date":19990111,"change":291000},
    {"date":19990112,"change":300000},
    {"date":20000101,"change":233000},
    {"date":20000102,"change":130000},
    {"date":20000103,"change":471000},
    {"date":20000104,"change":287000},
    {"date":20000105,"change":225000},
    {"date":20000106,"change":-46000},
    {"date":20000107,"change":166000},
    {"date":20000108,"change":2000},
    {"date":20000109,"change":127000},
    {"date":20000110,"change":-12000},
    {"date":20000111,"change":223000},
    {"date":20000112,"change":138000},
    {"date":20010101,"change":-32000},
    {"date":20010102,"change":69000},
    {"date":20010103,"change":-29000},
    {"date":20010104,"change":-281000},
    {"date":20010105,"change":-41000},
    {"date":20010106,"change":-126000},
    {"date":20010107,"change":-122000},
    {"date":20010108,"change":-156000},
    {"date":20010109,"change":-244000},
    {"date":20010110,"change":-327000},
    {"date":20010111,"change":-296000},
    {"date":20010112,"change":-172000},
    {"date":20020101,"change":-143000},
    {"date":20020102,"change":-135000},
    {"date":20020103,"change":-22000},
    {"date":20020104,"change":-83000},
    {"date":20020105,"change":-6000},
    {"date":20020106,"change":52000},
    {"date":20020107,"change":-92000},
    {"date":20020108,"change":-14000},
    {"date":20020109,"change":-58000},
    {"date":20020110,"change":124000},
    {"date":20020111,"change":7000},
    {"date":20020112,"change":-162000},
    {"date":20030101,"change":89000},
    {"date":20030102,"change":-158000},
    {"date":20030103,"change":-215000},
    {"date":20030104,"change":-51000},
    {"date":20030105,"change":-10000},
    {"date":20030106,"change":-3000},
    {"date":20030107,"change":20000},
    {"date":20030108,"change":-44000},
    {"date":20030109,"change":105000},
    {"date":20030110,"change":197000},
    {"date":20030111,"change":13000},
    {"date":20030112,"change":119000},
    {"date":20040101,"change":159000},
    {"date":20040102,"change":43000},
    {"date":20040103,"change":333000},
    {"date":20040104,"change":247000},
    {"date":20040105,"change":306000},
    {"date":20040106,"change":78000},
    {"date":20040107,"change":37000},
    {"date":20040108,"change":125000},
    {"date":20040109,"change":155000},
    {"date":20040110,"change":343000},
    {"date":20040111,"change":65000},
    {"date":20040112,"change":128000},
    {"date":20050101,"change":130000},
    {"date":20050102,"change":240000},
    {"date":20050103,"change":135000},
    {"date":20050104,"change":362000},
    {"date":20050105,"change":168000},
    {"date":20050106,"change":246000},
    {"date":20050107,"change":372000},
    {"date":20050108,"change":192000},
    {"date":20050109,"change":65000},
    {"date":20050110,"change":81000},
    {"date":20050111,"change":335000},
    {"date":20050112,"change":158000},
    {"date":20060101,"change":274000},
    {"date":20060102,"change":316000},
    {"date":20060103,"change":280000},
    {"date":20060104,"change":181000},
    {"date":20060105,"change":21000},
    {"date":20060106,"change":80000},
    {"date":20060107,"change":210000},
    {"date":20060108,"change":179000},
    {"date":20060109,"change":159000},
    {"date":20060110,"change":-3000},
    {"date":20060111,"change":205000},
    {"date":20060112,"change":169000},
    {"date":20070101,"change":234000},
    {"date":20070102,"change":90000},
    {"date":20070103,"change":186000},
    {"date":20070104,"change":76000},
    {"date":20070105,"change":141000},
    {"date":20070106,"change":80000},
    {"date":20070107,"change":-35000},
    {"date":20070108,"change":-24000},
    {"date":20070109,"change":77000},
    {"date":20070110,"change":86000},
    {"date":20070111,"change":111000},
    {"date":20070112,"change":93000},
    {"date":20080101,"change":14000},
    {"date":20080102,"change":-85000},
    {"date":20080103,"change":-79000},
    {"date":20080104,"change":-215000},
    {"date":20080105,"change":-186000},
    {"date":20080106,"change":-169000},
    {"date":20080107,"change":-216000},
    {"date":20080108,"change":-270000},
    {"date":20080109,"change":-459000},
    {"date":20080110,"change":-472000},
    {"date":20080111,"change":-775000},
    {"date":20080112,"change":-705000},
    {"date":20090101,"change":-794000},
    {"date":20090102,"change":-695000},
    {"date":20090103,"change":-830000},
    {"date":20090104,"change":-704000},
    {"date":20090105,"change":-352000},
    {"date":20090106,"change":-472000},
    {"date":20090107,"change":-351000},
    {"date":20090108,"change":-210000},
    {"date":20090109,"change":-233000},
    {"date":20090110,"change":-170000},
    {"date":20090111,"change":-21000},
    {"date":20090112,"change":-220000},
    {"date":20100101,"change":-13000},
    {"date":20100102,"change":-40000},
    {"date":20100103,"change":154000},
    {"date":20100104,"change":229000},
    {"date":20100105,"change":521000},
    {"date":20100106,"change":-130000},
    {"date":20100107,"change":-86000},
    {"date":20100108,"change":-37000},
    {"date":20100109,"change":-43000},
    {"date":20100110,"change":228000},
    {"date":20100111,"change":144000},
    {"date":20100112,"change":95000},
    {"date":20110101,"change":69000},
    {"date":20110102,"change":196000},
    {"date":20110103,"change":205000},
    {"date":20110104,"change":304000},
    {"date":20110105,"change":115000},
    {"date":20110106,"change":209000},
    {"date":20110107,"change":78000},
    {"date":20110108,"change":132000},
    {"date":20110109,"change":225000},
    {"date":20110110,"change":166000},
    {"date":20110111,"change":174000},
    {"date":20110112,"change":230000},
    {"date":20120101,"change":311000},
    {"date":20120102,"change":271000},
    {"date":20120103,"change":205000},
    {"date":20120104,"change":112000},
    {"date":20120105,"change":125000},
    {"date":20120106,"change":87000},
    {"date":20120107,"change":153000},
    {"date":20120108,"change":165000},
    {"date":20120109,"change":138000},
    {"date":20120110,"change":160000},
    {"date":20120111,"change":247000},
    {"date":20120112,"change":219000},
    {"date":20130101,"change":148000},
    {"date":20130102,"change":332000},
    {"date":20130103,"change":142000},
    {"date":20130104,"change":199000},
    {"date":20130105,"change":195000},
    {"date":20130106,"change":195000}
    ];

    var margin = {top: 34, right: 0, bottom: 30, left: 60},
        width = 900;
        height = 420 - margin.top - margin.bottom;

    var parseDate = d3.time.format("%Y%d%m").parse;
        formatValue = d3.format(",");
        formatTime = d3.time.format("%Y");


    var x = d3.scale.ordinal()
        .rangeRoundBands([0, width], 0.2);

    var y = d3.scale.linear()
        .range([height, 0]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .tickPadding(10)
        .ticks(20)
        .orient("top")
        .tickFormat(function(d) { return d3.time.format('%Y')(new Date(d)); });
        // .tickFormat(d3.time.format("%Y"));

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

    var svg = d3.select("#chart").append("svg")
        .attr("width", width  + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        // });
    x.domain(data.map(function(d) {
      return +d.date;
    }));
    y.domain(d3.extent(data, function(d) {
      return d.change;
    })).nice();

    // add grid lines
    function make_X_axis() {
    return d3.svg.axis()
    .scale(xScale)
    .orient("bottom")
    .ticks(6);
    }


    svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", function(d) { return d.change < 0 ? "bar negative" : "bar positive"; })
      .attr("y", function(d) {
        if (d.change < 0) {
          return y(0);
        } else {
          return y(d.change);
        }
      })
      .attr("x", function(d) {
        return x(d.change);
      })
      .attr("height", function(d) {
        return Math.abs(y(d.change) - y(0));
      })
      .attr("width", x.rangeBand())
      .on("mouseover", function(d) {

              //Get this bar's x/y values, then augment for the tooltip
              var xPosition = parseFloat(d3.select(this).attr("x")) + x.rangeBand() / 2;
              var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + height / 2;

              //Update the tooltip position and value
              d3.select("#tooltip")
                .style("left", xPosition + "px")
                .style("top", yPosition + "px")
                .style("right", xPosition + "px")
                .select("#value")
                // .text(formatValue(d.change)) + formatTime(d.date);
                .text(formatValue(d.change));
              //Show the tooltip
                d3.select("#tooltip").classed("hidden", false);

             })
             .on("mouseout", function() {
              //Hide the tooltip
              d3.select("#tooltip").classed("hidden", true);
             });

    // Update the inner dimensions.
    var g = svg.select("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // Regular x-axis
    svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis.orient("bottom").tickValues([1999, 20000101, 20010101, 20020101, 20030101, 20040101, 20050101, 20060101, 20070101, 20080101, 20090101, 20100101, 20110101, 20120101, 20130101]))
    .style("text-anchor", "start");



    svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("x", -25)
    .attr("y", -25)
    .style("text-anchor", "end")
    .text("Jobs");

    svg.append("g")
    .attr("class", "grid")
    .call(make_Y_axis()
    .tickSize(-width, 0, 0)
    .tickFormat(""));


    // //Zero axis
    svg.append("g")
    .attr("transform", "translate(0," + Y0() + ")")
    .call(xAxis.tickFormat("").tickSize(1));


    // add grid lines
    function make_X_axis() {
      return d3.svg.axis()
      .scale(x)
      .orient("bottom")
      .ticks(6);
    }

    function make_Y_axis() {
      return d3.svg.axis()
      .scale(y)
      .orient("left")
      .ticks(10);
    }

    function Y0() {
            return y(0);
    }

1 个答案:

答案 0 :(得分:1)

您需要修复日期的表示。有几种常用的方法可以用JavaScript表示日期:

  • 作为一个数字(例如,1375284578036),表示自UNIX epoch以来的毫秒数。
  • 作为任意字符串(例如"2013-07-31");这通常使用d3.time.format解析。
  • 作为真正的Date对象(例如,new Date(2013, 6, 31))。

通常,您的策略应该是尽快将事物放入Date个对象中,因为这是JavaScript中的规范表示。您应该只使用数字或字符串来表示(“序列化”)数据文件中的日期,例如CSV或JSON。总而言之,始终将日期表示为代码中的Date个对象,并根据需要将字符串或数字转换为Date个对象。

在您的代码中,您似乎使用了YYYYMMDD形式的数字(除了x轴的第一个刻度值,即YYYY)。因为在您使用的年份中没有前导零(即,它们都是四位数),所以在技术上可以用这种方式表示日期,然后在用d3.time.format解析之前将其强制转换为字符串 - 但是这样是个坏主意。您应该使用字符串来序列化日期,而不是数字;自UNIX纪元以来仅使用一个数字毫秒。

请注意,您的x轴刻度格式是new Date(d)。这是使用其中一个域值(YYYYMMDD形式的数字),然后使用Date构造函数将其转换为Date对象。但是当Date构造函数传递一个数字时,它假定这是自纪元以来的毫秒数,这就是为什么所有日期都在20世纪70年代。

如果您在加载数据时首先将所有日期转换为Date个对象,那么x-scale的域将为Date个对象,您无需强制更改日期作为格式化标记的一部分。您只需使用d3.time.format("%Y")作为刻度线格式。