chartjs / Chart.js

Simple HTML5 Charts using the <canvas> tag
https://www.chartjs.org/
MIT License
64.73k stars 11.92k forks source link

Is it possible to flip x & y view in LineChart? #7232

Closed ereborDeveloper closed 4 years ago

ereborDeveloper commented 4 years ago

I'm currently use vuechart-js wrapper, but it sends me to chartjs docs.

I create charts like this

chart (1)

But I need this. chart rotated For sure I can make it with CSS, but I can't rotate hover chart info, anyway it's not beautiful solution, is it?

I have lbl = [0, 0.1, 0.2, 0.3 ...] with fixed step for X-axis and some unpredictable data dt0 for Y-axis, but in fact it's just dotes. When I flip data in dataset..

labels: dt0,
                    datasets: [
                        {
                            label: 'W(q) (a/2; b/2)',
                            borderColor: 'rgb(255, 99, 132)',
                            data: lbl,
                            fill: false,
                            showLine: false
                        },

..I get this chart (2)

Is it possible to do that I need with Chart.js? Did I miss something? Thank you!

etimberg commented 4 years ago

@ereborDeveloper do you have a live sample of what you are trying to achieve? Have you tried setting reverse: true on the axis settings? https://www.chartjs.org/docs/latest/axes/styling.html#tick-configuration

ereborDeveloper commented 4 years ago

@etimberg sure. Here is sample of Vue.js code. It's LineChart, wrapped for Vue.js, so I can set options in :options bind object.

    <line-chart
                ref="chart"
                :chart-data="deflection"
                :options="{
                    scales: {
                        xAxes: [{
                            ticks: {
                                maxTicksLimit:10,
                                beginAtZero: true,
                            },
                            scaleLabel: {
                                display: true,
                                labelString: 'q'
                            }
                        }],
                        yAxes: [{
                            ticks: {
                                beginAtZero: true,
                            },
                            scaleLabel: {
                                display: true,
                                labelString: 'W'
                            }
                        }]
                }}"
    ></line-chart>

Here is JS data, used for chart creation (showed at first screen in post):

this.deflection = {
                    labels: lbl,
                    datasets: [
                        {
                            label: 'W(q) (a/2; b/2)',
                            borderColor: 'rgb(255, 99, 132)',
                            data: dt0,
                            fill: false,
                            showLine: false
                        }
                    ]
                };

I already tried reverse: true at axis, but it's not that I'm looking for. Chart must starts from left bottom part of the screen (from 0/0). It's live refreshing, so I get pairs of values:

{
0: 0,
0.01: 0.000123,
0.02: 0.000234,
0.03: 0.000345
...
etc
}

Bassicaly it's discrete y=f(x) function.

I need show x-value (0, 0.01, 0.02... with fixed step) at y-axis, and y-values at x-axis, but not like third screen in post.

I need fixed step for x-axis and chart like this: image Maple screenshot

But y-values which I need to handle with x-axis are not with fixed steps, that's the issue.

benmccann commented 4 years ago

To switch x and y we call that a "horizontal" chart. E.g. see horizontal vs regular bar chart here: https://www.chartjs.org/samples/latest/

Currently only bar charts can be horizontal. We started to allow it for any chart type, but the work wasn't completed. See https://github.com/chartjs/Chart.js/pull/7144

ereborDeveloper commented 4 years ago

@benmccann @etimberg so sorry for bothering you. I found in Scatter docs, what we got {x: value, y: value} dots, so I just switched them and it works.

Here is my data update method:

            fillData() {
                let json = [];
                this.dt0 = [];
                this.dt1 = [];
                for (var k in this.chartData) {
                    let w0 = this.chartData[k][0];
                    let w1 = this.chartData[k][1];
                    if (w0 > this.maxW) {
                        w0 = this.maxW;
                    }
                    if (w0 < this.minW) {
                        w0 = this.minW;
                    }
                    if (w1 > this.maxW) {
                        w1 = this.maxW;
                    }
                    if (w1 < this.minW) {
                        w1 = this.minW;
                    }
                    var ob = {q: k, W: [w0, w1]};
                    json.push(ob)
                }
                json.sort(function (a, b) {
                    return a.q - b.q;
                });
                for (let obj in json) {
                    const q = Number(json[obj].q).toFixed(2);
                    if (q >= this.minQ && q <= this.maxQ) {
                        this.dt0.push({x: json[obj].W[0], y: q});
                        this.dt1.push({x: json[obj].W[1], y: q});
                    }
                }
                this.deflection = {
                    datasets: [
                        {
                            label: 'W(q) (a/2; b/2)',
                            borderColor: 'rgb(255, 99, 132)',
                            data: this.dt0,
                        },
                        {
                            label: 'W(q) (a/4; b/4)',
                            borderColor: 'rgb(99, 255, 132)',
                            data: this.dt1,
                        }
                    ]
                };
            }

And here is some visual image

etimberg commented 4 years ago

Ah, perfect @ereborDeveloper. I was going to recommend the scatter chart. You can use the x & y axis options to control how the ticks are generated if you want different steps