graphieros / vue-data-ui

A user-empowering data visualization Vue 3 components library for eloquent data storytelling
https://vue-data-ui.graphieros.com/
MIT License
267 stars 13 forks source link

usage question: multiple y-axes #25

Closed focussing closed 4 months ago

focussing commented 4 months ago

Hello!

Following your great progress regarding this library!

One question, would something like this be possible using your library? So basically a number of line graphs of which the scales are quite different.

Looking forward to hearing from you!

logging2cropped

graphieros commented 4 months ago

Hey :)

Thanks for your comment!

Multiple scales for Y axis is not currently part of the possibilities in the VueUiXy component.

It was initially an opinionated choice, as multiple scales can be missread by chart users, and is not necessarily recommended, the alternative being to display as many charts as there are scales.

However, looking at the example you posted is inspiring me to reconsider, as drawing correlations between datasets does look much easier this way. I also like the fact that Y Labels are all stacked on the side (I really dislike charts were Y Labels with different scales are on both sides), making it possible to display n different scales easily.

Will keep you posted on this feature.

Cheers

P.S. One opinion I will keep, though, is that scales must start at 0.

graphieros commented 4 months ago

Hey again:)

v2.1.52 adds optional multiple Y scales to the VueUiXy component.

On scales mouseover, the concerned series is highlighted, and related horizontal lines are visible on the chart.

Thanks again for the inspiration @focussing !

focussing commented 4 months ago

Hey @graphieros, that was quick, thanks a lot!

Of cource I immediately tried, but somehow I made an error. This is what is shown. The console shows VueUiXy dataset prop is either missing, undefined or empty. The config is the default one, and it works because I see a legend and title.

image

graphieros commented 4 months ago

@focussing is there a way you can show me the implementation of the component where you're using VueUiXy ? From what I see, the dataset logged at the bottom of the screenshot appears to be compliant.

Is your dataset passed as prop a computed property ? When selecting datapoints from the checkboxes, some reaction seems to not be derived in the component state, but that's only a guess from the screenshot.

focussing commented 4 months ago

The dataset is passed as a prop: <VueUiXy :dataset="dataset" :config="config" />

Datapoints are read from a database. If I check the boxes, only the data of the selected item like P-01 etc is taken into the series. The series are then also updated on the screen.

This is the template code.

<template>
    <div>
        <div class="flex">
            <!-- logitem selection -->
            <div class="w-1/12 mt-6 text-sm">
                <p>outputs</p>
                <label class="text-gray-700 flex items-center" v-for="(n, i) in 14">
                    <input type="checkbox" value="" v-model="io[i]" />
                    <span class="ml-1"> {{ state.io.outputNames[n - 1] }}</span>
                </label>
                <p class="mt-2">inputs</p>
                <label class="text-gray-700 flex items-center" v-for="(n, i) in 14">
                    <input type="checkbox" value="" v-model="io[i + 14]" />
                    <span class="ml-1"> {{ state.io.inputNames[n - 1] }}</span>
                </label>
            </div>

            <!-- chart -->
            <VueUiXy :dataset="dataset" :config="config" />
        </div>

        {{ dataset }}
    </div>
</template>

If I remove everything from the templateexcept <VueUiXy> the graph shows via HMR, but disappears again after a browser reload.

image

The scaling however is not very nice though...

graphieros commented 4 months ago

Try adding a key to the component, which gets incremented whenever the server changes the dataset.

const step = ref(0)

and in your template:

<VueUiXy 
  :key="`step_${step}`" 
  :dataset="dataset"
  :config="config"
/>

The scaling does fit your dataset, what do you mean by 'not very nice' ?

focussing commented 4 months ago

The step helps, only not the first time after reload. Initially the dataset is empty. let dataset = ref([]);

With 'not very nice' I mean that the 'B-01' graph's scale is from 0 to 3, I would expect to be it from 2 to 3. As both P-01 and B-01 are outputs of a board, they are either 0 or 1 and would be on top of eachother. I give all added graphs an Y offset.

