Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-engineering the core abstract-chart code. #355

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

aboveyunhai
Copy link
Contributor

@aboveyunhai aboveyunhai commented Jun 23, 2020

I used the repo and encounter a lot of problems. I reengineer a lot of core codes to make some of charts fully responsive and ease out a lot of problems, I would rather called it a prototype of Ver.2 or breaking change. So I thought it might be somehow helpful for the main repo and good to share .

This is more like a proposal instead of PR. @Hermanya

Please don't use this merge unless you only care about BarChart, LineChart and ContributionChart (There are now fully responsive and can apply all padding styles).

StackedBar is broken unless I fixed it to match the new abstract-chart.js. There is also some changes so it has no backward-compatibility for those abused property in the past.
The rest of charts remain unknown because I don't know if how they used abstract-chart.js. As far I as know, they all should be fine because they just basically extends from it without actually use some of core functions.

If anyone is interested this merge may try it out. And of course it will slightly affect the chart-layout if ppl used the old style is the past but you can always apply your own chartStyles.

I just want to use pic to show the current problem and the main issue that many merges were already based on that.

image

This pic show the current properties are used to build you chart.

Red(1,2,3,4) is padding up right down left for the outer container <View>.

(P1)(Problem1): inside the chart their is a paddingRight Yellow(6). It should be rename to paddingLeft for it's true intent. The wrong paddingRight span almost everythere for every single calculation.

(P2): <View/> style prop mess with chart. for instance, changing paddingLeft(currently is named paddingRight in code) affects both Red(2) and Yellow(6). In line-chart.js, paddingTop changed Red(1) and Yellow(5) and other styles like borderRadius and so on.

