plotly / plotly.js

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

enable control of rendering order in stacked area charts (line colors) #6579

Open andrzej-r opened 1 year ago

andrzej-r commented 1 year ago

I am plotting a stacked area chart showing (positive y side) power consumption "from grid" (red) and "from solar" (orange) - in this order. Note that on the left-hand side of the chart, (non-zero red and zero orange), the red area is has an orange outline. While it is reasonable, taking into account that red area is rendered before orange, it is not visually appealing and can be confusing to the user.

Screenshot_2023-04-23_11-17-22

A preferred solution would be to somehow render the chart top-down (I do realize that both the stacking mechanism and tonexty fill currently depend on a bottom-up rendering order). In the example above, that would allow red outlines to be rendered last, covering zero areas above them.

I am using Plotly Graph Card for Home Assistant, so I do not have a JS code to include. I can provide source YAML code if that helps.

JamesNK commented 10 months ago

I have the same problem with stacked area charts. The zero value line of the topmost stack is displayed for zero values.

I found a hack to fix this:

function fixTraceLineRendering(chartDiv) {
    // In stack area charts Plotly orders traces so the top line area overwrites the line of areas below it.
    // This isn't the effect we want. When the P50, P90 and P99 values are the same, the line displayed is P99
    // on the P50 area.
    //
    // The fix is to reverse the order of traces so the correct line is on top. There isn't a way to do this
    // with CSS because SVG doesn't support z-index. Node order is what determines the rendering order.
    var parent = chartDiv.querySelector(".scatterlayer");

    if (parent.childNodes.length > 0) {
        for (var i = 1; i < parent.childNodes.length; i++) {
            parent.insertBefore(parent.childNodes[i], parent.firstChild);
        }
    }
}

Reversing the trace nodes changes the render order so that the bottom lines appear above top lines when they overlap (zero values). It would be nice to have the reverse order to be the default, or a setting for this behavior. The SVG hack above works, but it is a hack.

Kieran-Lynn commented 2 months ago

@gvwilson in case you havent seen this one, this may be a potential solution for the bug you picked up

https://github.com/plotly/plotly.js/issues/6138