D3 X 轴从最早日期开始,当前从最近的整周日期开始

D3 X-axis to start on earliest date, currently starts on nearest whole week date

我正在用 D3 制作这个甘特图,month/day 作为 x 轴。目前,我的数据集中最早的日期是 9/11/2018,但 D3 将 9/16(星期日)显示为第一个标记的刻度线。我想显示的是第一个刻度是 9/11,然后从那里到数据集中的最后一个日期 (8/30/2020)


let x = d3
      .scaleTime()
      .domain([xMin, xMax])
      //.nice(weeksBetween(xMin, xMax))
      .range([20, weeksBetween(xMin, xMax) * 56.7])
    let color = 'rgba(0, 93, 170, 0.5)'
    const _this = this

    svg
      .append('g')
      .attr('transform', 'translate(0,45)')
      .attr('width', window.clientWidth)
      .selectAll('.bar')
      .data(data)
      .enter()
      .append('g')
      .attr('class', 'bar')
      .attr('data-project', d => {
        return d.title
      })
      .append('rect')
      .style('opacity', 1)
      .attr('width', d => {
        svgHeight += 49
        let endDate = new Date(d.dateEnd)
        let dateStart = new Date(d.dateStart)

        return x(endDate) - x(dateStart)
      })
      .attr('x', d => {
        let startDate = new Date(d.dateStart)

        return x(startDate)
      })
      .attr('y', (d, i) => {
        return i * 55
      })
      .attr('height', barHeight + 'rem')
      .style('opacity', d => {
        let opacity = 0.2
        activeProject.forEach(project => {
          if (project === d.name) {
            opacity = 1
          }
        })
        if (viewDownstream) {
          selectedDownstreams.forEach(downstream => {
            if (downstream.name === d.name) {
              opacity = 0.5
            }
          })
        }
        if (viewInput) {
          selectedInputs.forEach(input => {
            if (input.name === d.name) {
              opacity = 0.5
            }
          })
        }

        return opacity
      })
      .style('fill', d => {
        let color = 'rgba(0, 93, 170, 0.5)'
        if (viewDownstream) {
          selectedDownstreams.forEach(downstream => {
            if (downstream.name === d.name) {
              if (downstream.conflict) {
                color = Colors.functional.fRed
              } else {
                color = Colors.primary.prGreen4
              }
            }
          })
        }
        if (viewInput) {
          selectedInputs.forEach(input => {
            if (input.name === d.name) {
              if (input.conflict) {
                color = Colors.functional.fRed
              } else {
                color = 'silver'
              }
            }
          })
        }
        return color
      })
      .on('click', () => this.props.handleDisableTextBox())
    //x-axis line - weeks
    const ficalWeekAdjustment = week => {
      if (week + 1 > 104) return week - 103
      if (week + 1 > 52) return week - 51
      return week + 1
    }
    svg
      .append('g')
      .data(data)
      .attr('class', 'x-axis')
      .attr('transform', 'translate(0,' + (svgHeight + 300) + ')')
      .call(
        d3
          .axisBottom(x)
          .ticks(weeksBetween(xMin, xMax))
          // .tickFormat((d, i) => ficalWeekAdjustment(i))
          .tickFormat(d3.timeFormat("%m/%d"))
      )
      .style('opacity', 1)
      .style('opacity', 0.8)
      .selectAll('text')
      .style('text-anchor', 'middle')
      .style('opacity', 0.5)
      .style('font-size', '0.9rem')

欢迎来到 Stack Overflow。

D3 会自动调整您的比例尺以使其更实用,即在整数边界而不是小数点上显示数字,与周或月边界对齐。如果愿意,您可以通过为刻度指定一个值数组来覆盖它,如下所示:

var xAxis = d3.axisBottom(x)
    .tickValues([1, 2, 3, 5, 8, 13, 21]);

显然,您将需要为报价提供日期值。