React-native-svg-charts: Y-Axis has wrong range in StackedBarChart

Created on 13 Jun 2018  路  6Comments  路  Source: JesperLekland/react-native-svg-charts

What is the problem?

I can't display an X-Axis with correct values for a horizontal StackedBarChart.

What platform?

  • iOS
    React Native version: 0.55

Code to reproduce

     let colors = [ '#7b4173', '#a55194'];

      let data = [
        {
          label: 'One',
          apples: 5,
          oranges: 6
        },
        {
          label: 'Two',
          apples: 10,
          oranges: 20
        }
      ];
      let keys = ['apples', 'oranges'];

      return (
        <View style={{ height: 220 }}>
          <View style={{ height: 200, flexDirection: 'row' }}>
            <YAxis
                data={ data }
                contentInset={ { top: 30, bottom: 30 } }
                yAccessor={({ index }) => index}
                formatLabel={ (value, index) => {return data[index].label} }
                svg={{ fontSize: 10, fill: 'grey' }}
                numberOfTicks={ 1 }
                scale={scale.scaleBand}
            />
            <StackedBarChart
                style={{ flex: 1, marginLeft: 16}}
                keys={ keys }
                colors={ colors }
                data={ data }
                horizontal={ true }
                contentInset={ { top: 15, bottom: 15 } }
            />
          </View>
          <XAxis
              data={ StackedBarChart.extractDataPoints(data, keys) }
              contentInset={ { left: 20, right: 15 } }
              // formatLabel={ (value, index) => this._chartData[index].label }
              svg={{ fontSize: 6, fill: 'grey' }}
              scale={scale.scaleBand}
          />
        </View>)

I would expect the X-Axis to go from 0 to 30, but instead it is from 0 to 7:
screenshot 2018-06-13 12 51 25

bug

Most helpful comment

You are correct that the static function extractDataPoints doesn't support complex data. I'll fix this in the next release

All 6 comments

Well your XAxis shouldn't use the scaleBand scale. Think of your chart as a regular BarChart lying down. This means that your XAxis is now your YAxis, i.e it represents the extent of the combined data. You should use scale={scale.scaleLinear}, which is also the default.

@JesperLekland Thanks, but I did try that as well. Without scale.scaleLiner I'm still getting a 0-7 range for the axis, even though both my datapoints are "1, 2"

Full code:

      let colors = [ '#7b4173', '#a55194'];

      let data = [
        {
          label: 'One',
          apples: 1,
          oranges: 2
        },
        {
          label: 'Two',
          apples: 1,
          oranges: 2
        }
      ];
      let keys = ['apples', 'oranges'];

      return (
        <View style={{ height: 220 }}>
          <View style={{ height: 200, flexDirection: 'row' }}>
            <YAxis
                data={ data }
                contentInset={ { top: 15, bottom: 15 } }
                yAccessor={({ index }) => index}
                formatLabel={ (value, index) => {return data[index].label} }
                svg={{ fontSize: 10, fill: 'grey' }}
                numberOfTicks={ 1 }
                scale={scale.scaleBand}
            />
            <StackedBarChart
                style={{ flex: 1, marginLeft: 16}}
                keys={ keys }
                colors={ colors }
                data={ data }
                horizontal={ true }
                contentInset={ { top: 15, bottom: 15 } }
            />
          </View>
          <XAxis
              data={ StackedBarChart.extractDataPoints(data, keys) }
              contentInset={ { left: 40, right: 20 } }
              svg={{ fontSize: 6, fill: 'grey' }}
          />
        </View>)

Ah I found the problem! Your XAxis needs xAccessor={({item}) => item} as it defaults to the index, not the value. What you'll also need is the numerOfTicks prop to calculate an evenly distributed array of numbers

@JesperLekland Thanks! That fixed the example I gave. It doesn't appear to work with a more complex data structure for the value though, which is what I was originally trying to do before I came up with a simplified example.

Full code below, with the changes commented since I couldn't find a way to bold the lines on github. Thank you for your help so far.

      let colors = [ '#7b4173', '#a55194'];

      let data = [
        {
          label: 'One',
/// Changed
          apples: {
            value: 1
          },
          oranges: {
            value: 2
          }
/// End changed
        },
        {
          label: 'Two',
/// Changed
          apples: {
            value: 4
          },
          oranges: {
            value: 5
          }
/// End changed
        }
      ];
      let keys = ['apples', 'oranges'];

      return (
        <View style={{ height: 220 }}>
          <View style={{ height: 200, flexDirection: 'row' }}>
            <YAxis
                data={ data }
                contentInset={ { top: 15, bottom: 15 } }
                yAccessor={({ index }) => index}
                formatLabel={ (value, index) => {return data[index].label} }
                svg={{ fontSize: 10, fill: 'grey' }}
                numberOfTicks={ 1 }
                scale={scale.scaleBand}
            />
            <StackedBarChart
                style={{ flex: 1, marginLeft: 16}}
                keys={ keys }
                colors={ colors }
                data={ data }
                horizontal={ true }
                contentInset={ { top: 15, bottom: 15 } }
/// Changed
                valueAccessor={ ({ item, key }) => item[ key ].value }
/// End changed
            />
          </View>
          <XAxis
              data={ StackedBarChart.extractDataPoints(data, keys) }
              contentInset={ { left: 40, right: 20 } }
/// Changed
              xAccessor={(obj) => {console.log(obj);}}
              valueAccessor={ (obj) => console.log('this is never called') }
/// End changed
              numberOfTicks={4}
              svg={{ fontSize: 6, fill: 'grey' }}
          />
        </View>)

Output:

```javascript
Object {
"index": 0,
"item": 0,
}
Object {
"index": 1,
"item": NaN,
}
Object {
"index": 2,
"item": 0,
}
Object {
"index": 3,
"item": NaN,
}
Object {
"index": 4,
"item": 0,
}
Object {
"index": 5,
"item": NaN,
}
Object {
"index": 6,
"item": 0,
}
Object {
"index": 7,
"item": NaN,
}

Snack example here: https://snack.expo.io/@vjsingh/yaxis-issue

You are correct that the static function extractDataPoints doesn't support complex data. I'll fix this in the next release

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lotcz picture lotcz  路  3Comments

otusweb picture otusweb  路  6Comments

BBenGit picture BBenGit  路  6Comments

antoinerousseau picture antoinerousseau  路  4Comments

rohithnair1996 picture rohithnair1996  路  3Comments