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

X-axis labels #51

Closed focussing closed 1 month ago

focussing commented 1 month ago

Hi @graphieros how are you?

Just finalizing the current vue-data-ui graph. I have this large dataset (500+ datapoints) which holds the date to be used as X-axis labels. When I show all x-axis labels it is a thick line so I want to reduce the number of labels, which are spread over the X-axis evently related to the datapoints.

How can I do that?

Best regards, Raymond

graphieros commented 1 month ago

Hi @focussing :)

If you are using VueUiXy, you can set the following config attribute:

chart.grid.labels.xAxisLabels.showOnlyFirstAndLast: true

For now this is the only way. As usual your questions point me to the right modifications I need to make. I've been thinking of adding another attribute to only show xAxis labels at a given modulo to avoid this undesirable effect. Will keep you posted.

Cheers:)

graphieros commented 1 month ago

@focussing

You can upgrade to v2.2.56.

Set the following config attributes:

config.chart.grid.labels.xAxisLabels.showOnlyAtModulo: true,
config.chart.grid.labels.xAxisLabels.modulo: 60, // looks like this would be consistent with your dataset, or maybe 30

This cannot work if showOnlyFirstAndLast is also true, this one needs to stay false as it is in its default configuration.

Let me know if this works for you!

focussing commented 1 month ago

Hi @graphieros, it surely works.

This was the situation: image

And now this: image

This is much better. Maybe the lowest and highest x-value could be displayed, and the remaining space divided (like css-flex space-between).

Another question: why is the X-axis not part of the dataset? Now I need to update it like this: config.value.chart.grid.labels.xAxisLabels.values = x;

graphieros commented 1 month ago

@focussing,

X-axis part of the config instead of the dataset is a legacy thing, changing that would constitute a breaking change I don't wish to risk as of now. I hope it's not a huge inconvenience for you.

I need to see if I can make modulo work in the way you proposed. In the meantime, maybe your modulo value can be a fraction of the datapoint with the biggest length, to which you add 1 to show the last x axis value.

modulo: Math.floor((biggestLen + 1) / n)

focussing commented 1 month ago

That is enough to add 1. Maybe you can look at the rightmost label of my first graph. The date is truncated. Does the canvasXy work similarly?I need to switch to that one because when using 2000+ datapoints the XY becomes slow… Verstuurd vanaf mijn iPhoneOp 17 aug 2024 om 18:02 heeft Alec Lloyd Probert @.***> het volgende geschreven: @focussing, X-axis part of the config instead of the dataset is a legacy thing, changing that would constitute a breaking change I don't wish to risk as of now. I hope it's not a huge inconvenience for you. I need to see if I can make modulo work in the way you proposed. In the meantime, maybe your modulo value can be a fraction of the datapoint with the biggest length, to which you add 1 to show the last x axis value.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>

graphieros commented 1 month ago

There are three ways to solve the cropping issue:

  1. Add right padding to the config

  2. rotate xAxisLabels (rotation attribute to a -20 value for example), and add some bottom padding to the configuration too so that it does not crop on the bottom (and most probably some left padding too). When rotated to the left, text elements for the xAxisLabels have a text-anchor set to 'end', when rotated to the right, it is set to 'start', so that the first or end letter is the closest to the intersection.

  3. target the css element and force its overflow-x to visible.

Using VueUiXyCanvas, 12 labels will be visible when max datapoint len > 12. You'll need to rotate labels too, as dates are long strings of chars. Let me know how it goes, and if more customization is required on this one. At least first and last values will always be visible on this chart, its conception is very different.

Edt: I changed my mind, I'm adding a config attribute to manage the number of labels in VueUiXyCanvas, because this fixed 12 is bothering me

graphieros commented 1 month ago

Ok you can upgrade to v2.2.58, which allows you to specify the number of time labels you want to display on VueUiXyCanvas

config.style.chart.grid.y.timeLabels.modulo: number; // default: 12

Any truncating issue with labels should be manageable by tweaking the padding attributes (and / or rotating labels).

focussing commented 1 month ago

It is not clear to me how the modulo property works. The user can select a number of datapoints; for example every 5s a log is made, so for one hour 720 datapoints is needed. I would like to have 6 intervals, so 7 date items on the X-axis, whereas the first is the most left item and last date is the most right item. How can I calculate the needed modulo value?

graphieros commented 1 month ago

Hi @focussing :)

I guess you are using VueUiXyCanvas ? If yes, have you tried setting modulo: 7 ?

focussing commented 1 month ago

No I still use VuiUiXy for a final release of the current 4 machines in the field. Tomorrow I will start taking a look at VueUiXyCanvas, because of the larger number of datapoints (currently 2000 takes 4 seconds to load).

For 500 datapoints I found that a value of 6 or 7 look very nice.

image

graphieros commented 1 month ago

Looks very nice indeed :) Unfortunately since xy uses svg, too many dom nodes slow down the rendering. It should be faster with canvas, which is ok with 10k datapoints on slow devices, and can manage 100k datapoints on a good machine, but then reaching JS limits... so in short you should be good. Let me know if you have all you need on canvas, I tried my best to apply all features our discussions lead to on xy.

focussing commented 1 month ago

Thanks! The image above is VueUiXy using module value of 6. What formula should I use to get the right value for other number of datapoints?

graphieros commented 1 month ago

Ok I need to test some stuff, I just came back

graphieros commented 1 month ago

You can try setting your modulo attribute using this function:

function getNumberOfLabels({datasetLength, lowerLimit, upperLimit}) {
    if (lowerLimit < 1) {
        lowerLimit = 1;
    }

    for (let i = lowerLimit; i <= upperLimit; i += 1) {
        if (datasetLength % i === 0) {
            return i;
        }
    }

    if (datasetLength > upperLimit) {
        return upperLimit;
    }

    return datasetLength;
}
getNumberOfLabels({
    datasetLength: 720,
    lowerLimit: 6,
    upperLimit: 10
  }) // result: 6

getNumberOfLabels({
    datasetLength: 313,
    lowerLimit: 6,
    upperLimit: 10
  }) // result: 10