]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Time Scale working, troubleshooting log scale
authorTanner Linsley <tannerlinsley@gmail.com>
Thu, 24 Sep 2015 18:07:40 +0000 (12:07 -0600)
committerTanner Linsley <tannerlinsley@gmail.com>
Thu, 24 Sep 2015 18:07:40 +0000 (12:07 -0600)
samples/combo-time-scale.html
samples/line-time-scale.html
src/controllers/controller.bar.js
src/core/core.controller.js
src/core/core.scale.js
src/scales/scale.logarithmic.js
src/scales/scale.time.js

index 548202e2cad25457eb7bb077bcb53c8c99e3a0c4..6b1bfef4dfcf9a4ed3201dd640c555ac340e285e 100644 (file)
                 // labels: ["01/01/2015", "01/02/2015", "01/03/2015", "01/06/2015", "01/15/2015", "01/17/2015", "01/30/2015"], // Days
                 // labels: ["12/25/2014", "01/08/2015", "01/15/2015", "01/22/2015", "01/29/2015", "02/05/2015", "02/12/2015"], // Weeks
                 datasets: [{
+                    type: 'bar',
                     label: 'Dataset 1',
                     backgroundColor: "rgba(151,187,205,0.5)",
                     data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
                     borderColor: 'white',
                     borderWidth: 2
                 }, {
+                    type: 'bar',
                     label: 'Dataset 2',
                     backgroundColor: "rgba(151,187,205,0.5)",
                     data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
@@ -90,7 +92,7 @@
                 },
                 elements: {
                     line: {
-                        tension: 0
+                        tension: 0.3
                     }
                 },
             }
index 3fc97b52be5fa280c4a43400479e950d8a12af60..7e238dcdf655ad2d377e4f85978ce56cd875db07 100644 (file)
@@ -89,7 +89,7 @@
                 },
                 elements: {
                     line: {
-                        tension: 0
+                        tension: 0.3
                     }
                 },
             }
index bd2d5f0ee80c9d86ac1313e90809ba5c10752637..933147c41ac24054c5bcda384c0e131cc8f4705d 100644 (file)
                        var datasetCount = !this.chart.isCombo ? this.chart.data.datasets.length : helpers.where(this.chart.data.datasets, function(ds) {
                                return ds.type == 'bar';
                        }).length;
-                       var tickWidth = xScale.getPixelForValue(null, 1) - xScale.getPixelForValue(null, 0);
+                       var tickWidth = (function() {
+                               var min = xScale.getPixelForValue(null, 1) - xScale.getPixelForValue(null, 0);
+                               for (var i = 2; i < this.getDataset().data.length; i++) {
+                                       min = Math.min(xScale.getPixelForValue(null, i) - xScale.getPixelForValue(null, i - 1), min);
+                               }
+                               return min;
+                       }).call(this);
                        var categoryWidth = tickWidth * xScale.options.categoryPercentage;
                        var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
                        var fullBarWidth = categoryWidth / datasetCount;
                        var yScale = this.getScaleForID(this.getDataset().yAxisID);
                        var xScale = this.getScaleForID(this.getDataset().xAxisID);
 
-                       var leftTick = xScale.getPixelForValue(null, index);
                        var ruler = this.getRuler();
+                       var leftTick = xScale.getPixelForValue(null, index, datasetIndex);
+                       leftTick -= this.chart.isCombo ? (ruler.tickWidth / 2) : 0;
 
                        if (yScale.options.stacked) {
                                return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;
index 26db1cd10a515ed2e2547d3bedf6168a4edff3ce..578d02e8337171e2a61e427c12af72b4aa89aff8 100644 (file)
                buildOrUpdateControllers: function() {
                        var types = [];
                        helpers.each(this.data.datasets, function(dataset, datasetIndex) {
-                               var type = dataset.type || this.config.type;
+                               if (!dataset.type) {
+                                       dataset.type = this.config.type;
+                               }
+                               var type = dataset.type;
                                types.push(type);
                                if (dataset.controller) {
                                        dataset.controller.updateIndex(datasetIndex);
index 3071d613d1ec2d6e6c62c1c5fbf6dac82ebe18ff..4f67ef964c1622e4cb03ae3e81b00e6fa0c7718f 100644 (file)
 
                                //Max label rotation can be set or default to 90 - also act as a loop counter
                                while (this.labelWidth > tickWidth && this.labelRotation <= this.options.ticks.maxRotation) {
-                                       console.log(this.labelWidth, tickWidth, ',', this.labelRotation, this.options.ticks.maxRotation);
                                        cosRotation = Math.cos(helpers.toRadians(this.labelRotation));
                                        sinRotation = Math.sin(helpers.toRadians(this.labelRotation));
 
 
                                        this.paddingRight = this.options.ticks.fontSize / 2;
 
-                                       console.log(sinRotation * originalLabelWidth, this.maxHeight);
                                        if (sinRotation * originalLabelWidth > this.maxHeight) {
                                                // go back one step
                                                this.labelRotation--;
index b7e0defb56abece0072be26bcffecdf3b772bc78..702451493c0acb94d01fd534c919315a82c65f40 100644 (file)
                helpers = Chart.helpers;
 
        var defaultConfig = {
-               display: true,
                position: "left",
 
-               // grid line settings
-               gridLines: {
-                       show: true,
-                       color: "rgba(0, 0, 0, 0.1)",
-                       lineWidth: 1,
-                       drawOnChartArea: true,
-                       drawTicks: true, // draw ticks extending towards the label
-                       zeroLineWidth: 1,
-                       zeroLineColor: "rgba(0,0,0,0.25)",
-               },
-
                // scale label
                scaleLabel: {
-                       fontColor: '#666',
-                       fontFamily: 'Helvetica Neue',
-                       fontSize: 12,
-                       fontStyle: 'normal',
-
                        // actual label
                        labelString: '',
-
                        // display property
                        show: false,
                },
 
-               // scale numbers
-               reverse: false,
-               override: null,
-
                // label settings
                labels: {
-                       show: true,
-                       mirror: false,
-                       padding: 10,
                        template: "<%var remain = value / (Math.pow(10, Math.floor(Chart.helpers.log10(value))));if (remain === 1 || remain === 2 || remain === 5) {%><%=value.toExponential()%><%} else {%><%= null %><%}%>",
-                       fontSize: 12,
-                       fontStyle: "normal",
-                       fontColor: "#666",
-                       fontFamily: "Helvetica Neue"
                }
        };
 
-       var LogarithmicScale = Chart.Element.extend({
-               isHorizontal: function() {
-                       return this.options.position == "top" || this.options.position == "bottom";
-               },
-               generateTicks: function(width, height) {
-                       // We need to decide how many ticks we are going to have. Each tick draws a grid line.
-                       // There are two possibilities. The first is that the user has manually overridden the scale
-                       // calculations in which case the job is easy. The other case is that we have to do it ourselves
-                       // 
-                       // We assume at this point that the scale object has been updated with the following values
-                       // by the chart.
-                       //  min: this is the minimum value of the scale
-                       //  max: this is the maximum value of the scale
-                       //  options: contains the options for the scale. This is referenced from the user settings
-                       //      rather than being cloned. This ensures that updates always propogate to a redraw
+       var LogarithmicScale = Chart.Scale.extend({
+               buildTicks: function() {
 
-                       // Reset the ticks array. Later on, we will draw a grid line at these positions
-                       // The array simply contains the numerical value of the spots where ticks will be
-                       this.ticks = [];
+                       // Calculate Range (we may break this out into it's own lifecycle function)
+
+                       this.min = null;
+                       this.max = null;
+
+                       var values = [];
+
+                       if (this.options.stacked) {
+                               helpers.each(this.data.datasets, function(dataset) {
+                                       if (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id) {
+                                               helpers.each(dataset.data, function(rawValue, index) {
+
+                                                       var value = this.getRightValue(rawValue);
+
+                                                       values[index] = values[index] || 0;
+
+                                                       if (this.options.relativePoints) {
+                                                               values[index] = 100;
+                                                       } else {
+                                                               // Don't need to split positive and negative since the log scale can't handle a 0 crossing
+                                                               values[index] += value;
+                                                       }
+                                               }, this);
+                                       }
+                               }, this);
+
+                               this.min = helpers.min(values);
+                               this.max = helpers.max(values);
 
-                       if (this.options.override) {
-                               // The user has specified the manual override. We use <= instead of < so that 
-                               // we get the final line
-                               for (var i = 0; i <= this.options.override.steps; ++i) {
-                                       var value = this.options.override.start + (i * this.options.override.stepWidth);
-                                       this.ticks.push(value);
-                               }
                        } else {
-                               // Figure out what the max number of ticks we can support it is based on the size of
-                               // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
-                               // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on 
-                               // the graph
+                               helpers.each(this.data.datasets, function(dataset) {
+                                       if (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id) {
+                                               helpers.each(dataset.data, function(rawValue, index) {
+                                                       var value = this.getRightValue(rawValue);
 
-                               var minExponent = Math.floor(helpers.log10(this.min));
-                               var maxExponent = Math.ceil(helpers.log10(this.max));
+                                                       if (this.min === null) {
+                                                               this.min = value;
+                                                       } else if (value < this.min) {
+                                                               this.min = value;
+                                                       }
 
-                               for (var exponent = minExponent; exponent < maxExponent; ++exponent) {
-                                       for (var i = 1; i < 10; ++i) {
-                                               this.ticks.push(i * Math.pow(10, exponent));
+                                                       if (this.max === null) {
+                                                               this.max = value;
+                                                       } else if (value > this.max) {
+                                                               this.max = value;
+                                                       }
+                                               }, this);
                                        }
+                               }, this);
+                       }
+
+                       if (this.min === this.max) {
+                               if (this.min !== 0 && this.min !== null) {
+                                       this.min = Math.pow(10, Math.floor(helpers.log10(this.min)) - 1);
+                                       this.max = Math.pow(10, Math.floor(helpers.log10(this.max)) + 1);
+                               } else {
+                                       this.min = 1;
+                                       this.max = 10;
                                }
+                       }
+
+
+                       // Reset the ticks array. Later on, we will draw a grid line at these positions
+                       // The array simply contains the numerical value of the spots where ticks will be
+                       this.ticks = [];
 
-                               this.ticks.push(1.0 * Math.pow(10, maxExponent));
+
+                       // Figure out what the max number of ticks we can support it is based on the size of
+                       // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
+                       // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on 
+                       // the graph
+
+                       var minExponent = Math.floor(helpers.log10(this.min));
+                       var maxExponent = Math.ceil(helpers.log10(this.max));
+
+                       for (var exponent = minExponent; exponent < maxExponent; ++exponent) {
+                               for (var i = 1; i < 10; ++i) {
+                                       this.ticks.push(i * Math.pow(10, exponent));
+                               }
                        }
 
+                       this.ticks.push(1.0 * Math.pow(10, maxExponent));
+
                        if (this.options.position == "left" || this.options.position == "right") {
                                // We are in a vertical orientation. The top value is the highest. So reverse the array
                                this.ticks.reverse();
                                this.start = this.min;
                                this.end = this.max;
                        }
+
+                       console.log(this.ticks);
                },
                buildLabels: function() {
                        // We assume that this has been run after ticks have been generated. We try to figure out
                                // Bottom - top since pixels increase downard on a screen
                                if (value === 0) {
                                        pixel = this.top + this.paddingTop;
-                               } else  {
+                               } else {
                                        var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
                                        pixel = (this.bottom - this.paddingBottom) - (innerHeight / range * (helpers.log10(value) - helpers.log10(this.start)));
                                }
                        return pixel;
                },
 
-               // Functions needed for line charts
-               calculateRange: function() {
-                       this.min = null;
-                       this.max = null;
-
-                       var values = [];
-
-                       if (this.options.stacked) {
-                               helpers.each(this.data.datasets, function(dataset) {
-                                       if (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id) {
-                                               helpers.each(dataset.data, function(rawValue, index) {
-
-                                                       var value = this.getRightValue(rawValue);
-
-                                                       values[index] = values[index] || 0;
-
-                                                       if (this.options.relativePoints) {
-                                                               values[index] = 100;
-                                                       } else {
-                                                               // Don't need to split positive and negative since the log scale can't handle a 0 crossing
-                                                               values[index] += value;
-                                                       }
-                                               }, this);
-                                       }
-                               }, this);
-
-                               this.min = helpers.min(values);
-                               this.max = helpers.max(values);
-
-                       } else {
-                               helpers.each(this.data.datasets, function(dataset) {
-                                       if (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id) {
-                                               helpers.each(dataset.data, function(rawValue, index) {
-                                                       var value = this.getRightValue(rawValue);
-
-                                                       if (this.min === null) {
-                                                               this.min = value;
-                                                       } else if (value < this.min) {
-                                                               this.min = value;
-                                                       }
-
-                                                       if (this.max === null) {
-                                                               this.max = value;
-                                                       } else if (value > this.max) {
-                                                               this.max = value;
-                                                       }
-                                               }, this);
-                                       }
-                               }, this);
-                       }
-
-                       if (this.min === this.max) {
-                               if (this.min !== 0 && this.min !== null) {
-                                       this.min = Math.pow(10, Math.floor(helpers.log10(this.min)) - 1);
-                                       this.max = Math.pow(10, Math.floor(helpers.log10(this.max)) + 1);
-                               } else {
-                                       this.min = 1;
-                                       this.max = 10;
-                               }
-                       }
-               },
-
                getPointPixelForValue: function(rawValue, index, datasetIndex) {
                        var value = this.getRightValue(rawValue);
 
 
                        return this.getPixelForValue(value);
                },
-
-               // Fit this axis to the given size
-               // @param {number} maxWidth : the max width the axis can be
-               // @param {number} maxHeight: the max height the axis can be
-               // @return {object} minSize : the minimum size needed to draw the axis
-               fit: function(maxWidth, maxHeight, margins) {
-                       this.calculateRange();
-                       this.generateTicks(maxWidth, maxHeight);
-                       this.buildLabels();
-
-                       var minSize = {
-                               width: 0,
-                               height: 0,
-                       };
-
-                       // In a horizontal axis, we need some room for the scale to be drawn
-                       //
-                       //      -----------------------------------------------------
-                       //          |           |           |           |           |
-                       //
-                       // In a vertical axis, we need some room for the scale to be drawn.
-                       // The actual grid lines will be drawn on the chart area, however, we need to show 
-                       // ticks where the axis actually is.
-                       // We will allocate 25px for this width
-                       //      |
-                       //     -|
-                       //      |
-                       //      |
-                       //     -|
-                       //      |
-                       //      |
-                       //     -|
-
-
-                       // Width
-                       if (this.isHorizontal()) {
-                               minSize.width = maxWidth; // fill all the width
-                       } else {
-                               minSize.width = this.options.gridLines.show && this.options.display ? 10 : 0;
-                       }
-
-                       // height
-                       if (this.isHorizontal()) {
-                               minSize.height = this.options.gridLines.show && this.options.display ? 10 : 0;
-                       } else {
-                               minSize.height = maxHeight; // fill all the height
-                       }
-
-                       // Are we showing a label for the scale?
-                       if (this.options.scaleLabel.show) {
-                               if (this.isHorizontal()) {
-                                       minSize.height += (this.options.scaleLabel.fontSize * 1.5);
-                               } else {
-                                       minSize.width += (this.options.scaleLabel.fontSize * 1.5);
-                               }
-                       }
-
-                       this.paddingLeft = 0;
-                       this.paddingRight = 0;
-                       this.paddingTop = 0;
-                       this.paddingBottom = 0;
-
-
-                       if (this.options.labels.show && this.options.display) {
-                               // Don't bother fitting the labels if we are not showing them
-                               var labelFont = helpers.fontString(this.options.labels.fontSize,
-                                       this.options.labels.fontStyle, this.options.labels.fontFamily);
-
-                               if (this.isHorizontal()) {
-                                       // A horizontal axis is more constrained by the height.
-                                       var maxLabelHeight = maxHeight - minSize.height;
-                                       var labelHeight = 1.5 * this.options.labels.fontSize;
-                                       minSize.height = Math.min(maxHeight, minSize.height + labelHeight);
-
-                                       var labelFont = helpers.fontString(this.options.labels.fontSize, this.options.labels.fontStyle, this.options.labels.fontFamily);
-                                       this.ctx.font = labelFont;
-
-                                       var firstLabelWidth = this.ctx.measureText(this.labels[0]).width;
-                                       var lastLabelWidth = this.ctx.measureText(this.labels[this.labels.length - 1]).width;
-
-                                       // Ensure that our labels are always inside the canvas
-                                       this.paddingLeft = firstLabelWidth / 2;
-                                       this.paddingRight = lastLabelWidth / 2;
-                               } else {
-                                       // A vertical axis is more constrained by the width. Labels are the dominant factor 
-                                       // here, so get that length first
-                                       var maxLabelWidth = maxWidth - minSize.width;
-                                       var largestTextWidth = helpers.longestText(this.ctx, labelFont, this.labels);
-
-                                       if (largestTextWidth < maxLabelWidth) {
-                                               // We don't need all the room
-                                               minSize.width += largestTextWidth;
-                                               minSize.width += 3; // extra padding
-                                       } else {
-                                               // Expand to max size
-                                               minSize.width = maxWidth;
-                                       }
-
-                                       this.paddingTop = this.options.labels.fontSize / 2;
-                                       this.paddingBottom = this.options.labels.fontSize / 2;
-                               }
-                       }
-
-                       if (margins) {
-                               this.paddingLeft -= margins.left;
-                               this.paddingTop -= margins.top;
-                               this.paddingRight -= margins.right;
-                               this.paddingBottom -= margins.bottom;
-
-                               this.paddingLeft = Math.max(this.paddingLeft, 0);
-                               this.paddingTop = Math.max(this.paddingTop, 0);
-                               this.paddingRight = Math.max(this.paddingRight, 0);
-                               this.paddingBottom = Math.max(this.paddingBottom, 0);
-                       }
-
-                       this.width = minSize.width;
-                       this.height = minSize.height;
-                       return minSize;
-               },
-               // Actualy draw the scale on the canvas
-               // @param {rectangle} chartArea : the area of the chart to draw full grid lines on
-               draw: function(chartArea) {
-                       if (this.options.display) {
-
-                               var setContextLineSettings;
-                               var hasZero;
-
-                               // Make sure we draw text in the correct color
-                               this.ctx.fillStyle = this.options.labels.fontColor;
-
-                               if (this.isHorizontal()) {
-                                       if (this.options.gridLines.show) {
-                                               // Draw the horizontal line
-                                               setContextLineSettings = true;
-                                               hasZero = helpers.findNextWhere(this.ticks, function(tick) {
-                                                       return tick === 0;
-                                               }) !== undefined;
-                                               var yTickStart = this.options.position == "bottom" ? this.top : this.bottom - 5;
-                                               var yTickEnd = this.options.position == "bottom" ? this.top + 5 : this.bottom;
-
-                                               helpers.each(this.ticks, function(tick, index) {
-                                                       // Grid lines are vertical
-                                                       var xValue = this.getPixelForValue(tick);
-
-                                                       if (this.labels[index] === null) {
-                                                               // If the user specifically hid the label by returning null from the label function, do so
-                                                               return;
-                                                       }
-
-                                                       if (tick === 0 || (!hasZero && index === 0)) {
-                                                               // Draw the 0 point specially or the left if there is no 0
-                                                               this.ctx.lineWidth = this.options.gridLines.zeroLineWidth;
-                                                               this.ctx.strokeStyle = this.options.gridLines.zeroLineColor;
-                                                               setContextLineSettings = true; // reset next time
-                                                       } else if (setContextLineSettings) {
-                                                               this.ctx.lineWidth = this.options.gridLines.lineWidth;
-                                                               this.ctx.strokeStyle = this.options.gridLines.color;
-                                                               setContextLineSettings = false;
-                                                       }
-
-                                                       xValue += helpers.aliasPixel(this.ctx.lineWidth);
-
-                                                       // Draw the label area
-                                                       this.ctx.beginPath();
-
-                                                       if (this.options.gridLines.drawTicks) {
-                                                               this.ctx.moveTo(xValue, yTickStart);
-                                                               this.ctx.lineTo(xValue, yTickEnd);
-                                                       }
-
-                                                       // Draw the chart area
-                                                       if (this.options.gridLines.drawOnChartArea) {
-                                                               this.ctx.moveTo(xValue, chartArea.top);
-                                                               this.ctx.lineTo(xValue, chartArea.bottom);
-                                                       }
-
-                                                       // Need to stroke in the loop because we are potentially changing line widths & colours
-                                                       this.ctx.stroke();
-                                               }, this);
-                                       }
-
-                                       if (this.options.labels.show) {
-                                               // Draw the labels
-
-                                               var labelStartY;
-
-                                               if (this.options.position == "top") {
-                                                       labelStartY = this.bottom - 10;
-                                                       this.ctx.textBaseline = "bottom";
-                                               } else {
-                                                       // bottom side
-                                                       labelStartY = this.top + 10;
-                                                       this.ctx.textBaseline = "top";
-                                               }
-
-                                               this.ctx.textAlign = "center";
-                                               this.ctx.font = helpers.fontString(this.options.labels.fontSize, this.options.labels.fontStyle, this.options.labels.fontFamily);
-
-                                               helpers.each(this.labels, function(label, index) {
-                                                       var xValue = this.getPixelForValue(this.ticks[index]);
-                                                       if (label) {
-                                                               this.ctx.fillText(label, xValue, labelStartY);
-                                                       }
-                                               }, this);
-                                       }
-
-                                       if (this.options.scaleLabel.show) {
-                                               // Draw the scale label
-                                               this.ctx.textAlign = "center";
-                                               this.ctx.textBaseline = 'middle';
-                                               this.ctx.font = helpers.fontString(this.options.scaleLabel.fontSize, this.options.scaleLabel.fontStyle, this.options.scaleLabel.fontFamily);
-
-                                               var scaleLabelX = this.left + ((this.right - this.left) / 2); // midpoint of the width
-                                               var scaleLabelY = this.options.position == 'bottom' ? this.bottom - (this.options.scaleLabel.fontSize / 2) : this.top + (this.options.scaleLabel.fontSize / 2);
-
-                                               this.ctx.fillText(this.options.scaleLabel.labelString, scaleLabelX, scaleLabelY);
-                                       }
-                               } else {
-                                       // Vertical
-                                       if (this.options.gridLines.show) {
-
-                                               // Draw the vertical line
-                                               setContextLineSettings = true;
-                                               hasZero = helpers.findNextWhere(this.ticks, function(tick) {
-                                                       return tick === 0;
-                                               }) !== undefined;
-                                               var xTickStart = this.options.position == "right" ? this.left : this.right - 5;
-                                               var xTickEnd = this.options.position == "right" ? this.left + 5 : this.right;
-
-                                               helpers.each(this.ticks, function(tick, index) {
-                                                       // Grid lines are horizontal
-                                                       var yValue = this.getPixelForValue(tick);
-
-                                                       if (tick === 0 || (!hasZero && index === 0)) {
-                                                               // Draw the 0 point specially or the bottom if there is no 0
-                                                               this.ctx.lineWidth = this.options.gridLines.zeroLineWidth;
-                                                               this.ctx.strokeStyle = this.options.gridLines.zeroLineColor;
-                                                               setContextLineSettings = true; // reset next time
-                                                       } else if (setContextLineSettings) {
-                                                               this.ctx.lineWidth = this.options.gridLines.lineWidth;
-                                                               this.ctx.strokeStyle = this.options.gridLines.color;
-                                                               setContextLineSettings = false; // use boolean to indicate that we only want to do this once
-                                                       }
-
-                                                       yValue += helpers.aliasPixel(this.ctx.lineWidth);
-
-                                                       // Draw the label area
-                                                       this.ctx.beginPath();
-
-                                                       if (this.options.gridLines.drawTicks) {
-                                                               this.ctx.moveTo(xTickStart, yValue);
-                                                               this.ctx.lineTo(xTickEnd, yValue);
-                                                       }
-
-                                                       // Draw the chart area
-                                                       if (this.options.gridLines.drawOnChartArea) {
-                                                               this.ctx.moveTo(chartArea.left, yValue);
-                                                               this.ctx.lineTo(chartArea.right, yValue);
-                                                       }
-
-                                                       this.ctx.stroke();
-                                               }, this);
-                                       }
-
-                                       if (this.options.labels.show) {
-                                               // Draw the labels
-
-                                               var labelStartX;
-
-                                               if (this.options.position == "left") {
-                                                       if (this.options.labels.mirror) {
-                                                               labelStartX = this.right + this.options.labels.padding;
-                                                               this.ctx.textAlign = "left";
-                                                       } else {
-                                                               labelStartX = this.right - this.options.labels.padding;
-                                                               this.ctx.textAlign = "right";
-                                                       }
-                                               } else {
-                                                       // right side
-                                                       if (this.options.labels.mirror) {
-                                                               labelStartX = this.left - this.options.labels.padding;
-                                                               this.ctx.textAlign = "right";
-                                                       } else {
-                                                               labelStartX = this.left + this.options.labels.padding;
-                                                               this.ctx.textAlign = "left";
-                                                       }
-                                               }
-
-                                               this.ctx.textBaseline = "middle";
-                                               this.ctx.font = helpers.fontString(this.options.labels.fontSize, this.options.labels.fontStyle, this.options.labels.fontFamily);
-
-                                               helpers.each(this.labels, function(label, index) {
-                                                       var yValue = this.getPixelForValue(this.ticks[index]);
-                                                       this.ctx.fillText(label, labelStartX, yValue);
-                                               }, this);
-                                       }
-
-                                       if (this.options.scaleLabel.show) {
-                                               // Draw the scale label
-                                               var scaleLabelX = this.options.position == 'left' ? this.left + (this.options.scaleLabel.fontSize / 2) : this.right - (this.options.scaleLabel.fontSize / 2);
-                                               var scaleLabelY = this.top + ((this.bottom - this.top) / 2);
-                                               var rotation = this.options.position == 'left' ? -0.5 * Math.PI : 0.5 * Math.PI;
-
-                                               this.ctx.save();
-                                               this.ctx.translate(scaleLabelX, scaleLabelY);
-                                               this.ctx.rotate(rotation);
-                                               this.ctx.textAlign = "center";
-                                               this.ctx.font = helpers.fontString(this.options.scaleLabel.fontSize, this.options.scaleLabel.fontStyle, this.options.scaleLabel.fontFamily);
-                                               this.ctx.textBaseline = 'middle';
-                                               this.ctx.fillText(this.options.scaleLabel.labelString, 0, 0);
-                                               this.ctx.restore();
-                                       }
-                               }
-                       }
-               }
        });
        Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig);
 
index 26cb67739d5907f60ceb83e6fb9a9c6215ca59f0..912d12099bc9e48ca54ce42e38dcf969932a787b 100644 (file)
        };
 
        var TimeScale = Chart.Scale.extend({
-               parseTime: function(label) {
-                       // Date objects
-                       if (typeof label.getMonth === 'function' || typeof label == 'number') {
-                               return moment(label);
-                       }
-                       // Moment support
-                       if (label.isValid && label.isValid()) {
-                               return label;
-                       }
-                       // Custom parsing (return an instance of moment)
-                       if (typeof this.options.time.format !== 'string' && this.options.time.format.call) {
-                               return this.options.time.format(label);
-                       }
-                       // Moment format parsing
-                       return moment(label, this.options.time.format);
-               },
-               generateTicks: function(index) {
+               buildTicks: function(index) {
 
                        this.ticks = [];
                        this.labelMoments = [];
                                }
                        }
                },
-               getSmallestDataDistance: function() {
-                       return this.smallestLabelSeparation;
-               },
-               getPixelForValue: function(value, datasetIndex, includeOffset) {
-                       // This must be called after fit has been run so that 
-                       //      this.left, this.top, this.right, and this.bottom have been defined
+               getPixelForValue: function(value, index, datasetIndex, includeOffset) {
+
+                       var offset = this.labelMoments[index].diff(this.firstTick, this.tickUnit, true);
 
-                       var decimal = 0.5;
+                       var decimal = offset / this.tickRange;
 
                        if (this.isHorizontal()) {
                                var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
                                return this.top + (decimal * (this.height / this.ticks.length));
                        }
                },
-               // getPointPixelForValue: function(value, index, datasetIndex) {
-
-               //      var offset = this.labelMoments[index].diff(this.firstTick, this.tickUnit, true);
-               //      return this.getPixelForValue(value, offset / this.tickRange, datasetIndex);
-               // },
-
-               // // Functions needed for bar charts
-               // calculateBaseWidth: function() {
-
-               //      var base = this.getPixelForValue(null, this.smallestLabelSeparation / this.tickRange, 0, true) - this.getPixelForValue(null, 0, 0, true);
-               //      var spacing = 2 * this.options.categorySpacing;
-               //      if (base < spacing * 2) {
-               //              var mod = Math.min((spacing * 2) / base, 1.5);
-               //              base = (base / 2) * mod;
-               //              return base;
-               //      }
-               //      return base - spacing;
-               // },
-               // calculateBarWidth: function(barDatasetCount) {
-               //      //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
-               //      var baseWidth = this.calculateBaseWidth() - ((barDatasetCount - 1) * this.options.spacing);
-
-               //      if (this.options.stacked) {
-               //              return Math.max(baseWidth, 1);
-               //      }
-               //      return Math.max((baseWidth / barDatasetCount), 1);
-               // },
-               // calculateBarX: function(barDatasetCount, datasetIndex, elementIndex) {
-
-               //      var xWidth = this.calculateBaseWidth(),
-               //              offset = this.labelMoments[elementIndex].diff(this.firstTick, this.tickUnit, true),
-               //              xAbsolute = this.getPixelForValue(null, offset / this.tickRange, datasetIndex, true) - (xWidth / 2),
-               //              barWidth = this.calculateBarWidth(barDatasetCount);
-
-               //      if (this.options.stacked) {
-               //              return xAbsolute + barWidth / 2;
-               //      }
-
-               //      return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * this.options.spacing) + barWidth / 2;
-               // },
-
-               // calculateTickRotation: function(maxHeight, margins) {
-               //      //Get the width of each grid by calculating the difference
-               //      //between x offsets between 0 and 1.
-               //      var labelFont = helpers.fontString(this.options.ticks.fontSize, this.options.ticks.fontStyle, this.options.ticks.fontFamily);
-               //      this.ctx.font = labelFont;
-
-               //      var firstWidth = this.ctx.measureText(this.ticks[0]).width;
-               //      var lastWidth = this.ctx.measureText(this.ticks[this.ticks.length - 1]).width;
-               //      var firstRotated;
-               //      var lastRotated;
-
-               //      this.paddingRight = lastWidth / 2 + 3;
-               //      this.paddingLeft = firstWidth / 2 + 3;
-
-               //      this.labelRotation = 0;
-
-               //      if (this.options.display) {
-               //              var originalLabelWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
-               //              var cosRotation;
-               //              var sinRotation;
-               //              var firstRotatedWidth;
-
-               //              this.labelWidth = originalLabelWidth;
-
-               //              //Allow 3 pixels x2 padding either side for label readability
-               //              // only the index matters for a dataset scale, but we want a consistent interface between scales
-
-               //              var datasetWidth = Math.floor(this.getPixelForValue(null, 1 / this.ticks.length) - this.getPixelForValue(null, 0)) - 6;
-
-               //              //Max label rotation can be set or default to 90 - also act as a loop counter
-               //              while (this.labelWidth > datasetWidth && this.labelRotation <= this.options.ticks.maxRotation) {
-               //                      cosRotation = Math.cos(helpers.toRadians(this.labelRotation));
-               //                      sinRotation = Math.sin(helpers.toRadians(this.labelRotation));
-
-               //                      firstRotated = cosRotation * firstWidth;
-               //                      lastRotated = cosRotation * lastWidth;
-
-               //                      // We're right aligning the text now.
-               //                      if (firstRotated + this.options.ticks.fontSize / 2 > this.yLabelWidth) {
-               //                              this.paddingLeft = firstRotated + this.options.ticks.fontSize / 2;
-               //                      }
-
-               //                      this.paddingRight = this.options.ticks.fontSize / 2;
-
-               //                      if (sinRotation * originalLabelWidth > maxHeight) {
-               //                              // go back one step
-               //                              this.labelRotation--;
-               //                              break;
-               //                      }
-
-               //                      this.labelRotation++;
-               //                      this.labelWidth = cosRotation * originalLabelWidth;
-
-
-               //              }
-               //      } else {
-               //              this.labelWidth = 0;
-               //              this.paddingRight = 0;
-               //              this.paddingLeft = 0;
-               //      }
-
-               //      if (margins) {
-               //              this.paddingLeft -= margins.left;
-               //              this.paddingRight -= margins.right;
-
-               //              this.paddingLeft = Math.max(this.paddingLeft, 0);
-               //              this.paddingRight = Math.max(this.paddingRight, 0);
-               //      }
-
-               // },
-               // Fit this axis to the given size
-               // @param {number} maxWidth : the max width the axis can be
-               // @param {number} maxHeight: the max height the axis can be
-               // @return {object} minSize : the minimum size needed to draw the axis
-               fit: function(maxWidth, maxHeight, margins) {
-                       // Set the unconstrained dimension before label rotation
-                       if (this.isHorizontal()) {
-                               this.width = maxWidth;
-                       } else {
-                               this.height = maxHeight;
+               parseTime: function(label) {
+                       // Date objects
+                       if (typeof label.getMonth === 'function' || typeof label == 'number') {
+                               return moment(label);
                        }
-
-                       this.generateTicks();
-                       this.calculateTickRotation(maxHeight, margins);
-
-                       var minSize = {
-                               width: 0,
-                               height: 0,
-                       };
-
-                       var labelFont = helpers.fontString(this.options.ticks.fontSize, this.options.ticks.fontStyle, this.options.ticks.fontFamily);
-                       var longestLabelWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
-
-                       // Width
-                       if (this.isHorizontal()) {
-                               minSize.width = maxWidth;
-                       } else if (this.options.display) {
-                               var labelWidth = this.options.ticks.show ? longestLabelWidth + 6 : 0;
-                               minSize.width = Math.min(labelWidth, maxWidth);
+                       // Moment support
+                       if (label.isValid && label.isValid()) {
+                               return label;
                        }
-
-                       // Height
-                       if (this.isHorizontal() && this.options.display) {
-                               var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * longestLabelWidth) + 1.5 * this.options.ticks.fontSize;
-                               minSize.height = Math.min(this.options.ticks.show ? labelHeight : 0, maxHeight);
-                       } else if (this.options.display) {
-                               minSize.height = maxHeight;
+                       // Custom parsing (return an instance of moment)
+                       if (typeof this.options.time.format !== 'string' && this.options.time.format.call) {
+                               return this.options.time.format(label);
                        }
-
-                       this.width = minSize.width;
-                       this.height = minSize.height;
-                       return minSize;
+                       // Moment format parsing
+                       return moment(label, this.options.time.format);
                },
-               // Actualy draw the scale on the canvas
-               // @param {rectangle} chartArea : the area of the chart to draw full grid lines on
-               draw: function(chartArea) {
-                       if (this.options.display) {
-
-                               var setContextLineSettings;
-
-                               // Make sure we draw text in the correct color
-                               this.ctx.fillStyle = this.options.ticks.fontColor;
-
-                               if (this.isHorizontal()) {
-                                       setContextLineSettings = true;
-                                       var yTickStart = this.options.position == "bottom" ? this.top : this.bottom - 10;
-                                       var yTickEnd = this.options.position == "bottom" ? this.top + 10 : this.bottom;
-                                       var isRotated = this.labelRotation !== 0;
-                                       var skipRatio = false;
-
-                                       if ((this.options.ticks.fontSize + 4) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) {
-                                               skipRatio = 1 + Math.floor(((this.options.ticks.fontSize + 4) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight)));
-                                       }
-
-                                       helpers.each(this.ticks, function(tick, index) {
-                                               // Blank ticks
-                                               if ((skipRatio > 1 && index % skipRatio > 0) || (tick === undefined || tick === null)) {
-                                                       return;
-                                               }
-                                               var xLineValue = this.getPixelForValue(null, (1 / (this.ticks.length - 1)) * index, null, false); // xvalues for grid lines
-                                               var xLabelValue = this.getPixelForValue(null, (1 / (this.ticks.length - 1)) * index, null, true); // x values for ticks (need to consider offsetLabel option)
-
-                                               if (this.options.gridLines.show) {
-                                                       if (index === 0) {
-                                                               // Draw the first index specially
-                                                               this.ctx.lineWidth = this.options.gridLines.zeroLineWidth;
-                                                               this.ctx.strokeStyle = this.options.gridLines.zeroLineColor;
-                                                               setContextLineSettings = true; // reset next time
-                                                       } else if (setContextLineSettings) {
-                                                               this.ctx.lineWidth = this.options.gridLines.lineWidth;
-                                                               this.ctx.strokeStyle = this.options.gridLines.color;
-                                                               setContextLineSettings = false;
-                                                       }
-
-                                                       xLineValue += helpers.aliasPixel(this.ctx.lineWidth);
-
-                                                       // Draw the tick area
-                                                       this.ctx.beginPath();
-
-                                                       if (this.options.gridLines.drawTicks) {
-                                                               this.ctx.moveTo(xLineValue, yTickStart);
-                                                               this.ctx.lineTo(xLineValue, yTickEnd);
-                                                       }
-
-                                                       // Draw the chart area
-                                                       if (this.options.gridLines.drawOnChartArea) {
-                                                               this.ctx.moveTo(xLineValue, chartArea.top);
-                                                               this.ctx.lineTo(xLineValue, chartArea.bottom);
-                                                       }
-
-                                                       // Need to stroke in the loop because we are potentially changing line widths & colours
-                                                       this.ctx.stroke();
-                                               }
-
-                                               if (this.options.ticks.show) {
-                                                       this.ctx.save();
-                                                       this.ctx.translate(xLabelValue, (isRotated) ? this.top + 12 : this.top + 8);
-                                                       this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1);
-                                                       this.ctx.font = this.font;
-                                                       this.ctx.textAlign = (isRotated) ? "right" : "center";
-                                                       this.ctx.textBaseline = (isRotated) ? "middle" : "top";
-                                                       this.ctx.fillText(tick, 0, 0);
-                                                       this.ctx.restore();
-                                               }
-                                       }, this);
-                               } else {
-                                       // Vertical
-                                       if (this.options.gridLines.show) {}
-
-                                       if (this.options.ticks.show) {
-                                               // Draw the ticks
-                                       }
-                               }
-                       }
-               }
        });
        Chart.scaleService.registerScaleType("time", TimeScale, defaultConfig);