Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a single dataset for line chart and I need to conditionally color the line based on Y value to show if thresholds are exceeded (from both top and bottom). And I can't figure out a proper approach to do so and I start to think that might not be possible without complex algorithm. I can't find any plugins, either.

What I have tried:

1) First approach is I've created an extension for line chart like this:

Chart.defaults.multicolorLine = Chart.defaults.line;
            Chart.controllers.multicolorLine = Chart.controllers.line.extend({
                draw: function (ease) {
                    const
                        meta = this.getMeta(),
                        points = meta.data || [],
                        colorss = this.getDataset().colorss,
                        area = this.chart.chartArea,
                        originalDatasets = meta.dataset._children
                            .filter(function (data) {
                                return !isNaN(data._view.y);
                            });

                    function _setColor(newColor, meta) {
                        meta.dataset._view.borderColor = newColor;
                    }

                    for (let i = 0; i < meta.dataset._children.length; i++) {
                        const slicer = i + 2;
                        if (meta.dataset._chart.config.data.datasets[0].data[i].y < 5) {
                            _setColor('yellow', meta);
                        } else {
                            _setColor('red', meta);
                        }
                        meta.dataset._children = originalDatasets.slice(i, slicer);
                        meta.dataset.draw();
                        meta.dataset._children = originalDatasets;
                    }

                    points.forEach(function (point) {
                        point.draw(area);
                    });
                },
            });  


and overall it SORTA do what it's supposed to but the problem with this approach is that it's CHART POINT related and often the change should be between the points so on the part of line where I have no measurement for Y value. So I've given up the idea and tried another one.


2) This approach is based on creating separate dataset for every changed color on the line so I just iterate over the dataset and if threshold is changed then I create another dataset e.g.:
[-3,-2,-1,0,1,2,3]
threshold is value has to be between [-1,1]
so I create 3 datasets:
[-3,-2], [-1,0,1], [2,3]

and I attach the correct color to every dataset. The problem with this approach is that the chart is empty between the measured points. The X axis is datetime and let's assume that -2 is 04/05/2020 and -1 is 05/05/2020 then there is an empty space between 04/05/2020 and 05/05/2020. And even if there would be an option to artificially approximate the missing line, there would be again the same problem, the approximated line would have to be 50% green and 50% red which is just the assumption of where crossing the edge condition should be.

My question is should I just give up the Chart.Js and use something different? If so then what library provides such functionality preferably out of the box? And if it's doable what would be the correct approach?

The app is latest angular webapp that gets the data from .net core REST API. We need support for current browsers.
Posted
Updated 29-May-20 0:51am

1 solution

Once the line color is set in a line chart, you can't change it based on the value of a data point. No chart library that I'm aware of is going to let you do it.

You have two options:

0) create another line (a different color from your data line) that indicates the desired threshold value (this will be a flat line with all data points being the same value).

2) create another series of dots without lines that indicates a value below the threshold, and a 2nd dot series that indicates values ABOVE the threshold, and overlay those dot series on your actual data line series.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900