-
Notifications
You must be signed in to change notification settings - Fork 951
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
Composable Axis #1640
Comments
Sounds interesting! I agree that the axes could use could use more flexibility. |
Linking #1255 : inexact maths will always be troublesome, but something to keep in mind. |
Linking #1721 : this is a good use-case for 'inline-side' bands. |
how are you progressing in the composite axis design? I am really looking forward to the opportunity to draw financial charts without gaps. |
@karuzzo not looked at it for a while. I rushed some notes a while back, but got caught up in designing a new layout system (https://github.com/VisualMelon/oxyplot/blob/ComposableAxis/Source/OxyPlot/Axes/ComposableAxis/Composable%20Axis.pptx) and have been focussed on other things lately. My conclusion for making axis less painful was to define a new space Interaction Space which sits between the Dataspace and Screen Space that only the axis need know about, and that just provides a way to provide 'linear' behaviour to a non-linear or non-continuous data-space (can't use screen space, because that depends on layout). However, there is a whole set of suffering to be had in making things render properly on such axes, because the assumption of linear interpolation doesn't work on a non-linear/discontinuous axis: we need to permit series to query where discontinuities occur so that it they can render accordingly (in the same way that The new interface for interpolation will probably need to look something like
The Note: this interface would be provided by a generic struct that wraps a mapping from Data to Interaction space and view information (i.e. It would probably be good for me to implement all this without the layout mechanism soon, because the layout mechanism is going to be a nightmare and the whole point is that its composable, so if I can't implement this independently then I'm doomed fail whatever I do. |
@Jonarw @objorke how would we feel about trying to make axis types statically typed for 3.0? That is, The idea is that the 'type gap' would be closed when axes are assigned to series (by The benefit would be that users can use 'proper' types instead of turning everything into
Below is mindless commentary, mostly for my benefit. I may end up butchering everything, but I'm going to try and get this working in my Composable Axis branch, because a lot of the work to provide powerful axes requires strongly typed axes. The big issue I'm facing (or rather avoiding) at the moment is that I need to replace the If we are very lucky, the anguish associated with resolving all the types at run-time will mean we don't suffer hideous performance from the abstractions. Instead, we will have hideous types like TypedXYRenderHelper: because all the providers can be structs, the JIT should do a good job of producing efficient code (potentially faster that what we have now, but obviously that's wishful thinking) as there shouldn't be any virtual calls in any tight loops: instead, there will be additional overhead in initialising such render helpers (which can exist for 1, 2, 3, etc. axis (e.g. X,(Y),(Color))) Other notes:
|
Looking into replacing With that out out of the way, the number of places that axis type parameters will need to be 'passed' should go right down... we won't even need it for series (but it would be nice to keep the option open, as it may help with performance (though, I think performance is pretty much limited by rendering). I'll shelve my work for the moment, and go from the other end (i.e. start by working out the Axis abstraction, now that I know what Axes themselves can look like). |
Thanks for your hard work! |
Linking #1612: |
Just look at this (OxyPlot + SkiaSharp) https://youtu.be/6y4X1a494kM?t=114 |
Thanks for pinging this. I've since changed the plan for handling discontinuities. I still need to work out how to fit my plan into the existing library, but for the moment I'm looking at how painful it will be to implement a series using typed axes (including all the power of discontinuities, etc.) because it's easier. Note to self: may need to know where discontinuities are precisely in order to render them... but that's probably a different type of discontinuity that should be customisable within the axis, not the data provision. Note: can probably do that quite nicely by wrapping the data-provider with a known-type data-provider that supports flexible gaps (and make this known to the axis renderer). |
The library should not have a mechanism for self-determination of gaps. But it would be great if the DateTime axis had a method for adding a break of the form axis.AddGap (double, double) |
My ComposableAxis branch has predictably become a nightmare, but I'm getting to the point where I should be able to start putting typed axes on a plot. (then I need to sort out typed series and typed annotations). Remaining tasks:
Not really looked into the
Some notes on things that are producing lots of overhead though and aren't totally on point but I need to remember:
I am totally convinced of the value of the data/interaction/screen space separation, and once you have that, you might as well make everything typed... Other:
|
Progress:
Next Tasks:
Tick band redesign:
Since all the work is around typing, I'm considering putting all this in a separate |
I don't think the CI failures are related to the new stuff: https://github.com/VisualMelon/oxyplot/runs/1806133454?check_suite_focus=true Also, I was able to rebase the Composable Axis branch (forked from 2.1preview1) without any conflicts, so that's reassuring. |
Thinking about it... why not expose interaction space to everyone? Series (e.g. Other benefits:
This is a ludicrously appealing prospect... which I shall ignore for the moment. It should be easy to implement this alongside what I already have later. That said... this would be much closer to the idea of a pre-transform on axis: it could be easy to bolt on-top of existing stuff by just attaching the pre-transform for to the axis, and looking for it in the series (rather than re-fabbing everything): redefine interaction space as data-space, and data-space as pre-transform-space. This wouldn't be as semantically nice, but it would be much easier. It also has nothing to do with composition: it might be easier to separate the need for a composable axis from the desire for typed everything. |
Instead of doing anything useful today, I looked into the performance of the new |
Progress:
Notes on non-obvious deficiencies in the new
Other notes:
New TODO list:
|
Progress:
TODO:
|
Progress:
Problems I am ignoring for the moment or that I might get around to during the week:
Hopefully I'll find more time for this next weekend, when I'll focus on trying to make one nice example with lots of shiny new features. I think I need to sort out some nice wrapper APIs before getting feedback on this stuff; however, I don't want to try for drop-in-replacement before discussing the architecture and general approach (and whether any of this is desirable). Last thought: I was thinking about a
|
Surprise first pass at Candle Stick on discontinuous axis, based on an existing Candle Stick example. Data is the same as in the existing Candle Stick examples, just with Sunday, Saturday, and 20:00 to 08:00 removed (hence the big jumps) You can see that each day cycled back to 08:00 instead of reaching 20:00, and that it skips June 19 and 20, which are a weekend. Example code is here: https://github.com/VisualMelon/oxyplot/blob/d7eab0f2fc4f2ff8cbce2f8a1755481f812183d0/Source/Examples/ExampleLibrary/Axes/ComposableAxisExamples.cs#L802 The bits that are 'unique' to the example are the use of the Other notes:
|
you are wonderful! tomorrow I'll study your example |
@karuzzo any and all feedback welcome, especially if it's along the lines of "you've totally missed the point". The bit that enables discontinuous axes to work is the The I don't anticipate much of what I've been doing lately to end up in the final library: it's just too complicated/bity. I would be very interested to hear ideas about which bits are important, so that we can try to work them in without creating too many compatibility headaches. |
Progress:
Notes:
TODO:
|
Having stopped looking at this regularly for a bit, I think I need to start focus on writing code that can actually be used in the library. I think the place to start is by fixing on a new axis abstraction (because everything else depends on them; everything else is pretty much stand-alone otherwise). I was going to write lots of stuff about it here... but then I looked at what I already have, and I'm pretty happy with it. See
One thing that is missing is an explicit provision for operating in interaction space: that is, currently the design expects you to feed data-space stuff to the render helper, but there are benefits to being about to perform 'pre transforms', taking data-space to interaction space and then rendering all that:
Providing such a capability means that we would have 2 ways of implementing typed axes: one using 'pre-transforms', and one not. It also means we could fairly easily retro-fit existing series, but changing the rendering logic to work in interaction space, and just put a mapping infront of this. Notes:
|
Feature description
We have axes that override formatting (Time), that override the transforms (Logarithmic), that override the Tick and Label placement (Category), and all these features are difficult to combine - despite dealing with independent concerns - because they are based on inheritance and internal implementations. I propose we design a composable axis class that allows you to 'plug in' the separate behaviours.
Obvious candidate extension points (with no real organisation) would be
Additionally, by formalising these boundaries and providing nice implementations, they can be recomposed in exciting ways e.g. to provide axes with multiple 'banks' of ticks (#1357, #1336, #1629), or (if they are ever supported) non-XY/polar (e.g. triangle #1136, or even 3D (would of course need dedicated front-end support)) plots, would minimise duplication.
This is something I've tried a number of times in the past (thinking it could go in oxy-contrib), but I've always come a gutser because it would involve duplicated the work done in
HorizontalAndVerticalAxisRenderer
, and my astounding laziness prevents me from trying stuff without a clear design goal, so I just end up fudging whatever I actually need at the time.Some random notes :
Anyhow, I thought it worth putting an issue together where we can put ideas, because I'm certainly never going to get around to it otherwise, though it's something on which I'd be keen to work.
The text was updated successfully, but these errors were encountered: