plotters
plotters copied to clipboard
Animated Charts and potential Iced backend
Hello,
When creating an animated chart, does this simply mean recreating the chart every time new data comes in? The piston example seems to suggest that, but it doesn't seem supported anymore.
I'm working on creating a Iced backend with its canvas
component. Drawing charts seems to work with the required DrawingBackend
methods implemented. The optional methods shouldn't be a problem besides estimate_text_size
and blit_bitmap
.
estimate_text_size
requires this issue to be implemented.
Does blit_bitmap
help with anything besides the bitmap backend?
draw_text
provides pos
as the anchorpoint of the text, where is this located in relation to the text, the top left corner?
Would you be interested to add an Iced backend to the other supported backends?
My end goal is to create interactive charts where you can resize the shown data and get a "popup" showing the data the cursor hovers over. For the hovering think something like this.
In Iced, I think this could be achieved by comparing the cursor position to what's drawn on the canvas. For this to work I would need the position of the drawn elements of the chart. As a simple example, when drawing a histogram I would need to know where the bar's borders are located. For zooming with linecharts, I would probably need the border coordinates of the coordinate system, maybe the coordinates of the data points but those should be easy enough to calculate with the coordinate system borders. Is there any way to get this information or maybe to include optional Methods in the
DrawingBackend
?
Thank you very much for your time and work.
Hi, I like the idea of having iced backend. Having integration to GUI framework seems amazing to me.
One reason of removing piston backend is there's some dependency issue and at that that piston-window seems poorly maintained. What make things worse is at that time core code and backend code are in the same crate, that makes maintaining a big pain. With plotters 0.3 there's no more concern.
Short answer to the backend implementation: The only needed function for a working backend is: ensure_prepared
, present
and draw_pixel
. All other function is implemented with draw_pixel
, although it may be inefficiently. Any overriding the provided trait method is most likely performance optimization.
When creating an animated chart, does this simply mean recreating the chart every time new data comes in?
Mostly, but there's one optimization: The problem can choose only redraw the data area, instead of the entire chart. https://github.com/38/plotters/blob/8e120a12ad97cd8b204f311592e87a589243f273/examples/minifb-demo/src/main.rs#L83-L89 When you have multiple subplot, you can selectively update the changed plot as well.
estimate_text_size
requires this issue to be implemented.
The estimate_text_size
has default implementation - when TTF support is enabled, Plotters will use it's own font handling code to estimate text size, so I believe that won't be a issue. Let me explain why this is a backend API: For most backend, the default implementation can be used and Plotters handles all the text positioning for you. But in some case, for example backend targeting a text console, which doesn't support font we want the backend to determine what's the size of the text is. Other than that I believe there's no need for override this trait method.
Does
blit_bitmap
help with anything besides the bitmap backend?
blit_bitmap
gives you an ability of drawing an image to the drawing area. See this example https://github.com/38/plotters/blob/master/examples/blit-bitmap.rs It has a default implementation, which calls the draw_pixel
and render the bitmap pixel by pixel - however, this could be very inefficient - for example, for bitmap backend we copy the image buffer directly for this purpose; for SVG we use the the <image>
element to implement this call (If this is not implemented for the SVG backend, drawing an image on SVG backend turns out to be drawing tons small rectangles to simulate pixels in SVG), etc.
to create interactive charts
For interactivity, Plotters have been planning for this for a long time #13 . The planned of Plotters interactivity support is use Plotters as a event dispatcher, which doesn't directly gives you any interactivity - But it provides a toolkit that allows you query what logic component is involved. I believe if you have idea on interactivity chart, it would be a good chance for plotters start supporting the interactivity. Personally I am not a GUI/Web programmer, so I may need some help for the actual interactivity implementation.
Hope this answers your question and please let me know if you have any more questions.
Cheers!
Thank you very much for the in depth answers!
I created a seemingly working prototype here: https://github.com/arctic-alpaca/plotters_backend_iced
You made integration into new backends really easy.
Under iced_backend
is the backend code. Do you have any recommendations on how to test this properly?
A simple working example with iced is under src
, cloning the repository and running cargo run
should be sufficient.
There is some blurriness and artifacts when resizing the window which seem to be related to https://github.com/hecrj/iced/issues/494.
For interactivity...
Using Plotters as an event dispatcher sounds like a great idea, especially from an ease of integration standpoint. What you wrote here seems like a good aproach to me, but I'm also not very well versed in GUI/Web development. Am I right in thinking this would mean keeping an instantiated plot struct somewhere, similiar to animated charts optimization?
There seems to be two obvious options. Providing information about the location of plot element to allow the developer/user to implement interactivity themself or to accept event like click_at(coords)
and hover_over(coords)
. I think allowing both could be useful for people who just want it to work and people who want to have fine control over the interaction. I guess the location information of plot objects (bars/lines/etc) needs to be saved anyway to allow dispatching of events so this information could be made accessible.
What events would you plan to support?
How could I help with implementing interactivity?
There seems to be two obvious options. Providing information about the location of plot element to allow the developer/user to implement interactivity themself or to accept event like
click_at(coords)
andhover_over(coords)
. I think allowing both could be useful for people who just want it to work and people who want to have fine control over the interaction. I guess the location information of plot objects (bars/lines/etc) needs to be saved anyway to allow dispatching of events so this information could be made accessible.
Currently we have limited ability of interpret the event. Plotters allows reverse coordinate mapping, which map the device coord to logic coord. https://docs.rs/plotters/0.3.0/plotters/chart/struct.ChartContext.html#method.into_coord_trans But I am still wanting a better version of this.
There is some blurriness and artifacts when resizing the window which seem to be related to hecrj/iced#494.
Finally get vulkan works on my side. And note more note on this: You are missing font rendering function, which means Plotters draws the text use it's own font handling code, use the iced text handling should give a better result.
But I am still wanting a better version of this.
What do you think a better version should look like?
And note more note on this: You are missing font rendering function, which means Plotters draws the text use it's own font handling code, use the iced text handling should give a better result.
I don't think the blurriness and artifacts are related to the text rendering. But I'll work on this as soon as I got some more free time.
About the text drawing, as far as I can tell, DrawingBackend::draw_text
requires BackendTextStyle
to be implemented. But I don't think this is possible until Iced can calculate the text size.
I looked a bit more into it, a way to estimate text size is definitly needed since plotters_backend::BackendTextStyle
supplies an anchorpoint and without the textsize I can't calculate the top right corner needed for iced.
I looked into creating a backend for OrbTk and had some problems that will need sorting before it could be used. One thing that would make it easier would be to make plotters_backend::DrawingBackend::estimate_text_size
also &mut self
like the rest of the trait. Would that be possible?
As far as I can tell, OrbTk currently only supports loading supplied fonts, not system fonts so that's an issue too. I'm not sure how this is in Iced at the moment.
Hi, sorry for the delay, I was busy last week. Thanks for looking into this.
make
plotters_backend::DrawingBackend::estimate_text_size
also&mut self
like the rest of the trait. Would that be possible?
This is possible, but only concern is this is a breaking change so that if we feel this is needed we are going to change in the next major release - the problem is we need to wait, since I don't think we want to ship any breaking change without bumping the version number.
So I am wondering if the RefCell
works in this case?
Let me know if you have any thoughts!
Really appreciated for your contribution! Cheers
So I am wondering if the RefCell works in this case?
I didn't think of that, it does indeed seem like it works. Thanks!
For a complete OrbTk backend, there are currently two things missing:
- Font loading, currently the only options are supplying a font yourself or using the default OrbTk font, no system fonts are accessible as far as I can tell. This isn't necessarily a problem, just something that would need attention when using the backend.
- Text rotation/translation
Here is my current code if you want to take a look.
Text rotation/translation has been added to OrbTk. The backend should work now, besides only supporting self supplied fonts.