]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Split legend and title block functionality into 2 separate blocks. This allows the...
authorEvert Timberg <evert.timberg@gmail.com>
Sun, 6 Dec 2015 15:20:38 +0000 (10:20 -0500)
committerEvert Timberg <evert.timberg@gmail.com>
Sun, 6 Dec 2015 15:20:38 +0000 (10:20 -0500)
samples/bar.html
samples/doughnut.html
samples/line-legend.html
samples/polar-area.html
samples/radar.html
src/core/core.controller.js
src/core/core.legend.js
src/core/core.title.js [new file with mode: 0644]

index 004e0738f7f84e1addf9f4d535ea8842446d2240..d127657007c5c0e5e928874a4788454a5a490dca 100644 (file)
                     responsive: true,
                     legend: {
                         position: 'top',
-                        title: {
-                            display: true,
-                            text: 'Our 3 Favorite Datasets'
-                        }
                     },
+                    title: {
+                        display: true,
+                        text: 'Our 3 Favorite Datasets'
+                    }
                 }
             });
 
index 0a6be617ada3606f450126efe0cbe1cfe0e602e0..f0ebd5129f59f44ac27030f54acd53406e2c00dd 100644 (file)
             responsive: true,
             legend: {
                 position: 'top',
-                title: {
-                    display: true,
-                    text: 'Our Favorite Datasets'
-                }
             },
+            title: {
+                display: true,
+                text: 'Our Favorite Datasets'
+            }
         }
     };
 
index 98ffc18f3e8cf19f03cfa4a1027900c52f460b83..ea345c21b8f6ae8c34c05058d4f53893139fbf63 100644 (file)
             options: {
                 responsive: true,
                 legend: {
-                    position: 'top',
-                    title: {
-                        display: true,
-                        text: 'Our 4 Favorite Datasets'
-                    }
+                    position: 'bottom',
                 },
                 hover: {
                     mode: 'label'
                             labelString: 'Value'
                         }
                     }]
+                },
+                title: {
+                    display: true,
+                    text: 'Our 4 Favorite Datasets'
                 }
             }
         };