I mean this as implemented with ApexCharts (which does no treeshaking so I dont want to use it).

image

graphieros commented 4 months ago

If your dataset is empty, you should consider displaying the chart if dataset.length, and have a placeholder with a message indicating to pick datapoints.

As for the scales, I see now what you mean. I could think of adding an additional optional attribute in the dataset items, to force the minimum on scales. I wanted all scales to be 0 based, because I dislike charts that tamper with scales to force interpretations. However, your use case is very specific, and I understand the need for further options.

I'll keep you posted:)

focussing commented 4 months ago

The v-if="dataset.length" works perfectly, also the "step" key can be removed.

I was thinking how to deal with overlapping graphs. As in the above image this is not so nice as I removed the Y-scale which is not userful when combining digital (0/1) graphs with analog graphs like temperature or similar. In the case of digital graphs it would be shown like this, but that is not very clear. Do you have an idea of how to solve this? Maybe give it an y-offset while keeping it's original scale?

image

graphieros commented 4 months ago

I'm working on a solution that can combine specific scales for each datapoint.

For use cases where datapoints are binary types (0 -1; 2-3; etc) :

image

and combined with a temperature datapoint:

image

The idea is to set a scaleMax to eachDatapoint (basically the last item with the highest binary type, with 2 series, it would be 3).

So basically analog & binary sets can coexist in this format.

graphieros commented 4 months ago

@focussing you can upgrade to v2.1.54 to try it out.

Your dataset should have this shape:

const dataset = [
  {
    name: "S1",
    series: [0, 1, 1, 1, 1, 0, 0, 0],
    type: "line",
    scaleMax: 3,
    scaleSteps: 4 // or dataset.length * 2 to make binary scales nice
  },
  {
    name: "S2",
    series: [2, 3, 3, 3, 2, 2, 3],
    type: "line",
    scaleMax: 3,
    scaleSteps: 4 // or dataset.length * 2 to make binary scales nice
  }
]

You just need to set scaleMax to your highest binary value.

Additional analog datapoints can be added to the dataset, and you can tweak the Y offset by adjusting scaleMax and scaleMin. (scaleMin is not necessary for binary sets in your use case).

focussing commented 4 months ago

That's for sure a nicer way than to have it hard coded in reading the datapoints like I had in my previous solution. However it is still showing a wrong scale eg. a binary value with a scaleMin of 2 and scaleMax of 4 which is not correct for a digital value. (That's why I would suppress the y-values in my ApexChart control.)

Maybe another option could be in the direction of this ? Think of an yScaleOffset related to the plot-area which does not alter the scale itself but only and offset in the y-direction to position the graph (including its's individual scale) above others.

By the way, how did you calculate the y-scaler in earlier versions? In an automated way?

graphieros commented 4 months ago

Are you saying that you need binary scales to always be 0 - 1, but be displayed at custom offsetY ? So your binary datasets would always be comrpised of 0 and 1, and never incremented as you previously showed me ?

A scaleOffset datapoint attribute can be a possibility, I'll think about that. It must move the scale along with the chart on the Y axis.

The scales are computed through a calculateNiceScale function, if you are curious, you can find it here on L.831

PS. I think what you really need is that no series overlap, each have an individual Y area which is height / dataset.length, with some additional gap between. Like this

image

focussing commented 4 months ago

Yes, the binary scale is always 0-1 and it might be a good idea to display it at custom offetY. I incremented the values so the different graphs would not overlap as shown in the graphs above.

Yes you state it very clear; no series should overlap (or make that a setting to stack or spread series or something like that).

PS. I added some anlog values to the graph, the scale it uses is that correct in your opinion? image

graphieros commented 4 months ago

Clearly not. It is impossible to evaluate variations with these 2 sets sharing the same scale. But I think I have you covered with the next release. An additional "stacked" config option will give each datapoint its own scale and space on the chart, so individual variations & correlations will be easier to read.

focussing commented 4 months ago

Wow! @graphieros that would be great! And how fast you're responding :) Tomorrow I am out of the office, get back to you on next thursday. See you!!

graphieros commented 4 months ago

@focussing you can upgrade to v2.1.55 or latest to try out the stacked mode. I will add a use case on the docs website, but I think you got the idea :)