(P3): hardcode number and the way to build chart content(the space used to draw bar and line)
Yellow (3) horizontal Label Width is predefined with fix number, Yellow (4) gutter size (some gap between the top of chart and padding so horizontal label wouldn't overflow and aesthetic)s )is hardcoded.

The content height is the sum of Yellow(1) and Purple. here is the tricky part, Yellow(1) is 3/4 of height (which is hardcoded) and then it was spliced by segment then render the extra one line (the position of bottom line 0) to determine the Purple height. Whatever (Yellow(2) - Purple) is reserved for bottom labels(SUN, MON....). It caused position calculation extremely difficult in code and trouble to further implement padding and other size property (whatever contents below Yellow(1) is almost uncontrollable with the current way of rendering)

There are also some minor issues upon that but I don't think it matters that much because I fixed most of them along with the new implementation.

The new implementation,
image

<View style={}/> is completed isolated from the chart hence style prop only affects the outer container style.
paddingRight is corrected to paddingLeft.

all the inner paddings Green(1,2,3,4) is now inside:

chartConfig {
 chartStyle: {  paddingLeft ....  }
}

so it wouldn't confused with style prop .

Green (5,6,7)``verticalLabelHeight, horizontalLabelWidth, and gutterTop is predefined dynamically to the size you provided. Default percentage is in Doc. You can pass some fix number or dynamic size by yourself,
which left out the chart content Blue Rect completely dynamic to your adjustment. The old way of calculating the height is completely removed,

In term of code, most of the old calculation logic ( height / some number * some number) /more number + ..... becomes straightaway addition and subtraction. IMO this is more intuitive for future implementation.

segments default is moved from 1 => 2, it means total number of lines in graph including the baseline, It has no harm if you really want to use baseline(1) only .

fromZero is completed removed because it is not generic and create duplicated code in if block.
Instead, defMax and defMin as optional props are introduced to define the default max/min in graph. If you noticed, the pic above has a defMax={1000} and defMin={0}.
The old 'fromZero' is basically defMin={0}.

Random no-sense exmaple like
defMin={-100} defMax={200}

image

<ContributionChart> itself is standalone from others, So I just apply the way of RN view style to it so it can work like

chartConfig{
  chartStyle{
     justifyConent:  'center' 
   }
}

as well as padding. More details are in the new Doc.

A customizable TooltIp is also added but I haven't prepared how to make Doc for it, it does required user to do some calculations by themselves.

But here is the gif in action.
sample

The other graphs based on `abstract-chart.js` remain broken.
reimplement core chart, support bar-chart for full dynamic sizes
re-invent heatmap to fully dynamy and layout-control
Fix issue include `useNativeDriver` warning for RN>6.2. Some crashes on `scrollDot` when user missing some trivial styles and props.
Fix: migrate Deprecated UNSAFE_componentWillReceiveProps to standard RN method.
Dynamic chart size (line-chart fix), Add tooltip to contribution content
Update abstract-chart compatibility for line-chart
Fix: correct midpoint for BarChart labels
@Hermanya
Copy link
Contributor

This library could definitely use some more responsiveness. Let's see if anybody else from the community is interested.

@aboveyunhai
Copy link
Contributor Author

This library could definitely use some more responsiveness. Let's see if anybody else from the community is interested.

The main concern is that this change is not friendly to current users because of the mixed style issues. They may add a lot of own styles to tackle the original style issue, Otherwise it's always ready to merge without crushing apps after I fixed the <stackbar>.

@tayloraleach
Copy link

Does this PR address the 'gap' to the right side of the LineChart that a lot of people are experiencing? Even the example code suffers from this and I am having a terrible time trying to fix it. Thanks.

@aboveyunhai
Copy link
Contributor Author

aboveyunhai commented Jul 6, 2020

Does this PR address the 'gap' to the right side of the LineChart that a lot of people are experiencing? Even the example code suffers from this and I am having a terrible time trying to fix it. Thanks.

The gap issue (technically padding left or padding right) is just initial motivation, small part of this PR, and eventually includes adding all padding and rework the core layout implementation. I believe the gap is implemented in a weird way is because the original layout calculation is quite confusing as I go through it. If you don't mind the stackedbar is currently broken, you can feel free to test others out, and try all the padding features, and see how it layout out slightly different than the old one.

return endOfWeek.getDate() >= 1 && endOfWeek.getDate() <= DAYS_IN_WEEK ? (
<Text
key={weekIndex}
x={x + paddingLeft}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paddingLeft is really annoying, thank god it will be removed finally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paddingLeft is really annoying, thank god it will be removed finally.

paddingLeft still exist but migrate to chartConfig: { chartStyle:{ //here } } without conflict with outer container style props.
This PR isn't going to anywhere yet, but I can guarantee the contribution chart itself it's fully functional. If you only use it you are free to try my fork. I believe Doc is up to date also.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, configurable is awesome.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checkout to your PR, but there is no build script in package.json, so how can I try use it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checkout to your PR, but there is no build script in package.json, so how can I try use it?

The complexity comes from all the recent typescript updated. So there must be a lot of conflicts as far as I know, Since PR is all based on my fork repo, a tricky and easy way to do this is to directly npm install my fork repo as another library, you probably need to create alias for it so it wouldn't replace the main one, and then use the contributionchart, by this way you can always switch back to the main repo and delete the old one once it's ready.

Copy link

@metrue metrue Jul 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean like?

git clone <your repo>
cd <your repo>
npm i

npm install in your repo won't help I think, which not install anything to my app repo.

If you're planning to create a branch new lib, a branch new pkg would be great, otherwise, I can wait for this PR got merged (hopefully).

And let me know if anything I can help if you want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, just directly install from github repo.
check this one out for specific details: https://stackoverflow.com/questions/26414587/how-to-install-multiple-versions-of-package-using-npm/56495651#56495651
You can do something like npm install YourOwnName@https://github.com/aboveyunhai/react-native-chart-kit.git

then in your project

import { ContributionChart } from 'react-native-chart-kit';
import { ContributionChart as TempContributionChart }  from "YouOwnName";

Now you can use whatever you want from both repo.

@metrue
Copy link

metrue commented Jul 23, 2020

@aboveyunhai it needs a rebase to fix the conflict.

@Hermanya is it ready for merge if conflicts are resolved, or what else needs to be addressed if it wants to get merge?

@Hermanya
Copy link
Contributor

@Hermanya is it ready for merge if conflicts are resolved, or what else needs to be addressed if it wants to get merge?

Please don't use this merge unless you only care about BarChart, LineChart and ContributionChart (There are now fully responsive and can apply all padding styles).

@adilusman51
Copy link

@aboveyunhai @metrue @Hermanya
Hi, any updates on timeline when this PR could be merged.

I also have a suggestion, can we also have an option to do solid color fill for the chart in this PR? Or this will be done as a separate PR. Having only gradient fills limits the ui design choices

@Hermanya
Copy link
Contributor

@adilusman51 I don't think we have a plan around this. But there are merge conflicts now.

As for colors, you can make a gradient from and to the same color.

@adilusman51
Copy link

adilusman51 commented Aug 30, 2020

@Hermanya Thanks for providing an update.
Currently we have properties backgroundGradientFrom backgroundGradientFromOpacity backgroundGradientTo backgroundGradientToOpacity from background configurations in ChartConfig. There is fillShadowGradient fillShadowGradientOpacity for the fill which are applied to the start of the gradient, but end of gradient has default opacity set to 0. As a result, in BarChart we always get a gradient which limits ui design. Kindly pardon me if I am wrong. I hope this is helpful.


<Stop offset="1" stopColor={fillShadowGradient} stopOpacity="0" />

@aboveyunhai
Copy link
Contributor Author

aboveyunhai commented Aug 31, 2020

@adilusman51 unfortunately, I don't believe this is going to merge any soon.
Just few things you might want to know, Stackedbar is broken and rest of charts should work as expect. There are a lot of code redundancy between barchart, stackedbar and `Linechart`` so i'm a little bit of impatient to fix it unless I can abstract another layer out of them.
Another thing is that this merge is right before the big typescript rewrite. I am personally more interested in functionalities first and not so familiar with advanced Typescript. So even all functionalities are up to date. Conflicts will still be there no matter what....
But always welcome if want to improve this fork. And see we can merge back eventually.

@hariDasu
Copy link

hariDasu commented Oct 6, 2020

@Hermanya Thanks for providing an update.
Currently we have properties backgroundGradientFrom backgroundGradientFromOpacity backgroundGradientTo backgroundGradientToOpacity from background configurations in ChartConfig. There is fillShadowGradient fillShadowGradientOpacity for the fill which are applied to the start of the gradient, but end of gradient has default opacity set to 0. As a result, in BarChart we always get a gradient which limits ui design. Kindly pardon me if I am wrong. I hope this is helpful.

<Stop offset="1" stopColor={fillShadowGradient} stopOpacity="0" />

i have been trying to override this gradient for bars in the BarChart in my fork: https://github.com/hariDasu/react-native-chart-kit/blob/master/src/BarChart.tsx#L65

but am still trying to fully understand the chart config types and how to override the LinearGradient that is being used to color each bar. this stackoverflow post i made describes my problem in more detail:

https://stackoverflow.com/questions/64035350/solid-bars-in-bar-chart-with-react-native-chart-kit/64044806?noredirect=1#comment113358826_64044806

I followed the suggested approach and it looks better, but still has a slight gradient that I wish I could do without. it would be nice if this was possible in a future release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants