【问题标题】:How to display negative values in a d3 bar chart?如何在 d3 条形图中显示负值?
【发布时间】:2018-12-08 11:12:05
【问题描述】:

嘿 :) 尽管在互联网上找到了许多使用 sn-ps 的尝试,但我无法在我已合并到 React 组件中的 d3 条形图中显示负值。当呈现负值时,不会显示任何内容。

组件:

// npm.
import React from 'react'
import {
  select,
  scaleBand,
  scaleLinear
} from 'd3'

// tmp.
import data from './data'

// styles.
import styles from './styles.scss'

class YearProfitLossBarChart extends React.Component {
  constructor(props) {
    super(props)

    this.draw = this.draw.bind(this)
  }

  componentDidMount() {
    this.draw()
  }

  componentDidUpdate() {
    this.draw()
  }

  render() {
    return (
      <svg style={{ width: '100%', height: '100%', marginBottom: '-4px' }} ref={(node) => {this.node = node}}></svg>
    )
  }

  draw() {
    let bounds = this.node.getBoundingClientRect()
    let width = bounds.width
    let height = bounds.height

    let node = select(this.node)

    let xScale = scaleBand()
    xScale.domain(data.map((d) => d.month))
    xScale.padding(1/8);
    xScale.paddingOuter(0)
    xScale.range([0, width])

    let yScale = scaleLinear()
    yScale.domain([0, Math.max(...data.map((d) => d.value))])
    yScale.range([0, height])

    let bars = node.selectAll('rect').data(data)
    bars.enter()
      .append('rect')
      .merge(bars)
      .attr('x', (d) => xScale(d.month))
      .attr('y', (d) => height - yScale(d.value))
      .attr('width', xScale.bandwidth())
      .attr('height', (d) => yScale(d.value))
 }
}

export default YearProfitLossBarChart

数据结构:

export default [
  { month: 'Jan', value: 100 },
  { month: 'Feb', value: 80 },
  { month: 'Mar', value: 100 },
  { month: 'Apr', value: 50 },
  { month: 'May', value: 100 },
  { month: 'Jun', value: 100 },
  { month: 'Jul', value: -100 },
  { month: 'Aug', value: 100 },
  { month: 'Sep', value: 100 },
  { month: 'Oct', value: 100 },
  { month: 'Nov', value: 100 },
  { month: 'Dec', value: 100 }
]

我对 d3 不太熟悉,因为这是我使用它的第一个项目,所以如果这很明显,请原谅。 非常感谢您的帮助。

组件呈现如下:

非常感谢您的宝贵时间:)

【问题讨论】:

  • 我认为问题可能在于您将 Y 域设置为:yScale.domain([0, Math.max(...data.map((d) =&gt; d.value))]),因此 0 是显示的最低值。也许做一个类似的Math.min(...) 而不是传递0
  • 嘿,不幸的是我们已经尝试过了,结果是一样的......谢谢:)
  • 啊,好吧。我确实找到了一些示例 herehere 以防万一它有帮助,否则希望其他人能够提供更多帮助。

标签: javascript reactjs d3.js


【解决方案1】:

如果没有负数,则将域最小值设置为 0,否则将其设置为最小数据值

yScale.domain([ Math.min(0, d3.min(data, d => d.value)), d3.max(data, d => d.value) ])

你需要改变条高的计算方式

yScale.range([height, 0]);
let bars = node.selectAll('rect').data(data)
    bars.enter()
      .append('rect')
      .merge(bars)
      .attr('x', (d) => xScale(d.month))
      .attr('y', (d) => yScale(d.value))
      .attr('width', xScale.bandwidth())
      .attr('height', (d) => height - yScale(d.value))

【讨论】:

    猜你喜欢
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多