折线图d3 js-- x轴月

时间:2013-12-27 16:10:42

标签: javascript css svg d3.js linechart

我正在尝试做一个简单的折线图,其中包含x轴上1月到12月的月份以及我公司网站上发布的y分配数量。我在映射y域时遇到了一些麻烦......基本上理解这个api应该如何工作。我找到了大量的解析日期或数值x轴的例子,但我似乎无法用几个月来解决它。

我用这段代码调整了这么长时间,我甚至不确定我在看什么。

对于一个年轻的菜鸟,非常感谢任何帮助。

这是要点:https://gist.github.com/wiredsister/8148974

我的造型如下:

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.axis text {
  font: 10px sans-serif;
}

.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}

2 个答案:

答案 0 :(得分:5)

日期/时间轴功能不起作用的原因是因为您的月份数据实际上并未存储为日期/时间值:它只是一个简单的整数。有两种方法可以解决这个问题。

第一个选项,如果您只想一次绘制一年(因此没有重复2013年1月与2014年1月相比)并且不需要进行任何基于时间的数学运算,您可以使用{{3将月份数字映射到月份名称,而不用担心时间尺度。

第二个选项,如果要将月份数据存储为日期,则需要将输入数据ordinal scale转换为日期对象。之后,其余代码应按预期工作。

目前,您的数据读取方法的第一个声明是数据转换例程,但它只是将所有内容存储为数字:

data.forEach(function(d) {
    d.month = +d.month;
    d.work = +d.work;
  });

+d.month告诉程序取出它读入的数字串(“0”或“7”或“11”)并用相应的数字替换它。相反,您希望它读取该数字串并将其解释为月份。

要做到这一点,你需要创建一个时间格式化对象,希望看到一个数字并将其作为一个月读取,然后在读入的值上使用该格式化对象的parse()方法。这是一个有点复杂,因为您的月份数字在0-11范围内给出,而日期的预期数字格式在1-12范围内。 (如果您可以更改数据格式而不会使代码的其他部分复杂化,那么这会使这更简单。)

var monthNumber = d3.time.format("%-m"); 
   //m is month number, '-' indicates no padding

data.forEach(function(d) {
    d.month = monthNumber("" + (+d.month + 1) );
      //convert the month to an integer and add one, 
      //then convert back to a string and parse
    d.work = +d.work;
  });

在此处查看此方法:parse

请注意,由于您的数据没有关于指定年份的任何信息,因此浏览器将插入“零”年,例如1900年。如果您想要对有效年份进行硬编码,那么您将拥有改变这样的格式:

var year = 2013;
var yearPlusMonthNumber = d3.time.format("%Y %-m"); 
    //Y is four digit year, m is month number, '-' indicates no padding

data.forEach(function(d) {
    d.month = yearPlusMonthNumber("" + year + " " + (+d.month + 1) );
      //convert the month to an integer, add one,  
      //then combine with year (and space) as a string and parse
    d.work = +d.work;
  });

答案 1 :(得分:2)

我想说明我最终是如何实现此图表的: 根据AmeliaBR的建议和Mike Bostock的Month Axis示例,我决定使用x和y作为线性比例的线图,以及一个名为xLabels的变量,作为xAxis的格式化时间刻度。像这样,

var xLabels = d3.time.scale().domain([new Date(2013, 0, 1), new Date(2013, 11, 31)]).range([0, w]);
    var x = d3.scale.linear().domain([0, data.length]).range([0, w]);
    var y = d3.scale.linear().domain([0, d3.max(data)]).range([h, 0]);

我绘制了我的线条,就像我的正常线性刻度一样,但对于xAxis:

var xAxis = d3.svg.axis().scale(xLabels).ticks(d3.time.months).tickFormat(d3.time.format("%B")).tickSize(-h).tickSubdivide(true);
    graph.append("svg:g")
          .attr("class", "x axis") 
          .attr("transform", "translate(0," + h + ")")
          .call(xAxis);

我传入我的xLabel作为比例,并将我的刻度格式化为几个月。

以下是jsfidde的工作示例: http://jsfiddle.net/vB5eW/