]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
add support for addData and removeData to the radar chart. Needed to update the radia...
authorEvert Timberg <evert.timberg@gmail.com>
Thu, 18 Jun 2015 22:28:45 +0000 (18:28 -0400)
committerEvert Timberg <evert.timberg@gmail.com>
Thu, 18 Jun 2015 22:28:45 +0000 (18:28 -0400)
samples/radar.html
src/controllers/controller.radar.js
src/scales/scale.radialLinear.js

index fd1214cbbdc535394bfc6fd3d3bf1dae24dcc7bc..0605c76e7608828efc773cc3a7203b68f7b825de 100644 (file)
@@ -14,6 +14,8 @@
     <button id="randomizeData">Randomize Data</button>
     <button id="addDataset">Add Dataset</button>
     <button id="removeDataset">Remove Dataset</button>
+    <button id="addData">Add Data</button>
+    <button id="removeData">Remove Data</button>
     <script>
     var randomScalingFactor = function() {
         return Math.round(Math.random() * 100);
     };
 
     $('#randomizeData').click(function() {
-        config.data.datasets[0].backgroundColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.3)';
-        config.data.datasets[0].data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
+        $.each(config.data.datasets, function(i, dataset) {
+            dataset.data = dataset.data.map(function() {
+                return randomScalingFactor();
+            });
 
-        config.data.datasets[1].backgroundColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.3)';
-        config.data.datasets[1].data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
+        });
 
         window.myRadar.update();
     });
             pointBorderColor: randomColor(0.7),
             pointBackgroundColor: randomColor(0.5),
             pointBorderWidth: 1,
-            data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
+            data: [],
         };
 
+        for (var index = 0; index < config.data.labels.length; ++index) {
+            newDataset.data.push(randomScalingFactor());
+        }
+
         window.myRadar.addDataset(newDataset);
     });
 
+    $('#addData').click(function() {
+        if (config.data.datasets.length > 0) {
+            config.data.labels.push('dataset #' + config.data.labels.length);
+
+            for (var index = 0; index < config.data.datasets.length; ++index) {
+                window.myRadar.addData(randomScalingFactor(), index);
+            }
+        }
+    });
+
     $('#removeDataset').click(function() {
         window.myRadar.removeDataset(0);
     });
+
+    $('#removeData').click(function() {
+        config.data.labels.splice(-1, 1); // remove the label first
+
+        config.data.datasets.forEach(function(dataset, datasetIndex) {
+            window.myRadar.removeData(datasetIndex, -1);
+        });
+    });
     </script>
 </body>
 
index e7577887f77edb3fc4a6534cfd17563d718cfd28..ce597d720f9184603b3114a5a60e0856a456d02d 100644 (file)
                                });
                        }, this);
                },
+               addElementAndReset: function(index) {
+                       this.getDataset().metaData = this.getDataset().metaData || [];
+                       var point = new Chart.elements.Point({
+                               _chart: this.chart.chart,
+                               _datasetIndex: this.index,
+                               _index: index,
+                       });
+
+                       // Reset the point
+                       this.updateElement(point, index, true);
+
+                       // Add to the points array
+                       this.getDataset().metaData.splice(index, 0, point);
+
+                       // Make sure bezier control points are updated
+                       this.updateBezierControlPoints();
+               },
+               removeElement: function(index) {
+                       this.getDataset().metaData.splice(index, 1);
+               },
 
                reset: function() {
                        this.update(true);
 
                        // Update Points
                        helpers.each(points, function(point, index) {
-                               var pointPosition = scale.getPointPositionForValue(index, this.getDataset().data[index]);
-
-                               helpers.extend(point, {
-                                       // Utility
-                                       _datasetIndex: this.index,
-                                       _index: index,
-
-                                       // Desired view properties
-                                       _model: {
-                                               x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
-                                               y: reset ? scale.yCenter : pointPosition.y,
-
-                                               // Appearance
-                                               tension: point.custom && point.custom.tension ? point.custom.tension : this.chart.options.elements.line.tension,
-                                               radius: point.custom && point.custom.radius ? point.custom.pointRadius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius),
-                                               backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor),
-                                               borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor),
-                                               borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth),
-                                               skip: point.custom && point.custom.skip ? point.custom.skip : this.getDataset().data[index] === null,
-
-                                               // Tooltip
-                                               hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius),
-                                       },
-                               });
+                               this.updateElement(point, index, reset);
                        }, this);
 
 
                        // Update bezier control points
