plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
16.97k stars 1.86k forks source link

Plotly shape always drawn under the trace when the plot type is pie #2110

Closed dipan66 closed 6 years ago

dipan66 commented 6 years ago

Code reference: https://codepen.io/dipan66/pen/dVEXOy

In this, we are trying to draw a gauge chart by drawing a needle shape over a pie. The needle is always being drawn below the trace, though the layer attribute is set to "above". Need help / thoughts on how we can go about and get the needle shape to be drawn above the pie.

Se are using Plotly.js v1.25.0

alexcjohnson commented 6 years ago

Good call, looks like even layer: 'above' shapes are still below pies and webgl plots. I suspect we could just move layer-above into _toppaper - though it should stay below infolayer so annotations will still be above shapes (which means the legend will also still be above shapes, unless and until we make another layer option.

BTW @monfera I don't see a place for sankey and table traces here - I guess they will end up on top of pies (ie on the top of _fullLayout._paper) but seems like their relative ordering might be uncontrolled? We really need to refactor this section to more flexible while still yielding a consistent layer structure (including within one trace type if traces are added out of order)...

monfera commented 6 years ago

@alexcjohnson pie was one of the models after which I patterned parcoords and therefore the subsequent plots I worked on so your conclusion looks valid. Re the larger point, here are some trivialities as the only thing I have atm 😄 If we want to control Z stacking of an arbitrary number and variety of plots/traces, including some that are of the same type, there's got to be a way for specifying that fully in the API. Two examples:

  1. Have some zorder or depth that's a scalar number
  2. Implicit ordering based on the order of specification, analogous to SVG painter's algo

I like explicit more, because it retains the flexibility temporally, ie. you can insert a middle layer when you already have some layers. It's also doable with SVG painter's algo as the DOM lets you insert a new node before any preexisting element, so it's painter's algo from a DOM scenegraph viewpoint but retains temporal reconfigurability by virtue of an editable DOM tree.

Layering isn't that simple, as sometimes you want data ink to follow some Z stacking but the corresponding annotations follow a different or even unrelated stacking, eg. all grids go to the bottom and all highlights come to the top. Similarly, just because there are some line charts in a stack, it doesn't mean that all should go below or above something else; ie. ordering ideally supports arbitrary layering of traces of arbitrary variety.

It looks impossible to automate that (for it is a design question and depends on particulars of data and annotations). Luckily, if iayered graphs are called for, the maker usually has a good idea for the desired design, either off the bat or after seeing some results. Of course there can still be sensible defaults as per plotly.js user-facing architecture.

For these reasons it'd be neat to reconsider the role of dedicated layers we have now, and permit flexibility, in a similar vein to how the DOM itself provides it (and DOM-oriented approaches eg. react.js). It'd be a lot of work as currently, all plots hardcode certain DOM layers. So if it's eventually undertaken, it'd be good to do it such that some type of composition is enabled. For example, we have a table trace type, or hover tooltips, but we can't place plots into table cells or hover tooltips because plots rely (for a lot of things, none of which inherently inevitable) on graphDiv which isn't SVG and composition is eliminated, despite the plots' use of SVG.

With WebGL, as we discussed together, there's the problem of resource management, ie. a max of 16 gl contexts in the browser, so our conclusion was to have but a few, sometimes full screen sized (dashboard sized) gl layers and sharing these across all WebGL user plots, and the z-order would be provided by the drawing order (basically, using the rendering techniques of games and modeling: 1) start with opaque, from nearby to far, to save the expense of drawing occluded fragments; 2) continue with blending in translucent elements from far to near, if any.

We don't have that now, but Canvas2d is more flexible in that there's no fixed limit of <canvas> element count.