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

What's the proper way to manually set chart's scale and scroll offset? #226

Closed
liuxuan30 opened this issue Jul 17, 2015 · 7 comments
Closed

Comments

@liuxuan30
Copy link
Member

Say I have two view controllers in navigation view controller,

On first VC, I have a bar chart, and I zoom & scroll the chart. Then When user double tap the VC, it pushes to the second VC,

Now I want the chart to be at the same zoom & scroll status if I pop back to the first VC. What's the proper way to do so? Does ios-charts support this right now?

I am looking at ChartViewPortHandler, and I see functions like setDragOffsetX(), setDragOffsetY(), zoom(), but I am not sure if this can achieve my goal? It feels like such APIs are too high level for my requirement, so I am wondering is there any better way to do it?

@danielgindi
Copy link
Collaborator

If the charts are the same size, and same amount of data, then calling restrainViewPort with the data from the first chart's viewport, and same for zoom, should suffice. But I haven't tried this yet so I'm not sure 100% about it :-)

@liuxuan30
Copy link
Member Author

Looks like restrainViewPort only set the contentRect's frame, not the scale and offset(translation)?

Do you think change _touchMatrix will help? It becomes hard to understand how it works..

Do you consider this is a good feature to have? Not sure about others. It's more like a 'session' mechanism that can memorize the chart last state.

@liuxuan30
Copy link
Member Author

Alright, I am lucky to find out that viewPortHandler.refresh() can achieve such feature, just save the last touchMatrix, and then feed this touchMatrix to refresh(), it can set the chart to the almost same state.

Why I am saying 'almost' is it sometimes will have a slightly offset horizontally.. and sometime it will pause one second, and then jump to the correct position, exact the same state. It is hard to know where goes wrong...

Screenshot:

the chart last state as below:
old

save the touchMatrix, and call refresh() to try to restore:
new

Look at the left most bar, the blue one is out of bound. has some slight offset I guess.

It is reproducible when chart has no zoom and scroll, just call refresh().

However, when I zoomed & scrolled, it can restore to the exact same state.

@liuxuan30
Copy link
Member Author

OK, I found the reason! While I don't zoom the chart, the leftAxis range is [0,100], so the leftOffset is some value; however, when I zoomed, the leftAxis range becomes double digit like [40,90], so the leftOffeset is changed.
Check the original chart, and watch for yAxis range and the leftOffeset and compare to below one.
origin

@danielgindi , do you know where you change the left offset and what's the variable name? Compare below offset for 100 and 90 label:
before the zoom, the axis max is 100, so there is some margin:
100
after zoom, the max value is 90, so the left margin is changed....
90

@danielgindi
Copy link
Collaborator

This is actually a recent feature that I've implemented, to prevent cases where after changing the viewport, the labels get longer and are clipped (#72).
Now if you want to gain more control - you could set ChartYAxis.minWidth and ChartYAxis.maxWidth, so it doesn't change no matter what!
But it has its own consequences of course.

Anyway, if you want to keep the dynamic nature of the viewport, you could either:

  1. Do a two-phase change - first change the Y axis scale/position, force it to recalculate (computeAxis), and then set the X scale/position.
  2. Make sure you copy the offsetLeft/offsetRight etc. between viewports. As you can see in BarLineChartViewBase's calculateOffsets() - it queries for leftAxisRenderer.requiredSize() and then calls viewPortHandler.restrainViewPort(...). And of course, requiredSize() returns the correct required size only after being properly calculated by computeAxis() of the renderer. The renderer calculates the axis' values according the the viewport position and user's configuration. (We might move this to the axis itself but not sure yet)

@LucaFagan
Copy link

I have the same problem in a LineChartView but have no idea how to salve it because your solution is for BarChart. Can you help me ?

@marshtupa
Copy link

I find solution that helps me! Check this comment
#450 (comment)

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

No branches or pull requests

4 participants