+                       this.updateBezierControlPoints();
+               },
+               updateElement: function(point, index, reset) {
+                       var pointPosition = this.chart.scale.getPointPositionForValue(index, this.getDataset().data[index]);
+
+                       helpers.extend(point, {
+                               // Utility
+                               _datasetIndex: this.index,
+                               _index: index,
+
+                               // Desired view properties
+                               _model: {
+                                       x: reset ? this.chart.scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
+                                       y: reset ? this.chart.scale.yCenter : pointPosition.y,
+
+                                       // Appearance
+                                       tension: point.custom && point.custom.tension ? point.custom.tension : this.chart.options.elements.line.tension,
+                                       radius: point.custom && point.custom.radius ? point.custom.pointRadius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius),
+                                       backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor),
+                                       borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor),
+                                       borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth),
+                                       skip: point.custom && point.custom.skip ? point.custom.skip : this.getDataset().data[index] === null,
+
+                                       // Tooltip
+                                       hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius),
+                               },
+                       });
+               },
+               updateBezierControlPoints: function() {
                        helpers.each(this.getDataset().metaData, function(point, index) {
                                var controlPoints = helpers.splineCurve(
                                        helpers.previousItem(this.getDataset().metaData, index, true)._model,
 
                                // Prevent the bezier going outside of the bounds of the graph
 
-                               // Cap puter bezier handles to the upper/lower scale bounds
+                               // Cap outer bezier handles to the upper/lower scale bounds
                                if (controlPoints.next.y > this.chart.chartArea.bottom) {
                                        point._model.controlPointNextY = this.chart.chartArea.bottom;
                                } else if (controlPoints.next.y < this.chart.chartArea.top) {
                                // Now pivot the point for animation
                                point.pivot();
                        }, this);
-
                },
 
                draw: function(ease) {
index 15169aa8673589b609b5f53ad005efe63638b20d..0a1a26b45af3245397f80607849df8951e3b1b37 100644 (file)
                        this.xCenter = this.chart.width / 2;
                        this.yCenter = this.chart.height / 2;
                        this.size = helpers.min([this.height, this.width]);
-                       this.valuesCount = this.data.labels.length;
                        this.labels = this.data.labels;
                        this.drawingArea = (this.options.display) ? (this.size / 2) - (this.options.labels.fontSize / 2 + this.options.labels.backdropPaddingY) : (this.size / 2);
                },
+               getValueCount: function() {
+                       return this.data.labels.length;
+               },
                update: function() {
                        if (!this.options.lineArc) {
                                this.setScaleSize();
                        }, this);
                },
                getCircumference: function() {
-                       return ((Math.PI * 2) / this.valuesCount);
+                       return ((Math.PI * 2) / this.getValueCount());
                },
                setScaleSize: function() {
                        /*
                                radiusReductionLeft,
                                maxWidthRadius;
                        this.ctx.font = helpers.fontString(this.options.pointLabels.fontSize, this.options.pointLabels.fontStyle, this.options.pointLabels.fontFamily);
-                       for (i = 0; i < this.valuesCount; i++) {
+                       for (i = 0; i < this.getValueCount(); i++) {
                                // 5px to space the text slightly out - similar to what we do in the draw function.
                                pointPosition = this.getPointPosition(i, largestPossibleRadius);
                                textWidth = this.ctx.measureText(helpers.template(this.options.labels.template, {
                                        value: this.labels[i]
                                })).width + 5;
-                               if (i === 0 || i === this.valuesCount / 2) {
+                               if (i === 0 || i === this.getValueCount() / 2) {
                                        // If we're at index zero, or exactly the middle, we're at exactly the top/bottom
                                        // of the radar chart, so text will be aligned centrally, so we'll half it and compare
                                        // w/left and right text sizes
                                                furthestLeft = pointPosition.x - halfTextWidth;
                                                furthestLeftIndex = i;
                                        }
-                               } else if (i < this.valuesCount / 2) {
+                               } else if (i < this.getValueCount() / 2) {
                                        // Less than half the values means we'll left align the text
                                        if (pointPosition.x + textWidth > furthestRight) {
                                                furthestRight = pointPosition.x + textWidth;
                                                furthestRightIndex = i;
                                        }
-                               } else if (i > this.valuesCount / 2) {
+                               } else if (i > this.getValueCount() / 2) {
                                        // More than half the values means we'll right align the text
                                        if (pointPosition.x - textWidth < furthestLeft) {
                                                furthestLeft = pointPosition.x - textWidth;
                },
 
                getIndexAngle: function(index) {
-                       var angleMultiplier = (Math.PI * 2) / this.valuesCount;
+                       var angleMultiplier = (Math.PI * 2) / this.getValueCount();
                        // Start from the top instead of right, so remove a quarter of the circle
 
                        return index * angleMultiplier - (Math.PI / 2);
                                                        } else {
                                                                // Draw straight lines connecting each index
                                                                ctx.beginPath();
-                                                               for (var i = 0; i < this.valuesCount; i++) {
+                                                               for (var i = 0; i < this.getValueCount(); i++) {
                                                                        var pointPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.ticks[index]));
                                                                        if (i === 0) {
                                                                                ctx.moveTo(pointPosition.x, pointPosition.y);
                                        ctx.lineWidth = this.options.angleLines.lineWidth;
                                        ctx.strokeStyle = this.options.angleLines.color;
 
-                                       for (var i = this.valuesCount - 1; i >= 0; i--) {
+                                       for (var i = this.getValueCount() - 1; i >= 0; i--) {
                                                if (this.options.angleLines.show) {
                                                        var outerPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.max));
                                                        ctx.beginPath();