Chartjs-Chartjs: display different average line while grouping

0👍

this was my solution: i created a plugin and than tried to draw a line for each component of the chart. the code is quite messy (i’ll try to clean)

                            // Define a plugin to provide average for different groups of data
                        Chart.plugins.register({                                                            
                            afterDatasetsDraw: function(chartInstance, easing) {
                                // To only draw at the end of animation, check for easing === 1
                                {

                                    var ctx = chartInstance.chart.ctx;
                                    var mapAverageLinePoints = {};

                                    chartInstance.data.datasets.forEach(function (dataset, i) {
                                        var meta = chartInstance.getDatasetMeta(i);                                                 
                                        if (!meta.hidden) {                                             
                                            meta.data.forEach(function(element, index) {                                                                                                    
                                                var dataString = dataset.label;
                                                var groupAverageLine = mapAverageLinePoints[dataString];
                                                if(groupAverageLine==null)
                                                {
                                                    groupAverageLine = [];
                                                } 
                                                //store the point coordinate and the value
                                                var linePoint =
                                                {
                                                        x : position.x,
                                                        y : position.y,
                                                        value: dataset.data[index], 
                                                        avg : 0
                                                }   
                                                //adding the point to the array going to be stored in the map that group the point by the label
                                                groupAverageLine.push(linePoint);
                                                mapAverageLinePoints[dataString]=groupAverageLine; 
                                            }

                                            );                                                                                      
                                        }
                                    });

                                    for (var type in mapAverageLinePoints) {
                                        var avgLinePoints = mapAverageLinePoints[type];
                                        //NON E' in valore bensì rispecchia la sommatoria dei posY utilizzati nella rappresentazione
                                        var totalYAxis=0;
                                        var totale=0;
                                        var labelNumero=0;
                                        for(var k=0;k<avgLinePoints.length;k++)
                                        {
                                            var point = avgLinePoints[k];
                                            totalYAxis+=point.y;
                                            totale+=point.value;
                                            //jump the first one
                                            if(k>=1)
                                            {                                                                   
                                                var prevPoint = avgLinePoints[k-1];
                                                //k start from 0!!!!
                                                var avgYAxis = (totalYAxis/(k+1));
                                                var avg = (totale/(k+1));

                                                // here i draw the line starting from the previous average
                                                ctx.beginPath();
                                                ctx.moveTo(point.x, avgYAxis);
                                                ctx.strokeStyle = '#979797';
                                                ctx.lineTo((prevPoint.x), prevPoint.avg);
                                                ctx.stroke();
                                                point.avg=avgYAxis;
                                                //this one is for drawing a "o" where two segments collide
                                                var fontSize = 12;
                                                var fontStyle = 'normal';
                                                var fontFamily = 'Helvetica Neue';
                                                ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);                                                   
                                                ctx.fillText("avg: "+(avg/range).toLocaleString() + rangeSuffix + ' €', point.x, point.y+(point.value>0?-30:+10));
                                            }
                                            else{
                                                //for the first one only record the y as the avg
                                                point.avg=point.y;
                                            }
                                            var fontSize = 10;
                                            var fontStyle = 'normal';
                                            var fontFamily = 'Helvetica Neue';
                                            ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
                                            ctx.fillText("o", point.x, point.avg);
                                        }                                           
                                        labelNumero=labelNumero+1;
                                    }
                                }
                            }
                        });

the result is this one:

chart result

Leave a comment