d3 - 按周计算的时间

时间:2017-10-27 11:17:19

标签: javascript d3.js

我正在使用d3在网络中重新创建图表。我有一个折线图在y轴上使用适当的比例。我现在需要能够在x轴上设置与日期一起使用的比例。

我想要的是能够在excel中打印出类似于此示例的总日期和周的日期: Excel example

这是我目前得到的: d3 example

这是我目前的课程:

chart.js之

import React, { Component } from 'react';
import moment from 'moment';
import { scaleLinear, scaleTime } from 'd3-scale';
import { max, extent } from 'd3-array';
import { select } from 'd3-selection';
import { line } from 'd3-shape';
import { axisBottom, axisLeft } from 'd3-axis';

import '../App.css';

const margin = { top: 20, right: 20, bottom: 30, left: 50 };

class Chart extends Component {
  componentDidMount = () => {
    this.createChart();
  }

  componentDidUpdate = () => {
    this.createChart();
  }

  createChart = () => {
    switch (this.props.type) {
      case 'bar': this.createBarChart(); break;
      case 'line-date': this.createDateLineChart(); break;
      default: break;
    }
  }

  createBarChart = () => {
    const node = this.node;
    const dataMax = max(this.props.data);
    const yScale = scaleLinear()
      .domain([0, dataMax])
      .range([0, this.props.size[1]]);

    select(node)
      .selectAll('rect')
      .data(this.props.data)
      .enter()
      .append('rect');

    select(node)
      .selectAll('rect')
      .data(this.props.data)
      .exit()
      .remove();

    select(node)
      .selectAll('rect')
      .data(this.props.data)
      .style('fill', '#fe9922')
      .attr('x', (d, i) => i * 25)
      .attr('y', d => this.props.size[1] - yScale(d))
      .attr('height', d => yScale(d))
      .attr('width', 25);
  }

  createDateLineChart = () => {
    const node = this.node;
    var svg = select(node);

    var width = +svg.attr('width') - margin.left - margin.right;
    var height = +svg.attr('height') - margin.top - margin.bottom;

    var g = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');


    var x = scaleTime()
      .rangeRound([0, width]);

    var y = scaleLinear()
      .rangeRound([height, 0]);

    var d3Line = line()
      .x(function (d) { return x(d.date); })
      .y(function (d) { return y(d.number); });

    var data = [];
    for (var item of this.props.data) {
      data.push({
        date: moment(item.date, 'YYYY-MM-DD').toDate(),
        number: +item.number
      });
    }

    x.domain(this.props.xscale !== undefined ? this.props.xscale : extent(data, function (d) { return d.date; }));
    y.domain(this.props.yscale !== undefined ? this.props.yscale : extent(data, function (d) { return d.number; }));

    // X axis
    g.append('g')
      .call(axisLeft(y))
      // Set axis label
      .append('text')
      .attr('fill', '#000000')
      .attr('transform', 'rotate(-90)')
      .attr('transform-y', '-50%')
      .attr('y', -30) // Left
      .attr('x', (height / 2) * -1) // Down
      .attr('font-weight', 'bold')
      .attr('text-anchor', 'center')
      .text(this.props.labels.x);

    // Y axis
    g.append('g')
      .attr('transform', 'translate(0,' + height + ')')
      .call(axisBottom(x))
      // Removes axis line
      // .select('.domain')
      // .remove()
      // Set axis label
      .append('text')
      .attr('fill', '#000000')
      .attr('transform-x', '-50%')
      .attr('y', 30) // Down
      .attr('x', (width / 2)) // Left
      .attr('font-weight', 'bold')
      .attr('text-anchor', 'center')
      .text(this.props.labels.y);

    // Path / Line
    g.append('path')
      .datum(data)
      .attr('fill', 'none')
      .attr('stroke', 'steelblue')
      .attr('stroke-linejoin', 'round')
      .attr('stroke-linecap', 'round')
      .attr('stroke-width', 1.5)
      .attr('d', d3Line);
    // });
  }

  render() {
    return (
      <svg ref={node => this.node = node}
        width={1280}
        height={720} />
    );
  }
}

export default Chart;

我需要做什么才能让d3设置比例,以便我可以将日期设置为W1 - 08/09/17等。

1 个答案:

答案 0 :(得分:2)

您可以获得想要操纵轴生成器的结果。

首先,要显示每周一个刻度,请使用ticks

.ticks(d3.timeWeek.every(1))

然后,要显示一周前的周数,请使用tickFormat中的第二个参数:

.tickFormat(function(d, i) {
    return "W" + (i + 1) + " - " + d3.timeFormat("%d/%m/%y")(d)
});

由于我们每周只显示一个刻度,因此第二个参数(即每个刻度的索引)将是周数(加1,因为索引基于零)。

这是一个演示:

&#13;
&#13;
var svg = d3.select("svg");
var scale = d3.scaleTime()
  .range([40, 560])
  .domain([new Date(2017, 0), new Date(2017, 1)]);
var axis = d3.axisBottom(scale)
  .ticks(d3.timeWeek.every(1))
  .tickFormat(function(d, i) {
    return "W" + (i + 1) + " - " + d3.timeFormat("%d/%m/%y")(d)
  });
var gX = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis)
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="600" height="100"></svg>
&#13;
&#13;
&#13;