Additional config attributes in config.chart.grid.labels.yAxis:

stacked: boolean; // default: false
gap: number; // default: 64

Of course, it is still required to set config.chart.grid.labels.yAxis.useIndividualScale:true.

In your dataset, no need for you to use scaleMax and scaleMin anymore. You may need to set scaleSteps: 2 for binary sets, and what suits you better for analog series (5 should be enough, 10 might be overkill).

All datapoints types (bar, line, plot) will work in stack mode. You can also use useArea: true on datapoints for binary sets of type line, just to see if it looks any good.

focussing commented 4 months ago

Wauw @graphieros what a huge step you've made! This is how it looks like overhere: Scherm­afbeelding 2024-05-16 om 10 27 57

I get more and more exited about this! While thinking about the possibilities I have some ideas/remarks:

1) Above you talk about the scaleSteps, I assume that should be the commonScaleSteps property. 2) I see the y-axis but no x-axis line in the graphs, where should I enable that? 3) I tried to use your calculateNiceScale function for the "+24V" series and use the result from that to set the scaleMin and scaleMax per series but it still seems to use the zero-base.

Scherm­afbeelding 2024-05-16 om 10 19 45

4) Would it be an idea to make some kind of height property for stacked series? That way I could use scaleSteps:2 for digital series and set the height to smaller than for analog series like the "+24V". 5) The tooltip pointer is a bit wide, I was looking for a way of changing that and when I search it comes up with a 'tooltipCustomFormat' property, but when I click on that it does not give more information.

Best regards! Raymond

graphieros commented 4 months ago

Hi @focussing, it starts to look nice!

scaleSteps is a datapoint property you can use in the dataset to customize individual scales. For binary scales, it can be set to 2, as you'll never need intermediate anchors. Could you provide a sample dataset so I can test it ? Ideally the same shape as your first screenshoot. As a user, you shouldn't have to tweak the scales, it should be right out of the box.

As for customizing tooltips, you need to use the

config.chart.tooltip.customFormat

customFormat: ({ seriesIndex, datapoint, series, config, bars, lines, plots }) => {
    // use args to build your custom content,
    const content = "My custom content";
    return `<div>${content}</div>` // use any styles you need here
}

This callback exposes the data from the hovered X.

FInally, as for x axis lines, I think your dataset might be too large for them to be relevant. Currrenty they are drawn on each X segment. I need to provide an additional config option with custom divisions.

focussing commented 4 months ago

Hi Alec,

Thanks! That is only because of your good work :)

1) scalestep: you are completely right.

2) I did not define an x-axis, this is in fact the (same) logging timestamp for every point in all series. Currently I fetch 100 items from the logging database. In a stacked situation maybe only the bottom one would be sufficient to keep the total overview clean. Maybe it is possible to show the x-axis timestamp in the tooltip?

3) I agree that the scale should be right out of the box, I just used your "nice" function to test scaleMin and scaleMax. But it seems not to help overhere in my situation. This is the dataset. [ { "name": "P-01", "series": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ], "type": "line", "scaleMin": 0, "scaleMax": 1 }, { "name": "AV-01", "series": [ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "type": "line", "scaleMin": 0, "scaleMax": 1 }, { "name": "AV-03", "series": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "type": "line", "scaleMin": 0, "scaleMax": 1 }, { "name": "FB-AV-03", "series": [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], "type": "line", "scaleMin": 0, "scaleMax": 1 }, { "name": "+24V", "series": [ 23.997080078124995, 23.960610351562497, 24.006197509765624, 23.997080078124995, 24.006197509765624, 23.960610351562497, 24.024432373046874, 23.969727783203123, 24.006197509765624, 23.94237548828125, 23.987962646484377, 23.987962646484377, 24.070019531249997, 24.2523681640625, 23.94237548828125, 24.006197509765624, 23.951492919921876, 23.960610351562497, 24.142958984375, 24.060902099609372, 23.987962646484377, 24.060902099609372, 24.033549804687496, 23.969727783203123, 23.960610351562497, 23.951492919921876, 23.987962646484377, 24.01531494140625, 23.94237548828125, 23.951492919921876, 23.969727783203123, 24.070019531249997, 23.951492919921876, 23.951492919921876, 23.951492919921876, 23.94237548828125, 23.978845214843748, 23.969727783203123, 23.978845214843748, 23.969727783203123, 23.93325805664062, 24.179428710937497, 23.997080078124995, 24.006197509765624, 23.978845214843748, 23.951492919921876, 23.951492919921876, 23.987962646484377, 23.997080078124995, 23.969727783203123, 24.01531494140625, 23.94237548828125, 23.951492919921876, 23.997080078124995, 23.960610351562497, 23.94237548828125, 23.978845214843748, 24.01531494140625, 24.106489257812495, 23.987962646484377, 23.960610351562497, 24.106489257812495, 23.987962646484377, 24.006197509765624, 23.987962646484377, 23.969727783203123, 23.969727783203123, 23.969727783203123, 24.006197509765624, 24.01531494140625, 23.987962646484377, 23.978845214843748, 24.01531494140625, 23.987962646484377, 24.024432373046874, 24.006197509765624, 23.960610351562497, 24.04266723632812, 23.997080078124995, 24.01531494140625, 24.033549804687496, 23.969727783203123, 24.024432373046874, 24.033549804687496, 23.960610351562497, 23.960610351562497, 23.978845214843748, 24.006197509765624, 23.969727783203123, 24.088254394531248, 24.033549804687496, 23.978845214843748, 24.024432373046874, 23.997080078124995, 24.024432373046874, 24.097371826171873, 23.997080078124995, 24.033549804687496, 24.01531494140625, 23.987962646484377 ], "type": "line", "scaleMin": 23.8, "scaleMax": 24.400000000000002 } ]

4) Series height; I hope this might be something to consider because digital series should only be small so the user is able to show a whole bunch of signals like in a logic analyser. Maybe a smart default (if no height is given) could be to equally divide the remaining vertical part of the graph between the series without having this height set or something like that?

5) Hm the custom tooltip example gives a syntax error, and a width property in the .vue-data-ui-custom-tooltip class is probably to easy It behaves really nice using the default, but I would like to see a small line instead of it covering the whole datapoint "width". Maybe a little bit of an example would be helpful.

6) Is the aspect ratio of the component fixed?

graphieros commented 4 months ago

Thanks for sharing a sample I can play with.

Managing individual series height is manageable, maybe through an additional datapoint attribute stackedHeightRatio (0 to 1), and must work with defaults (remainingHeight / series.length without custom height ratio).

You can manage aspect ratio using config.chart.width (default: 500) and config.chart.height (default: 300), which set the svg viewBox.

I'll provide an example of customFormat for the tooltip asap.

I'll keep you posted.

graphieros commented 4 months ago

Hi @focussing ! You can try out v2.1.62

What you need to do on your dataset:

From the dataset you sent me, this is how it should be setup:

[
  {
    name: "P-01",
    series: [0, 1, ...],
    type: "line",
    scaleSteps: 2
  },
  {... other binary sets },
  {
    name: "+24V",
    series: [ 23.997080078124995, ...],
    type: "line",
    scaleSteps: 5,
    autoScaling: true,
    stackRatio: 0.6
  }
]

As for xAxis, I added chart.grid.labels.xAxis.showBaseline which is true by default.

As for custom tooltip, here is a working implementation:

set config.chart.tooltip.customFormat as follows:

customFormat: ({ datapoint }) => {
   let html = "";
   datapoint.forEach(d => {
     html += `<li>${d.name} : ${d.value}</li>`
    })
    return `<ul>${html}</ul>`
}

This will just show a basic ul but you can style your wrapper as you wish.

focussing commented 4 months ago

Hi @graphieros !

What a huge update again :) You are amazing!

This is the result until now: Naamloos

I used for the 2 analog series a stackRatio of 0.3 and left the digital series undefined. I can almost add unlimited number of digital series, of course until the graph becomes useless. The xAxis baseline also works beautifully!

A few remarks: 1) With this dataset the analog series's auto-scaling shows a bit too tight. It looks as it is zoomed in maximally. I tried a few combinations to "zoom out", and tried to set autoScale: false and set scaleMin and scaleMax but that is not working anymore. With for example a slider I would be able to implement a kind of "y-axis zoom" function. Are these properties not available anymore? 2) The tooltip is nicely adaptable, thank you for the example. I can show the tooltip values for the analog series with 2 digits now (although I cannot get that beautiful tooltip styling as you provide standard out of the box). The same goes for showing the x-value, eg. like a timestamp (when defined in the dataset) or the index number otherwise (see my old graph below). I probably phrased my question not correct; how can I change the style of the "gray cursor block".

Naamloos2

I used this as dataset so you would be able to get the same result. Sorry I cannot give you access to the system because it is behind a VPN.

[ { "name": "P-01", "series": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ], "type": "line", "autoScaling": true, "scaleSteps": 2 }, { "name": "B-01", "series": [ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 ], "type": "line", "autoScaling": true, "scaleSteps": 2 }, { "name": "B-02", "series": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "type": "line", "autoScaling": true, "scaleSteps": 2 }, { "name": "AV-01", "series": [ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "type": "line", "autoScaling": true, "scaleSteps": 2 }, { "name": "AV-02", "series": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "type": "line", "autoScaling": true, "scaleSteps": 2 }, { "name": "FB-AV-03", "series": [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], "type": "line", "autoScaling": true, "scaleSteps": 2 }, { "name": "+24V", "series": [ 23.997080078124995, 23.960610351562497, 24.006197509765624, 23.997080078124995, 24.006197509765624, 23.960610351562497, 24.024432373046874, 23.969727783203123, 24.006197509765624, 23.94237548828125, 23.987962646484377, 23.987962646484377, 24.070019531249997, 24.2523681640625, 23.94237548828125, 24.006197509765624, 23.951492919921876, 23.960610351562497, 24.142958984375, 24.060902099609372, 23.987962646484377, 24.060902099609372, 24.033549804687496, 23.969727783203123, 23.960610351562497, 23.951492919921876, 23.987962646484377, 24.01531494140625, 23.94237548828125, 23.951492919921876, 23.969727783203123, 24.070019531249997, 23.951492919921876, 23.951492919921876, 23.951492919921876, 23.94237548828125, 23.978845214843748, 23.969727783203123, 23.978845214843748, 23.969727783203123, 23.93325805664062, 24.179428710937497, 23.997080078124995, 24.006197509765624, 23.978845214843748, 23.951492919921876, 23.951492919921876, 23.987962646484377, 23.997080078124995, 23.969727783203123, 24.01531494140625, 23.94237548828125, 23.951492919921876, 23.997080078124995, 23.960610351562497, 23.94237548828125, 23.978845214843748, 24.01531494140625, 24.106489257812495, 23.987962646484377, 23.960610351562497, 24.106489257812495, 23.987962646484377, 24.006197509765624, 23.987962646484377, 23.969727783203123, 23.969727783203123, 23.969727783203123, 24.006197509765624, 24.01531494140625, 23.987962646484377, 23.978845214843748, 24.01531494140625, 23.987962646484377, 24.024432373046874, 24.006197509765624, 23.960610351562497, 24.04266723632812, 23.997080078124995, 24.01531494140625, 24.033549804687496, 23.969727783203123, 24.024432373046874, 24.033549804687496, 23.960610351562497, 23.960610351562497, 23.978845214843748, 24.006197509765624, 23.969727783203123, 24.088254394531248, 24.033549804687496, 23.978845214843748, 24.024432373046874, 23.997080078124995, 24.024432373046874, 24.097371826171873, 23.997080078124995, 24.033549804687496, 24.01531494140625, 23.987962646484377 ], "type": "line", "autoScaling": true, "scaleSteps": 10, "stackRatio": 0.3 }, { "name": "+5V", "series": [ 4.966513671875, 5.032822265625, 4.98806396484375, 4.96817138671875, 4.9698291015625005, 4.99469482421875, 5.0112719726562505, 4.993037109375, 4.9764599609375, 5.02453369140625, 4.993037109375, 4.9764599609375, 4.966513671875, 4.98640625, 4.98474853515625, 4.96817138671875, 5.02619140625, 4.98143310546875, 4.97148681640625, 5.02453369140625, 5.02619140625, 4.97480224609375, 4.98474853515625, 4.9698291015625005, 4.96817138671875, 4.97148681640625, 4.966513671875, 4.97811767578125, 4.9631982421875, 5.0029833984375, 4.97314453125, 4.9764599609375, 5.02619140625, 4.97148681640625, 4.9764599609375, 4.97811767578125, 4.9830908203125, 4.96817138671875, 4.96817138671875, 4.97811767578125, 4.9698291015625005, 4.98640625, 4.96817138671875, 4.979775390625, 4.96817138671875, 4.97148681640625, 4.98640625, 4.9698291015625005, 4.9897216796875, 4.96817138671875, 4.97314453125, 4.979775390625, 4.97314453125, 4.97314453125, 4.97148681640625, 4.97148681640625, 4.97148681640625, 4.96817138671875, 4.97314453125, 4.98474853515625, 4.9698291015625005, 4.966513671875, 4.97314453125, 4.9631982421875, 4.97480224609375, 4.97314453125, 4.96485595703125, 4.96817138671875, 4.97148681640625, 5.02453369140625, 4.966513671875, 4.97480224609375, 4.96485595703125, 4.97811767578125, 4.966513671875, 4.97148681640625, 4.9764599609375, 4.98143310546875, 4.96817138671875, 4.97811767578125, 4.98143310546875, 4.96154052734375, 4.97811767578125, 4.97314453125, 4.97148681640625, 4.9698291015625005, 4.9698291015625005, 4.966513671875, 4.97148681640625, 5.00795654296875, 4.966513671875, 4.96817138671875, 4.96817138671875, 4.966513671875, 4.966513671875, 4.97480224609375, 4.966513671875, 4.96817138671875, 4.9698291015625005, 4.966513671875 ], "type": "line", "autoScaling": true, "scaleSteps": 10, "stackRatio": 0.3 } ]

graphieros commented 4 months ago

Small variations in analog series are way more readable now:)

scaleMin & scaleMax are useless if autoScaling is set to true.

For your +5V serie you might consider setting a scaleSteps of 2. It will show a max at 5.1 and min at 4.9 Maybe it's also better to stick with 2 for all series, as variations are very small.

Available config options for the highlighter are available in:

config.chart.highlighter, but only color and opacity are available.

As for time labels, you can provide all time values in: config.chart.labels.xAxisLabels.values

However, with your huge dataset, it does not make sense to show them all. So either hide them with show: false, or use showOnlyFirstAndLast: true

If time values are added, the selected X will show the time value in the default tooltip. On your custom tooltip, as it exposes the seriesIndex, you can get your time label this way.

customFormat: ({ datapoint, seriesIndex }) => {
   let html = "";
   html += `<div>${myTimeLabels[seriesIndex]}</div>`;
   datapoint.forEach(d => {
      html += `<li><span style="color:${d.color}">⬤</span> ${d.name} : ${d.value}</li>`;
   });
   return `<ul>${html}</ul>`;
}

Using the default tooltip, you can also set config.chart.tooltip.roundingValue to 2. This config attribute is currently missing on the docs website.

Finally, the zoom slider should be visible by default (config.chart.zoom.show). Even though I'm not satisfied with the looks, it should work.

graphieros commented 4 months ago

@focussing check out v2.1.64, to use a timeTag, and have a vertical line when hovering the chart (set config.chart.highlighter.opacity to 0 and useLine to true)

focussing commented 4 months ago

Absolutely amazing! Works like a charm!

graphieros commented 4 months ago

Thanks:) As always I rushed a bit, so v2.1.64 is latest, contains a minor fix.

focussing commented 4 months ago

One small question for customer release; how did you setup (html) this beautiful tooltip? So I can use the same as start for custom tooltip incl update the analog series with 2 decimals.

focussing commented 4 months ago

Sorry found it!

tooltip.roundingValue:2

focussing commented 4 months ago

In general; where can I find the docs about for example all tooltip properties?

graphieros commented 4 months ago

You can check out the docs page under the config tab. It is now updated. All components have this tab, with inputs to play with config and copy either the default one, or the one you made.

You can also console.log the full default config object:

import { getVueDataUiConfig } from "vue-data-ui";
const xy_config = getVueDataUiConfig("vue_ui_xy");
focussing commented 4 months ago

Top!

focussing commented 2 months ago

Hello again!

Just to let you know that this week the first machine of my project will be assembled and next week introduced at one of the largest festivals in NL.

These 2 links show what it's all about:

https://www.bluelephant.global/ https://www.jotem.nl/oplossingen/bluelephant

I was pleasently surprised about the VueUiXyCanvas component. As we are gathering a lot of logging data this would be very important for us. One question versus the VueUiXy component; is the API similar for both components?

I use version 2.2.26 of VueUiXy and when I simply exchange VueUiXy by VueUiXyCanvas it is shown differently as shown below. When I update VueUiXy to the latest version I get some warnings in the console regarding stack (I reverted it right away for the time being because today I need a stable version).

image

versus

image

graphieros commented 2 months ago

Hello @focussing !

Your project looks awesome, I wish you a great success :)

This console warning you noticed does not affect the stability of the chart, and wrongly shows because it's linked to the wrong variables.

Unfortunately VueUiXyCanvas uses a different config API (SVG and canvas are very different when it comes to managing responsiveness) In its current state, it does not suit your specific requirements, as custom series height is not supported yet. I'm currently working on improvements.

graphieros commented 2 months ago

@focussing

You can upgrade to v2.2.31 which fixes the console warning minor issue.

Btw I noticed on your VueUiXy that your x axis labels are overlapping. It is possible to rotate them slightly to make them readable. And if rotation crops labels, you can increase bottom padding:

Rotating x axis labels:

config.chart.grid.labels.xAxisLabels.rotation: -20 // should do the trick

Padding bottom config attr:

config.chart.padding.bottom
graphieros commented 2 months ago

Hi @focussing :)

v2.2.35 implements for VueUiXyCanvas custom datapoint height with stackRatio, and autoScaling to visualize small variations on a datapoint.

Console warning issue on VueUiXy was fixed previously (see previous message).

API for dataset prop is the same as VueUiXy.

API for config prop is very different.

Here is a basic config you can use for VueUiXyCanvas:

    const config = ref({
        style: {
            chart: {
                stacked: true,
                stackGap: 20,
                dataLabels: {
                    show: false
                },
                line: {
                    plots: {
                        show: false
                    }
                }
            }
        }
    })

API documentation for VueUiXyCanvas is available here