leeoniya / uPlot

📈 A small, fast chart for time series, lines, areas, ohlc & bars
MIT License
8.51k stars 371 forks source link

Dynamic y-shifted series #428

Closed GoodMorgon closed 3 years ago

GoodMorgon commented 3 years ago

Hello,

I'm trying to replicate https://leeoniya.github.io/uPlot/demos/y-shifted-series.html but where I have a button for toggling between a 'shifted y series' mode as in the example and a normal shared y-series between my series.

Is there any way I can edit the axes[] and scales[] dynamically as needed? Or is the only way to first destroy() the plot and recreate it with new options?

Thanks

leeoniya commented 3 years ago

can you show me your current config?

GoodMorgon commented 3 years ago
function getSize() {

    return {
            width: document.getElementById('chart-view').offsetWidth,
            height: document.getElementById('chart-view').offsetHeight - 30
           }

}

let opts = {
            id      : 'uplot_chart',
            class   : 'uPlot',
            ...getSize(),
            scales  : {
                       x : {time: true},
                       },
            gutters : {
                       x : 0,
                       y : 0
                      },
            axes    : [
                       {
                        grid : {
                                width: 0.5,
                                stroke: 'rgba(2, 128, 0, 0.5)'
                               }
                       },
                       {}
                       ],
            series  : [
                       {
                        value: function (self, rawValue) {

                            let val = dayjs.unix(rawValue).tz()

                            if (val.hour() === 0 && val.minute() === 0) return val.utc().format('YYYY-MM-DD')
                            return val.utc().format('YYYY-MM-DD HH:mm:ss')

                        },
                        key: 'date'
                       }
                      ]
            }

this.chart = new uPlot(opts, null, document.getElementById('chart'))

:)

leeoniya commented 3 years ago

this doesn't tell much at all.

the demo you're referencing has y-series definitions [1], but your code has none. in the demo, series.value and series.fillTo functions would need to return different things based on whether you're in shifted mode or not. the same goes for axis.values and the actual data.

https://github.com/leeoniya/uPlot/blob/master/demos/y-shifted-series.html#L42-L66

GoodMorgon commented 3 years ago

Yes.

My concern is how can I change the axes[] and scales[] definitions. I meant to ask before starting to code any possible solutions.

The current options is for a 'standard' shared y-axis solution, but how can it become like the demo with y-series definitions and added axes[] without recreating the plot from scratch? I don't know (I've checked the docs but there doesn't seem to be a set api for the axes and scales).

Recreating the plot when shifting between the two 'modes' seems unnecessarily heavy for the task.

leeoniya commented 3 years ago

it was easier to just add it to the demo instead of explaining it here :D

https://leeoniya.github.io/uPlot/demos/y-shifted-series.html

vinnitu commented 1 year ago

What is Core #4 in your example if we have only 3 series? (Core #1, Core #2 and Core #3)

image

vinnitu commented 1 year ago

and what about different ranges? and autoscale by y-asix every serie? Very useful functionaliry in general

leeoniya commented 1 year ago

every Core label is a 0 value of that series and also the 10 value of the series below it. you can change the labels to something else.

autoscaling can be done by adjusting a lot of the demo code (similar to the stacking demos) but is likely a bad idea, since the y range becomes difficult to interpret at a glance.

vinnitu commented 1 year ago

Often the user needs to see a column of charts with the same time domain. In this case it is better to display one time axis at the bottom of column. But in my case all charts have same width with shared crossline cursor. That is why I look at this (shifted-y) example as start point.

leeoniya commented 1 year ago

take a look at Inverted Log10 Y Scale demo here: https://leeoniya.github.io/uPlot/demos/log-scales2.html

it uses two charts with a synced cursor and hides the x axis on the top chart to show different ranges it also does some DOM manip during init to combine the legend from both. this strategy might work better for you.

vinnitu commented 1 year ago

but there are two different charts, and I don't like magic DOM manipulation like image

I can't even imagine what needs to be done for 8 charts... (It is real case)