index 58f9d57f10f156fe728affa4cebf91e53e99afc1..8d9bc9c64896d705c9fc8ef819cb3094a379f245 100644 (file)
             responsive: true,
             legend: {
                 position: 'top',
-                title: {
-                    display: true,
-                    text: 'Our Favorite Dataset'
-                }
+            },
+            title: {
+                display: true,
+                text: 'Our Favorite Dataset'
             },
             scale: {
               ticks: {
index 867605275932eb4822b7c2929caee33ff3943b95..e294cee1807599c429a1b835f73dfed783973fc0 100644 (file)
         options: {
             legend: {
                 position: 'top',
-                title: {
-                    display: true,
-                    text: 'Our 3 Favorite Datasets'
-                }
+            },
+            title: {
+                display: true,
+                text: 'Our 3 Favorite Datasets'
             },
             scale: {
-              reverse: true,
+              reverse: false,
               ticks: {
                 beginAtZero: true
               }
index 47884b732734c2750ccb1769d4c07aafa29a38ee..88bf11a83d5141c6a0d5662584da60421ad8f362 100644 (file)
@@ -59,7 +59,7 @@
                        this.ensureScalesHaveIDs();
                        this.buildOrUpdateControllers();
                        this.buildScales();
-                       this.buildLegends();
+                       this.buildSurroundingItems();
                        this.updateLayout();
                        this.resetElements();
                        this.initToolTip();
                        Chart.scaleService.addScalesToLayout(this);
                },
 
-               buildLegends: function() {
-                       if (!this.options.legend) {
-                               return;
+               buildSurroundingItems: function() {
+                       if (this.options.title) {
+                               this.titleBlock = new Chart.Title({
+                                       ctx: this.chart.ctx,
+                                       options: this.options.title,
+                                       chart: this
+                               });
+
+                               Chart.layoutService.addBox(this, this.titleBlock);
                        }
 
-                       this.legend = new Chart.Legend({
-                               ctx: this.chart.ctx,
-                               options: this.options.legend,
-                               chart: this,
-                       });
+                       if (this.options.legend) {
+                               this.legend = new Chart.Legend({
+                                       ctx: this.chart.ctx,
+                                       options: this.options.legend,
+                                       chart: this,
+                               });
 
-                       Chart.layoutService.addBox(this, this.legend);
+                               Chart.layoutService.addBox(this, this.legend);
+                       }
                },
 
                updateLayout: function() {
index fb3776d271fbce226315b44a9eff9efb8631f915..14e1c6b4e62c85f12c64516a56a3e0d34b6e504f 100644 (file)
                fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
                onClick: false, // a callback will override the default behavior of toggling the datasets
 
-               title: {
-                       position: 'top',
-                       fontColor: '#666',
-                       fontFamily: 'Helvetica Neue',
-                       fontSize: 12,
-                       fontStyle: 'bold',
-                       padding: 10,
-
-                       // actual title
-                       text: '',
-
-                       // display property
-                       display: false,
-               },
-
                labels: {
                        boxWidth: 40,
                        fontSize: 12,
                fit: function() {
 
                        var ctx = this.ctx;
-                       var titleFont = helpers.fontString(this.options.title.fontSize, this.options.title.fontStyle, this.options.title.fontFamily);
                        var labelFont = helpers.fontString(this.options.labels.fontSize, this.options.labels.fontStyle, this.options.labels.fontFamily);
 
                        // Reset hit boxes
 
                        // Increase sizes here
                        if (this.isHorizontal()) {
-
-                               // Title
-                               if (this.options.title.display) {
-                                       this.minSize.height += this.options.title.fontSize + (this.options.title.padding * 2);
-                               }
-
                                // Labels
 
                                // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
                                var ctx = this.ctx;
                                var cursor = {
                                        x: this.left + ((this.width - this.lineWidths[0]) / 2),
-                                       y: this.top,
+                                       y: this.top + this.options.labels.padding,
                                        line: 0,
                                };
 
 
                                // Horizontal
                                if (this.isHorizontal()) {
-
-                                       // Title Spacing if on top
-                                       if (this.options.title.display) {
-                                               if (this.options.title.position === 'top') {
-                                                       cursor.y += this.options.title.fontSize + (this.options.title.padding * 2);
-                                               } else {
-                                                       // bottom
-                                                       cursor.y += this.options.labels.padding;
-                                               }
-                                       }
-
                                        // Labels
                                        ctx.textAlign = "left";
                                        ctx.textBaseline = 'top';
 
                                                cursor.x += width + (this.options.labels.padding);
                                        }, this);
-
-                                       // Title Spacing if on bottom
-                                       if (this.options.title.display && this.options.title.position === 'bottom') {
-                                               cursor.y += this.options.title.fontSize + (this.options.title.padding * 2);
-                                       }
-
-                                       // Title
-                                       if (this.options.title.display) {
-
-                                               ctx.textAlign = "center";
-                                               ctx.textBaseline = 'middle';
-                                               ctx.fillStyle = this.options.title.fontColor; // render in correct colour
-                                               ctx.font = helpers.fontString(this.options.title.fontSize, this.options.title.fontStyle, this.options.title.fontFamily);
-
-                                               var titleX = this.left + ((this.right - this.left) / 2); // midpoint of the width
-                                               var titleY = this.options.title.position == 'bottom' ? this.bottom - (this.options.title.fontSize / 2) - this.options.title.padding : this.top + (this.options.title.fontSize / 2) + this.options.title.padding;
-
-                                               ctx.fillText(this.options.title.text, titleX, titleY);
-                                       }
-
-
                                } else {
 
-                                       // Title
-                                       if (this.options.title.display) {
-
-                                               // Draw the legend label
-                                               titleX = this.options.position == 'left' ? this.left + (this.options.title.fontSize / 2) : this.right - (this.options.title.fontSize / 2);
-                                               titleY = this.top + ((this.bottom - this.top) / 2);
-                                               var rotation = this.options.position == 'left' ? -0.5 * Math.PI : 0.5 * Math.PI;
-
-                                               ctx.save();
-                                               ctx.translate(titleX, titleY);
-                                               ctx.rotate(rotation);
-                                               ctx.textAlign = "center";
-                                               ctx.fillStyle = this.options.title.fontColor; // render in correct colour
-                                               ctx.font = helpers.fontString(this.options.title.fontSize, this.options.title.fontStyle, this.options.title.fontFamily);
-                                               ctx.textBaseline = 'middle';
-                                               ctx.fillText(this.options.title.text, 0, 0);
-                                               ctx.restore();
-
-                                       }
-
                                }
                        }
                },
                                                        this.chart.data.datasets[i].hidden = !this.chart.data.datasets[i].hidden;
 
                                                        // We hid a dataset ... rerender the chart
-                                                       //this.chart.render();
                                                        this.chart.update();
                                                        break;
                                                }
diff --git a/src/core/core.title.js b/src/core/core.title.js
new file mode 100644 (file)
index 0000000..7758fd3
--- /dev/null
@@ -0,0 +1,196 @@
+(function() {
+       "use strict";
+
+       var root = this,
+               Chart = root.Chart,
+               helpers = Chart.helpers;
+
+       Chart.defaults.title = {
+
+               display: true,
+               position: 'top',
+               fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
+
+               fontColor: '#666',
+               fontFamily: 'Helvetica Neue',
+               fontSize: 12,
+               fontStyle: 'bold',
+               padding: 10,
+
+               // actual title
+               text: '',
+       };
+
+       Chart.Title = Chart.Element.extend({
+
+               initialize: function(config) {
+                       helpers.extend(this, config);
+                       this.options = helpers.configMerge(Chart.defaults.title, config.options);
+
+                       // Contains hit boxes for each dataset (in dataset order)
+                       this.legendHitBoxes = [];
+               },
+
+               // These methods are ordered by lifecyle. Utilities then follow.
+
+               beforeUpdate: helpers.noop,
+               update: function(maxWidth, maxHeight, margins) {
+
+                       // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+                       this.beforeUpdate();
+
+                       // Absorb the master measurements
+                       this.maxWidth = maxWidth;
+                       this.maxHeight = maxHeight;
+                       this.margins = margins;
+
+                       // Dimensions
+                       this.beforeSetDimensions();
+                       this.setDimensions();
+                       this.afterSetDimensions();
+                       // Labels
+                       this.beforeBuildLabels();
+                       this.buildLabels();
+                       this.afterBuildLabels();
+
+                       // Fit
+                       this.beforeFit();
+                       this.fit();
+                       this.afterFit();
+                       //
+                       this.afterUpdate();
+
+                       return this.minSize;
+
+               },
+               afterUpdate: helpers.noop,
+
+               //
+
+               beforeSetDimensions: helpers.noop,
+               setDimensions: function() {
+                       // Set the unconstrained dimension before label rotation
+                       if (this.isHorizontal()) {
+                               // Reset position before calculating rotation
+                               this.width = this.maxWidth;
+                               this.left = 0;
+                               this.right = this.width;
+                       } else {
+                               this.height = this.maxHeight;
+
+                               // Reset position before calculating rotation
+                               this.top = 0;
+                               this.bottom = this.height;
+                       }
+
+                       // Reset padding
+                       this.paddingLeft = 0;
+                       this.paddingTop = 0;
+                       this.paddingRight = 0;
+                       this.paddingBottom = 0;
+
+                       // Reset minSize
+                       this.minSize = {
+                               width: 0,
+                               height: 0,
+                       };
+               },
+               afterSetDimensions: helpers.noop,
+
+               //
+
+               beforeBuildLabels: helpers.noop,
+               buildLabels: helpers.noop,
+               afterBuildLabels: helpers.noop,
+
+               //
+
+               beforeFit: helpers.noop,
+               fit: function() {
+
+                       var ctx = this.ctx;
+                       var titleFont = helpers.fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily);
+
+                       // Width
+                       if (this.isHorizontal()) {
+                               this.minSize.width = this.maxWidth; // fill all the width
+                       } else {
+                               this.minSize.width = 0;
+                       }
+
+                       // height
+                       if (this.isHorizontal()) {
+                               this.minSize.height = 0;
+                       } else {
+                               this.minSize.height = this.maxHeight; // fill all the height
+                       }
+
+                       // Increase sizes here
+                       if (this.isHorizontal()) {
+
+                               // Title
+                               if (this.options.display) {
+                                       this.minSize.height += this.options.fontSize + (this.options.padding * 2);
+                               }
+                       } else {
+                               // TODO vertical
+                       }
+
+                       this.width = this.minSize.width;
+                       this.height = this.minSize.height;
+
+               },
+               afterFit: helpers.noop,
+
+               // Shared Methods
+               isHorizontal: function() {
+                       return this.options.position == "top" || this.options.position == "bottom";
+               },
+
+               // Actualy draw the title block on the canvas
+               draw: function() {
+                       if (this.options.display) {
+                               var ctx = this.ctx;
+                               var titleX, titleY;
+
+                               // Horizontal
+                               if (this.isHorizontal()) {
+                                       // Title
+                                       if (this.options.display) {
+
+                                               ctx.textAlign = "center";
+                                               ctx.textBaseline = 'middle';
+                                               ctx.fillStyle = this.options.fontColor; // render in correct colour
+                                               ctx.font = helpers.fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily);
+
+                                               titleX = this.left + ((this.right - this.left) / 2); // midpoint of the width
+                                               titleY = this.top + ((this.bottom - this.top) / 2); // midpoint of the height
+
+                                               ctx.fillText(this.options.text, titleX, titleY);
+                                       }
+                               } else {
+
+                                       // Title
+                                       if (this.options.display) {
+                                               titleX = this.options.position == 'left' ? this.left + (this.options.fontSize / 2) : this.right - (this.options.fontSize / 2);
+                                               titleY = this.top + ((this.bottom - this.top) / 2);
+                                               var rotation = this.options.position == 'left' ? -0.5 * Math.PI : 0.5 * Math.PI;
+
+                                               ctx.save();
+                                               ctx.translate(titleX, titleY);
+                                               ctx.rotate(rotation);
+                                               ctx.textAlign = "center";
+                                               ctx.fillStyle = this.options.fontColor; // render in correct colour
+                                               ctx.font = helpers.fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily);
+                                               ctx.textBaseline = 'middle';
+                                               ctx.fillText(this.options.text, 0, 0);
+                                               ctx.restore();
+
+                                       }
+
+                               }
+                       }
+               }
+       });
+
+}).call(this);