【问题标题】:d3 time scale - last bar on graph is appearing outside of the graphd3 时间刻度 - 图表上的最后一个条出现在图表之外
【发布时间】:2016-09-19 14:16:37
【问题描述】:

我正在 D3 版本 4 中构建一个条形图,使用时间刻度作为我的 x 轴。轴本身渲染得很好,但条形图已关闭;图表中的最后一个条形出现在轴范围之外。如何指定正确的范围和/或 x 值?

Working example

代码片段:

const xScale = (width, dates) =>
  scaleTime()
    .domain([new Date(dates[0]), new Date(last(dates))])
    .range([0, width])

svg.select('g')
  .selectAll(`.${styles['bar']}`)
  .data(series)
  .enter()
  .append('rect')
  .attr('class', styles['bar'])
  .attr('x', (d) => x(d.date))
  .attr('width', Math.floor(width / series.length))
  .attr('y', (d) => {
    const scaled = y(d.count)
      return height - scaled > 0 && height - scaled < 2
      ? height - 2
      : scaled
  })
  .attr('height', (d) => {
    const scaled = height - y(d.count)
    return scaled > 0 && scaled < 2
      ? 2
      : scaled
  })

【问题讨论】:

  • 看起来最后一个条的左边缘出现在范围内。我想您可以通过使您的范围略宽于width 来解决此问题。 (说宽度 + 一个条的预期宽度。)
  • 不幸的是,这也没有正确对齐。我添加了一个 JSFiddle 来说明这个问题。

标签: javascript d3.js


【解决方案1】:

问题不在于条的宽度、填充或范围……问题在于scaleTime 的概念。例如,您的第一个值是(我指的是工作示例):

Wed Sep 21 2016

从 2017 年之前开始,但由于条形的宽度,在 2017 年之后。您的最后一个值是(再次,工作示例):

Sat Sep 21 2030

位于域末尾 (2030) 之前,但由于条形的宽度,超出了该比例的范围。

你可以很容易地看到这是这个小提琴,我将域设置为 2032:https://jsfiddle.net/gerardofurtado/dnxc9cd9/

一个简单的解决方案:如果您想要一个以 x 刻度显示年份的条形图,请解析您的日期以获取年份并改用带刻度。

【讨论】:

  • 我使用时间刻度的原因之一是它会自动确定何时 呈现刻度。例如,如果一个图表有 50 个条目,它可能只渲染 10 个刻度以保持轴上的内容清晰。
  • scaleBand 实际上最终确实是我所需要的。我将它与github.com/d3/d3-axis/blob/master/README.md#axis_tickValues 结合起来,得到我所需要的。
【解决方案2】:

看起来最后一个条的左边缘出现在范围内。我想你可以通过让你的范围比宽度略宽来解决这个问题。 (说宽度 + 一个条的预期宽度。)

const barWidth = width / series.length;


const xScale = (width, dates) =>
  scaleTime()
    .domain([new Date(dates[0]), new Date(last(dates))])
    .range([0, width - barWidth])

svg.select('g')
  .selectAll(`.${styles['bar']}`)
  .data(series)
  .enter()
  .append('rect')
  .attr('class', styles['bar'])
  .attr('x', (d) => x(d.date))
  .attr('width', Math.floor(barWidth))
  .attr('y', (d) => {
    const scaled = y(d.count)
      return height - scaled > 0 && height - scaled < 2
      ? height - 2
      : scaled
  })
  .attr('height', (d) => {
    const scaled = height - y(d.count)
    return scaled > 0 && scaled < 2
      ? 2
      : scaled
  })

【讨论】:

  • 您的解决方案进一步限制了图表(现在最后 2 个条形图超出范围)。如果我这样做 range([0, width - barWidth]) 一切都合适,但条形图没有填充。
  • 如果您添加一个工作示例,我很乐意为您提供进一步的帮助。或者看看 Gerardo 对这个问题的评论。
  • 当然可以。在上面添加。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 2015-07-22
相关资源
最近更新 更多