diff --git a/README.md b/README.md
index 3e52d44a..60ce098f 100644
--- a/README.md
+++ b/README.md
@@ -122,6 +122,7 @@ const data = {
| withShadow | boolean | Show shadow for line - default: True |
| withInnerLines | boolean | Show inner dashed lines - default: True |
| withOuterLines | boolean | Show outer dashed lines - default: True |
+| fromZero | boolean | Render charts from 0 not from the minimum value. - default: False |
| yAxisLabel | string | Prepend text to horizontal labels -- default: '' |
| chartConfig | Object | Configuration object for the chart, see example config object above |
|decorator | Function | This function takes a [whole bunch](https://github.com/indiespirit/react-native-chart-kit/blob/master/src/line-chart.js#L266) of stuff and can render extra elements, such as data point info or additional markup. |
@@ -197,6 +198,7 @@ const data = {
| data | Object | Data for the chart - see example above |
| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
| height | Number | Height of the chart |
+| fromZero | boolean | Render charts from 0 not from the minimum value. - default: False |
| yAxisLabel | string | Prepend text to horizontal labels -- default: '' |
| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
@@ -210,7 +212,7 @@ const data ={
legend: ['L1', 'L2', 'L3'],
data: [
[60, 60, 60],
- [30,30,60],
+ [30,30,60],
],
barColors: ['#dfe4ea', '#ced6e0', '#a4b0be'],
}
diff --git a/src/abstract-chart.js b/src/abstract-chart.js
index d7965e31..1408b984 100644
--- a/src/abstract-chart.js
+++ b/src/abstract-chart.js
@@ -3,7 +3,41 @@ import React, {Component} from 'react'
import {LinearGradient, Line, Text, Defs, Stop} from 'react-native-svg'
class AbstractChart extends Component {
- calcScaler = data => Math.max(...data) - Math.min(...data) || 1
+ calcScaler = data => {
+ if (this.props.fromZero) {
+ return Math.max(...data, 0) - Math.min(...data, 0) || 1
+ } else {
+ return Math.max(...data) - Math.min(...data) || 1
+ }
+ }
+
+ calcBaseHeight = (data, height) => {
+ const min = Math.min(...data)
+ const max = Math.max(...data)
+ if (min >= 0 && max >= 0) {
+ return height
+ } else if (min < 0 && max <= 0) {
+ return 0
+ } else if (min < 0 && max > 0) {
+ return height * max / this.calcScaler(data)
+ }
+ }
+
+ calcHeight = (val, data, height) => {
+ const max = Math.max(...data)
+ const min = Math.min(...data)
+ if (min < 0 && max > 0) {
+ return height * (val / this.calcScaler(data))
+ } else if (min >= 0 && max >= 0) {
+ return this.props.fromZero ?
+ height * (val / this.calcScaler(data)) :
+ height * ((val - min) / this.calcScaler(data))
+ } else if (min < 0 && max <= 0) {
+ return this.props.fromZero ?
+ height * (val / this.calcScaler(data)) :
+ height * ((val - max) / this.calcScaler(data))
+ }
+ }
renderHorizontalLines = config => {
const {count, width, height, paddingTop, paddingRight} = config
@@ -57,7 +91,8 @@ class AbstractChart extends Component {
if (count === 1) {
yLabel = `${yAxisLabel}${data[0].toFixed(decimalPlaces)}`
} else {
- const label =
+ const label = this.props.fromZero ?
+ (this.calcScaler(data) / (count - 1)) * i + Math.min(...data, 0) :
(this.calcScaler(data) / (count - 1)) * i + Math.min(...data)
yLabel = `${yAxisLabel}${label.toFixed(decimalPlaces)}`
}
diff --git a/src/bar-chart.js b/src/bar-chart.js
index 92a597f9..0efd4058 100644
--- a/src/bar-chart.js
+++ b/src/bar-chart.js
@@ -8,9 +8,9 @@ const barWidth = 32
class BarChart extends AbstractChart {
renderBars = config => {
const {data, width, height, paddingTop, paddingRight} = config
- const baseHeight = (height / 4 * 3) * (Math.max(...data) / this.calcScaler(data)) + paddingTop
+ const baseHeight = this.calcBaseHeight(data, height)
return data.map((x, i) => {
- const barHeight = height / 4 * 3 * (x / this.calcScaler(data))
+ const barHeight = this.calcHeight(x, data, height)
const barWidth = 32
return (
)
@@ -31,9 +31,9 @@ class BarChart extends AbstractChart {
renderBarTops = config => {
const {data, width, height, paddingTop, paddingRight} = config
- const baseHeight = (height / 4 * 3) * (Math.max(...data) / this.calcScaler(data)) + paddingTop
+ const baseHeight = this.calcBaseHeight(data, height)
return data.map((x, i) => {
- const barHeight = height / 4 * 3 * (x / this.calcScaler(data))
+ const barHeight = this.calcHeight(x, data, height)
return (
{
output.push(
- paddingRight +
- (i * (width - paddingRight)) / dataset.data.length +
- ',' +
- ((height / 4) *
- 3 *
- (1 - (x - Math.min(...datas)) / this.calcScaler(datas)) +
- paddingTop)
+ (d, i) => {
+ const x = paddingRight + (i * (width - paddingRight)) / dataset.data.length
+ const y = (baseHeight - this.calcHeight(d, datas, height)) / 4 * 3 + paddingTop
+ return `${x},${y}`
+ }
)
.join(' ') +
` ${paddingRight +
@@ -116,16 +114,14 @@ class LineChart extends AbstractChart {
const {width, height, paddingRight, paddingTop, data} = config
const output = []
const datas = this.getDatas(data)
+ const baseHeight = this.calcBaseHeight(datas, height)
data.forEach((dataset, index) => {
const points = dataset.data.map(
- (x, i) =>
- paddingRight +
- (i * (width - paddingRight)) / dataset.data.length +
- ',' +
- ((height / 4) *
- 3 *
- (1 - (x - Math.min(...datas)) / this.calcScaler(datas)) +
- paddingTop)
+ (d, i) => {
+ const x = (i * (width - paddingRight)) / dataset.data.length + paddingRight
+ const y = (baseHeight - this.calcHeight(d, datas, height)) / 4 * 3 + paddingTop
+ return `${x},${y}`
+ }
)
output.push(
@@ -153,14 +149,11 @@ class LineChart extends AbstractChart {
Math.floor(
paddingRight + (i * (width - paddingRight)) / dataset.data.length
)
- const y = i =>
- Math.floor(
- (height / 4) *
- 3 *
- (1 -
- (dataset.data[i] - Math.min(...datas)) / this.calcScaler(datas)) +
- paddingTop
- )
+ const baseHeight = this.calcBaseHeight(datas, height)
+ const y = i => {
+ const yHeight = this.calcHeight(dataset.data[i], datas, height)
+ return Math.floor((baseHeight - yHeight) / 4 * 3 + paddingTop)
+ }
return [`M${x(0)},${y(0)}`]
.concat(