React-native-svg-charts: Chart with both XAxis & YAxis

Created on 11 Dec 2017  ·  16Comments  ·  Source: JesperLekland/react-native-svg-charts

Missing doc example of how to use both XAxis and YAxis with the same chart.

enhancement help wanted

Most helpful comment

And just a reminder, "expectations" on open-source projects, specifically with few contributors, should always be managed accordingly. I do this on my spare time, for free

All 16 comments

Not sure this actually is featured without hacky height solutions.

@johanolandero Hi! I didn't include it because I figured people could derive it from the single axis use cases. It works without any hacks, just think of how you would align regular <View>s the same way you would want your axes. I'll try to update the README as soon as I can

Your comment about "hacky height solutions" made my think I should clarify. In order for the YAxis to be able to layout properly you must indeed make sure that it is has the same layout constraints as the chart (there's no other way of measuring things otherwise). The easiest solution is to specify a fixed height for the xAxis and make sure that you have the same bottom (or top) margin of the YAxis

The problem occurs when you want to allow the chart for dynamic sizes with flex: 1 since the layout would result in something like this.
screen shot 2017-12-12 at 16 51 05
This is solved by the same approach you mention except with a fixed width for YAxis and an added marginLeft for the XAxis.

You are correct. seeing how a fixed height (or width, depending on which axis you want to specify) doesn't result in you not being able to use flex 1 on any of the other components I don't see the problem. Do you have a use case where having one axis dimension fix would cause a problem? I think this is a fair tradeoff in order to have the Y/X-Axis as stand alone components, thus allowing way more flexibility, customisability and cleaner API

You're right, the flexibility of having stand alone components for X/Y-Axis is great. However the API would perhaps be more straight forward without having to specify fixed numbers in order to just add 2 common properties of a chart.

A solution to this could perhaps look something like this where the components gets wrapped inside a chart component and the X/Y-Axis gets their layout calculations from the parent.

screen shot 2017-12-12 at 17 58 45

The API would look something like this.

<Chart>
  <DataPlot />
  <XAxis />
  <YAxis />
</Chart>

However, it works by the previously mentioned solution but I must admit it feels awkward to use fixed measurements in an otherwise responsive environment.

Interesting suggestion and great illustrations! Wish all issues were this thorough 🥇
I think your proposal looks good, I'll try to implement something like it when I get the time. If you have the time I would love a PR!

I do think that the fixed height/width is the best solution still as the alignment problem stems from flexbox, not this specific library. I've used the fixed height/width solution in several projects and never found any problems with it, the primary direction still flexes according to it's parent. And seeing how you render text in the axes you never want them too small anyway.

I would expect a "chart" library to have a built-in support of x and y axis. It's a big pain to have the positioning done on user land, it really shouldn't if you want this library to be a high level chart library.. At the moment, I feel this library is more helpers on top of SVG.

anyway, yeah, I know this is definitely tricky subject, the x<>y axis problem that was discussed is also a common problem. The flexible width/height is solvable tho, but tricky. It's still a legit usecase but yeah, as mentioned, fixing one axis is a tradeoff.

There are millions of ways for people to position their axes, doing it inside the library would introduce unnecessary complexity and would probably bloat the API with a bunch of axisPosition, axisStyle etc ( or the likes ) props. This library isn't meant to be too high level, as it would limit the user and/or introduce unnecessary complexity.

I will however keep considering some kind of "wrapper” component around a chart and two axes that would layout it in a default manner (y-axis to the left and x-axis below), both for ease of use but mostly for inspiration for users to create their own implementations.

I still think that one fixed width/height is a perfectly valid fix for what is basically a flexbox limitation. Try to layout regular Views in the manner you want the chart and axes layed out and you'll see the inherent problem

And just a reminder, "expectations" on open-source projects, specifically with few contributors, should always be managed accordingly. I do this on my spare time, for free

Ok understand this :) no worries I maintain lot of libs so I know ;)

(I'm currently looking at solution like https://github.com/FormidableLabs/victory-native for my need)

Nice! Then you know that people sometimes take your work for granted 😋 You have a lot of OSS, great job dude!

Victory charts is a really nice lib, but I've always considered it a bit too high level and bloated, hence this library :) Victory is a way more mature lib though

I've implemented a solution but as I feared it becomes fragile when the user is allowed to individually style the components, e.g set margin on the yAxis, padding on the Chart etc. Maybe that's expected behaviour but it doesn't feel that nice. Do you guys have any input? Would you expect the xAxis to automatically align when you set marginLeft on the chart? Here is the work in progress

const data = [ 7, 30, 10, 17, 14, 17,22 ] const dataWeek = [ 'F', 'S', 'S', 'M', 'T', 'W','T' ]

` ,width:Metrics.screenWidth}}>
data={data}
style={{ marginBottom: xAxisHeight }}
// contentInset={verticalContentInset}
svg={axesSvg}
/>

                  <BarChart
                    style={{flex:1}}
                    data={ data }
                    svg={{ fill }}
                    spacingInner={0.5} 
                    // contentInset={verticalContentInset}
                    spacing={0.2}
                    gridMin={0} 
                    >
                    <Grid/>
                  </BarChart>
                  <View style={styles.separeLine}/>  
                  <XAxis
                      style={{ height: xAxisHeight,paddingTop:10 }}
                      data={data}
                      formatLabel={(value, index) => dataWeek[ index ]}
                      contentInset={{ left: 10, right: 10 }}
                      svg={axesSvg}
                  />
              </View>
          </View>
         </View>`

Closing this due to inactivity

const data = [ 7, 30, 10, 17, 14, 17,22 ] const dataWeek = [ 'F', 'S', 'S', 'M', 'T', 'W','T' ]

` ,width:Metrics.screenWidth}}>
data={data}
style={{ marginBottom: xAxisHeight }}
// contentInset={verticalContentInset}
svg={axesSvg}
/>

                  <BarChart
                    style={{flex:1}}
                    data={ data }
                    svg={{ fill }}
                    spacingInner={0.5} 
                    // contentInset={verticalContentInset}
                    spacing={0.2}
                    gridMin={0} 
                    >
                    <Grid/>
                  </BarChart>
                  <View style={styles.separeLine}/>  
                  <XAxis
                      style={{ height: xAxisHeight,paddingTop:10 }}
                      data={data}
                      formatLabel={(value, index) => dataWeek[ index ]}
                      contentInset={{ left: 10, right: 10 }}
                      svg={axesSvg}
                  />
              </View>
          </View>
         </View>`

That's a working tweak. Thanks.

Was this page helpful?
0 / 5 - 0 ratings