-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Proposal: Data Visualization
There are many concepts, actions, data, etc. that are best modeled by visualizations of some kind or another. GoLang is currently lacking in effective visualization tools, especially those that can be used interactively. This document intends to provide a road-map for future development of visualizations in Fyne. The intent is to lay out what types of visualizations may be of interest, identify prior art (if any), and form the foundation of future discussion on the matter.
This document is intended to be aspirational, not a detailed technical review of how these ideas might actually be implemented. The scope, nature, details, etc. might be reduced due to real-world constraints. In other words, this document should be viewed as "what we would like to have if we had unlimited developer time".
Some or all of these ideas may be judged "out of scope" for Fyne proper, but may nevertheless serve as a useful starting point for community members wishing to implement them as libraries.
Others are invited to extend the "prior art" with their own subjective experiences, or other relevant past solutions to these problems that have been missed. All are also invited to further elaborate on the set of proposed visualizations and what features they should offer.
Discussion/proposals of specific features to be implemented and their implementation details should be done in separate documents and linked back here.
Ideas/features that are common across all types of visualizations.
It should be possible to export vector graphics figures from these data visualizations, in a format such as PostScript or SVG. It is possible this could be implemented at the level of fyne.canvas
, in which case figure exporting would come for free.
Note: "canvas" is a working name, we don't want to have a confusing collision with fyne.canvas
.
- New working name: Diagram
A "canvas" in this context refers to a container which allows the developer to conveniently show shapes and text, ideally in an animated fashion. This would offer a superset of the functionality that the current "canvas" in Fyne offers. It may be useful to come up with a better name than "canvas" to distinguish the two.
A pseudo-code example of what this might enable the user to do:
mycanvas := dataviz.NewCanvas()
rect1 := mycanvs.AddRect()
rect1.setColor(dataviz.green)
rect1.bindWidth(&somevar)
rect1.bindPosY(&someothervar)
It should be possible to either set an attribute (such as width, size, scale, rotation, position, etc.) to a constant value, or bind it to a pointer (polled during an animation?). Setting a constant value could allocate a variable, set it to the constant, and then bind that.
It should also offer a large number of geometric primitives: line, arrow, curve, circle, rectangle, triangle, various markers, and generic polygons.
A variety of colors and color scales should be easy to use ("here is my data, here is the min and max, color this object according to that" should be easy to express).
This type of "canvas" would not seek to offer a high level of performance, but rather make it easy to implement visualizations. As a baseline performance target, dozens to hundreds of objects with multiple bound attributes should run smoothly on a typical commodity system.
TODO
A high-level canvas implemented in Fyne. Definitely worth considering as the starting point for any future implementation.
An introduction to d3.js in 10 basic examples.
d3.js offers essentially all of the features proposed above, and then some. Potential users would be likely to compare any "canvas visualization" Fyne would write to d3.
Subjective experience: I've dabbled (as a user) very lightly in d3.js. I found the API didn't offer the right primitives for most of the things I wanted to do. d3.js as an abstraction over HTML+CSS+SVG leaks to a considerable extent, and I found it too slow nearly ever time I have tried to use it. However, it is widely used and solves many of the problems a canvas visualization would like to solve. I do not think the API it offers is something to be emulated, but the set of features it has on tap is. -- Charles
TCL/Tk includes a robust canvas widget that also implements most of what the proposed canvas visualization hopes to include. This is a tried and battle-tested implementation, although TCL/Tk is certainly long in the tooth, and many valid criticisms of both can be made.
Subjective experience: I've also dabbled in TCL/Tk, and found their canvas very straightforward to work with (if you are comfortable with TCL's anachronisms). It definitely has some flaws endemic to it's age and history, but I would vouch for it as a good reference point for a good API for doing this. -- Charles
Eggx tries to be a much more general-purpose library for drawing graphics, and also has it's own little widget library baked in. It is notable for the extremely simple and easy to understand API. It allows the developer to do quite a bit without having to understand much about graphics, synchronicity, etc.
Subjective experience: Eggx is great if you only want to solve the set of problems that it is able to solve. It seems difficult to extent, isn't portable, and generally makes things hard as soon as you go off the beaten track with it. I think it's simplicity is something to be emulated if possible. -- Charles
Plots are pre-baked visualizations that allow showing how data changes over time (or with respect to some other variable). This would include things like pine pots, bar charts, scatter plots, pie charts, and many more.
Ideally a plotting system built in Fyne would allow:
- Large amounts of data (tens of thousands+ points)
- Live updating of data
- Sensible implementations of a variety of common plot types
- Data in a variety of formats to be used
Plot(Xcoords []float64, Ycords []float64, ...)
Plot(points [][]float64, ...)
Plot(getter func(float64)float64, xmin, xmax, xstep float64, ...)
Plot(getter func(int)float64, howmany int)
- Different use cases may lend themselves to one or the other
https://speakerdeck.com/ajstarks/dchart-charts-from-deck-markup
TODO
(thank you Anthony!)
TODO
A chart library written in Fyne. It is definitely worth considering this as the basis for any future implementation.
Matplotlib is the de-facto plotting library used in the Python ecosystem. It can support nearly every time of plot one can imagine. However, live updating plots is difficult, and having one or more plots up in the background while continuing to progress through the application code is challenging.
Subjective experience: I have worked extensively with matplotlib. It's extremely featureful, but the API is often inconstant between different types of plots, and handling some common tasks (such as having two plots open at once) are more herculean than I would like. -- Charles
TODO
TODO
An imgui-based plotting widget. This is a great model of how it should feel for the end user to interact with plots. It's also got great live-plotting capabilities.
Graphs are collections of edges and vertices. Graphs (and structures that are subset of them like trees) crop up all the time, being able to directly visualize them can be very powerful.
The "node editor" pattern is very useful in certain applications to allow users to visually observe/describe/modify how data should move between systems. To this end, it would be valuable to consider allowing interactive editing, with "slots" or "sockets" to connect links into, and allowing widgets to be embedded as graph nodes.
AG_Graph is the native plotting widget for libAgar.
TODO
Subjective experience: I've used AG_Graph
for data visualizations to great effect in the past. It's really the only pre-done graph widget I've used, so I can't comment on how it would compare to other implementations. I have some example code here. Full disclosure: I wrote the direct graph support for AG_Graph. -- Charles
Graphviz is the gold-standard in automatic graph layout. However, it is not a graph widget, and isn't suitable for interactive use.
TODO
imgui proper does not support this type of visualization, however there are a large number of extensions that do. In particular, many offer "node editor" type interfaces, allowing widgets to be embedded so the user can represent how data should flow between different components of a system.
TODO