如何在d3条形图中显示负值?

时间:2018-12-08 11:12:05

标签: javascript reactjs d3.js

嘿:)尽管尝试使用Internet上的代码片段进行了很多尝试,但是我无法在我已集成到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不太熟悉,因为这是我正在使用它的第一个项目,因此,如果这很明显,请原谅。 帮助将不胜感激。

该组件呈现如下:

enter image description here

非常感谢您的时间:)

1 个答案:

答案 0 :(得分:0)

如果没有负数,则将域最小值设置为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))