xanderdeseyn / react-native-responsive-linechart

A customizable and responsive line or area chart for react-native
https://react-native-responsive-linechart.surge.sh
MIT License
203 stars 47 forks source link

Dynamic x-values are not plotted properly #35

Closed techinsider99 closed 3 years ago

techinsider99 commented 3 years ago

I'm trying to display yearly data (12 months) in a sliding window manner i.e. it can be anything among the 12 months that shifts each month in a forward manner such as,

const xValues = [5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4] - from May (2019) to April (2020) const xValues = [6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5] - from June (2019) to May (2020)

I'm using the tickValues prop in the Line component to set xValues, and tickCount to 12 (since the number of months will always be the same irrespective of the sliding manner) so that the data will be displayed in the above said manner. But this seems not to be working. I've ignored the xDomain prop in Chart component since I've provided the data in Line component.

                  <HorizontalAxis
                      tickValues={xValues}
                      tickCount={12}
                      includeOriginTick={true}
                      theme={{
                        axis: {
                          stroke: {
                            color: '#030303',
                            width: 1,
                          },
                        },
                        ticks: {
                          dy: responsiveHeight(-0.9),
                          length: responsiveHeight(1),
                          stroke: {
                            width: 1,
                            color: '#030303',
                          },
                        },
                        labels: {
                          label: {
                            dy: responsiveHeight(-2.5),
                            fontSize: responsiveFontSize(1.35),
                            fontWeight: 500,
                          },
                          formatter: (xValue) =>
                            this.getMonth(xValue).slice(0, 3),
                        },
                        grid: {
                          visible: false,
                        },
                      }}
                    />

Note: getMonth() returns the name of the month based on the index passed ranging from 1 to 12

Thanks in advance!

xanderdeseyn commented 3 years ago

Hi @techinsider99, what exactly are you seeing? Can you provide a minimal example? (You can just alter the source file of the Demo app slightly)

techinsider99 commented 3 years ago

Hi @N1ghtly, here is the screenshot of the plotted chart Simulator Screen Shot - iPhone 11 The given data passed for tickValues prop in HorizontalAxis component is,

const xValues = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

The above values are being passed into a helper function (getMonth()) to display the x values as months.

The data that is passed into the Line component is,

const data = [{"x": 12, "y": 0}, {"x": 1, "y": 0}, {"x": 2, "y": 0}, {"x": 3, "y": 0}, {"x": 4, "y": 0}, {"x": 5, "y": 0}, {"x": 6, "y": 0}, {"x": 7, "y": 0}, {"x": 8, "y": 0}, {"x": 9, "y": 0}, {"x": 10, "y": 0}, {"x": 11, "y": 5}]

                 <Chart
                    yDomain={{min: 0, max: yAxisThreshold}}>
                    <VerticalAxis
                      tickCount={5}
                    />
                    <HorizontalAxis
                      tickValues={xValues}
                      tickCount={12}
                      includeOriginTick={true}
                     />
                    <Line
                      data={data}
                      tooltipComponent={
                        <Tooltip />
                      }
                      smoothing="cubic-spline"
                    />
                  </Chart>

Thanks!

xanderdeseyn commented 3 years ago

Ahh I see what you are doing now! This is actually expected behaviour, if it wouldn't be like this, we would not be following the laws of mathematics. We can't render a data point with x = 12 on x = 1! You should solve this by always using 1-12 as X values, and using the formatter prop to show the correct month.

Eg, if you have this data:

Nov Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct
5 10 2 0 3 4 8 12 9 7 6 0

We convert it to these data points:

0 1 2 3 4 5 6 7 8 9 10 11
5 10 2 0 3 4 8 12 9 7 6 0 

Now, in order to show the correct month label, we modify our formatter:

formatter: (xValue) => this.getMonth((xValue - 2) % 12)

where getMonth(0) === January.

I hope this is clear :)