Allow ticks.fixedStepSize or ticks.stepSize options to mean the same thing

This commit is contained in:
Evert Timberg 2016-03-06 08:56:31 -05:00
parent a16093e51c
commit 9bcc3ca34c
6 changed files with 178 additions and 116 deletions

81
dist/Chart.bundle.js vendored
View File

@ -5886,6 +5886,7 @@ module.exports = function(Chart) {
legend: {
labels: {
generateLabels: function(data) {
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
return {
text: label,
@ -5896,6 +5897,9 @@ module.exports = function(Chart) {
index: i
};
});
} else {
return [];
}
}
},
onClick: function(e, legendItem) {
@ -6425,6 +6429,7 @@ module.exports = function(Chart) {
legend: {
labels: {
generateLabels: function(data) {
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
return {
text: label,
@ -6435,6 +6440,9 @@ module.exports = function(Chart) {
index: i
};
});
} else {
return [];
}
}
},
onClick: function(e, legendItem) {
@ -9818,10 +9826,6 @@ module.exports = function(Chart) {
skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight)));
}
if (!useAutoskipper) {
skipRatio = false;
}
// if they defined a max number of ticks,
// increase skipRatio until that number is met
if (maxTicks && this.ticks.length > maxTicks) {
@ -9833,6 +9837,10 @@ module.exports = function(Chart) {
}
}
if (!useAutoskipper) {
skipRatio = false;
}
helpers.each(this.ticks, function(label, index) {
// Blank ticks
var isLastTick = this.ticks.length === index + 1;
@ -11584,9 +11592,9 @@ module.exports = function(Chart) {
// for details.
var spacing;
var fixedStepSizeSet = this.options.ticks.fixedStepSize && this.options.ticks.fixedStepSize > 0;
var fixedStepSizeSet = (this.options.ticks.fixedStepSize && this.options.ticks.fixedStepSize > 0) || (this.options.ticks.stepSize && this.options.ticks.stepSize > 0);
if (fixedStepSizeSet) {
spacing = this.options.ticks.fixedStepSize;
spacing = helpers.getValueOrDefault(this.options.ticks.fixedStepSize, this.options.ticks.stepSize);
} else {
var niceRange = helpers.niceNum(this.max - this.min, false);
spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);
@ -12345,7 +12353,8 @@ module.exports = function(Chart) {
position: "bottom",
time: {
format: false, // false == date objects or use pattern string from http://momentjs.com/docs/#/parsing/string-format/
parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment
format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/
unit: false, // false == automatic or override with week, month, year, etc.
round: false, // none, or override with week, month, year, etc.
displayFormat: false, // DEPRECATED
@ -12434,22 +12443,30 @@ module.exports = function(Chart) {
this.ticks = [];
this.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step
this.scaleSizeInUnits = 0; // How large the scale is in the base unit (seconds, minutes, etc)
// Set unit override if applicable
if (this.options.time.unit) {
this.tickUnit = this.options.time.unit || 'day';
this.displayFormat = this.options.time.displayFormats[this.tickUnit];
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit, true));
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true);
this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, 1);
} else {
// Determine the smallest needed unit of the time
var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);
var innerWidth = this.isHorizontal() ? this.width - (this.paddingLeft + this.paddingRight) : this.height - (this.paddingTop + this.paddingBottom);
var labelCapacity = innerWidth / (tickFontSize + 10);
var buffer = this.options.time.round ? 0 : 1;
// Crude approximation of what the label length might be
var tempFirstLabel = this.tickFormatFunction(this.firstTick, 0, []);
var tickLabelWidth = tempFirstLabel.length * tickFontSize;
var cosRotation = Math.cos(helpers.toRadians(this.options.ticks.maxRotation));
var sinRotation = Math.sin(helpers.toRadians(this.options.ticks.maxRotation));
tickLabelWidth = (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
var labelCapacity = innerWidth / (tickLabelWidth + 10);
// Start as small as possible
this.tickUnit = 'millisecond';
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit, true) + buffer);
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true);
this.displayFormat = this.options.time.displayFormats[this.tickUnit];
var unitDefinitionIndex = 0;
@ -12460,19 +12477,19 @@ module.exports = function(Chart) {
// Can we scale this unit. If `false` we can scale infinitely
this.unitScale = 1;
if (helpers.isArray(unitDefinition.steps) && Math.ceil(this.tickRange / labelCapacity) < helpers.max(unitDefinition.steps)) {
if (helpers.isArray(unitDefinition.steps) && Math.ceil(this.scaleSizeInUnits / labelCapacity) < helpers.max(unitDefinition.steps)) {
// Use one of the prefedined steps
for (var idx = 0; idx < unitDefinition.steps.length; ++idx) {
if (unitDefinition.steps[idx] > Math.ceil(this.tickRange / labelCapacity)) {
this.unitScale = unitDefinition.steps[idx];
if (unitDefinition.steps[idx] > Math.ceil(this.scaleSizeInUnits / labelCapacity)) {
this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, unitDefinition.steps[idx]);
break;
}
}
break;
} else if ((unitDefinition.maxStep === false) || (Math.ceil(this.tickRange / labelCapacity) < unitDefinition.maxStep)) {
} else if ((unitDefinition.maxStep === false) || (Math.ceil(this.scaleSizeInUnits / labelCapacity) < unitDefinition.maxStep)) {
// We have a max step. Scale this unit
this.unitScale = Math.ceil(this.tickRange / labelCapacity);
this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, Math.ceil(this.scaleSizeInUnits / labelCapacity));
break;
} else {
// Move to the next unit up
@ -12480,7 +12497,7 @@ module.exports = function(Chart) {
unitDefinition = time.units[unitDefinitionIndex];
this.tickUnit = unitDefinition.name;
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit) + buffer);
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true);
this.displayFormat = this.options.time.displayFormats[unitDefinition.name];
}
}
@ -12518,7 +12535,7 @@ module.exports = function(Chart) {
this.ticks.push(this.firstTick.clone());
// For every unit in between the first and last moment, create a moment and add it to the ticks tick
for (var i = 1; i < this.tickRange; ++i) {
for (var i = 1; i < this.scaleSizeInUnits; ++i) {
var newTick = roundedStart.clone().add(i, this.tickUnit);
// Are we greater than the max time
@ -12532,13 +12549,18 @@ module.exports = function(Chart) {
}
// Always show the right tick
if (this.ticks[this.ticks.length - 1].diff(this.lastTick, this.tickUnit) !== 0 || this.scaleSizeInUnits === 0) {
// this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart
// but the last tick was not rounded.
if (this.options.time.max) {
this.ticks.push(this.lastTick.clone());
} else if (this.ticks[this.ticks.length - 1].diff(this.lastTick, this.tickUnit, true) !== 0) {
this.tickRange = Math.ceil(this.tickRange / this.unitScale) * this.unitScale;
this.ticks.push(this.firstTick.clone().add(this.tickRange, this.tickUnit));
this.scaleSizeInUnits = this.lastTick.diff(this.ticks[0], this.tickUnit, true);
} else {
this.scaleSizeInUnits = Math.ceil(this.scaleSizeInUnits / this.unitScale) * this.unitScale;
this.ticks.push(this.firstTick.clone().add(this.scaleSizeInUnits, this.tickUnit));
this.lastTick = this.ticks[this.ticks.length - 1].clone();
}
}
},
// Get tooltip label
getLabelForIndex: function(index, datasetIndex) {
@ -12555,8 +12577,8 @@ module.exports = function(Chart) {
return label;
},
convertTicksToLabels: function() {
this.ticks = this.ticks.map(function(tick, index, ticks) {
// Function to format an individual tick mark
tickFormatFunction: function tickFormatFunction(tick, index, ticks) {
var formattedTick = tick.format(this.displayFormat);
if (this.options.ticks.userCallback) {
@ -12564,7 +12586,9 @@ module.exports = function(Chart) {
} else {
return formattedTick;
}
}, this);
},
convertTicksToLabels: function() {
this.ticks = this.ticks.map(this.tickFormatFunction, this);
},
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
var labelMoment = this.getLabelMoment(datasetIndex, index);
@ -12572,7 +12596,7 @@ module.exports = function(Chart) {
if (labelMoment) {
var offset = labelMoment.diff(this.firstTick, this.tickUnit, true);
var decimal = offset / this.tickRange;
var decimal = offset / this.scaleSizeInUnits;
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
@ -12590,6 +12614,12 @@ module.exports = function(Chart) {
}
},
parseTime: function(label) {
if (typeof this.options.time.parser === 'string') {
return moment(label, this.options.time.parser);
}
if (typeof this.options.time.parser === 'function') {
return this.options.time.parser(label);
}
// Date objects
if (typeof label.getMonth === 'function' || typeof label === 'number') {
return moment(label);
@ -12600,6 +12630,7 @@ module.exports = function(Chart) {
}
// Custom parsing (return an instance of moment)
if (typeof this.options.time.format !== 'string' && this.options.time.format.call) {
console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale");
return this.options.time.format(label);
}
// Moment format parsing

File diff suppressed because one or more lines are too long

81
dist/Chart.js vendored
View File

@ -2281,6 +2281,7 @@ module.exports = function(Chart) {
legend: {
labels: {
generateLabels: function(data) {
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
return {
text: label,
@ -2291,6 +2292,9 @@ module.exports = function(Chart) {
index: i
};
});
} else {
return [];
}
}
},
onClick: function(e, legendItem) {
@ -2820,6 +2824,7 @@ module.exports = function(Chart) {
legend: {
labels: {
generateLabels: function(data) {
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
return {
text: label,
@ -2830,6 +2835,9 @@ module.exports = function(Chart) {
index: i
};
});
} else {
return [];
}
}
},
onClick: function(e, legendItem) {
@ -6213,10 +6221,6 @@ module.exports = function(Chart) {
skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight)));
}
if (!useAutoskipper) {
skipRatio = false;
}
// if they defined a max number of ticks,
// increase skipRatio until that number is met
if (maxTicks && this.ticks.length > maxTicks) {
@ -6228,6 +6232,10 @@ module.exports = function(Chart) {
}
}
if (!useAutoskipper) {
skipRatio = false;
}
helpers.each(this.ticks, function(label, index) {
// Blank ticks
var isLastTick = this.ticks.length === index + 1;
@ -7979,9 +7987,9 @@ module.exports = function(Chart) {
// for details.
var spacing;
var fixedStepSizeSet = this.options.ticks.fixedStepSize && this.options.ticks.fixedStepSize > 0;
var fixedStepSizeSet = (this.options.ticks.fixedStepSize && this.options.ticks.fixedStepSize > 0) || (this.options.ticks.stepSize && this.options.ticks.stepSize > 0);
if (fixedStepSizeSet) {
spacing = this.options.ticks.fixedStepSize;
spacing = helpers.getValueOrDefault(this.options.ticks.fixedStepSize, this.options.ticks.stepSize);
} else {
var niceRange = helpers.niceNum(this.max - this.min, false);
spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);
@ -8740,7 +8748,8 @@ module.exports = function(Chart) {
position: "bottom",
time: {
format: false, // false == date objects or use pattern string from http://momentjs.com/docs/#/parsing/string-format/
parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment
format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/
unit: false, // false == automatic or override with week, month, year, etc.
round: false, // none, or override with week, month, year, etc.
displayFormat: false, // DEPRECATED
@ -8829,22 +8838,30 @@ module.exports = function(Chart) {
this.ticks = [];
this.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step
this.scaleSizeInUnits = 0; // How large the scale is in the base unit (seconds, minutes, etc)
// Set unit override if applicable
if (this.options.time.unit) {
this.tickUnit = this.options.time.unit || 'day';
this.displayFormat = this.options.time.displayFormats[this.tickUnit];
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit, true));
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true);
this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, 1);
} else {
// Determine the smallest needed unit of the time
var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);
var innerWidth = this.isHorizontal() ? this.width - (this.paddingLeft + this.paddingRight) : this.height - (this.paddingTop + this.paddingBottom);
var labelCapacity = innerWidth / (tickFontSize + 10);
var buffer = this.options.time.round ? 0 : 1;
// Crude approximation of what the label length might be
var tempFirstLabel = this.tickFormatFunction(this.firstTick, 0, []);
var tickLabelWidth = tempFirstLabel.length * tickFontSize;
var cosRotation = Math.cos(helpers.toRadians(this.options.ticks.maxRotation));
var sinRotation = Math.sin(helpers.toRadians(this.options.ticks.maxRotation));
tickLabelWidth = (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
var labelCapacity = innerWidth / (tickLabelWidth + 10);
// Start as small as possible
this.tickUnit = 'millisecond';
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit, true) + buffer);
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true);
this.displayFormat = this.options.time.displayFormats[this.tickUnit];
var unitDefinitionIndex = 0;
@ -8855,19 +8872,19 @@ module.exports = function(Chart) {
// Can we scale this unit. If `false` we can scale infinitely
this.unitScale = 1;
if (helpers.isArray(unitDefinition.steps) && Math.ceil(this.tickRange / labelCapacity) < helpers.max(unitDefinition.steps)) {
if (helpers.isArray(unitDefinition.steps) && Math.ceil(this.scaleSizeInUnits / labelCapacity) < helpers.max(unitDefinition.steps)) {
// Use one of the prefedined steps
for (var idx = 0; idx < unitDefinition.steps.length; ++idx) {
if (unitDefinition.steps[idx] > Math.ceil(this.tickRange / labelCapacity)) {
this.unitScale = unitDefinition.steps[idx];
if (unitDefinition.steps[idx] > Math.ceil(this.scaleSizeInUnits / labelCapacity)) {
this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, unitDefinition.steps[idx]);
break;
}
}
break;
} else if ((unitDefinition.maxStep === false) || (Math.ceil(this.tickRange / labelCapacity) < unitDefinition.maxStep)) {
} else if ((unitDefinition.maxStep === false) || (Math.ceil(this.scaleSizeInUnits / labelCapacity) < unitDefinition.maxStep)) {
// We have a max step. Scale this unit
this.unitScale = Math.ceil(this.tickRange / labelCapacity);
this.unitScale = helpers.getValueOrDefault(this.options.time.unitStepSize, Math.ceil(this.scaleSizeInUnits / labelCapacity));
break;
} else {
// Move to the next unit up
@ -8875,7 +8892,7 @@ module.exports = function(Chart) {
unitDefinition = time.units[unitDefinitionIndex];
this.tickUnit = unitDefinition.name;
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit) + buffer);
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true);
this.displayFormat = this.options.time.displayFormats[unitDefinition.name];
}
}
@ -8913,7 +8930,7 @@ module.exports = function(Chart) {
this.ticks.push(this.firstTick.clone());
// For every unit in between the first and last moment, create a moment and add it to the ticks tick
for (var i = 1; i < this.tickRange; ++i) {
for (var i = 1; i < this.scaleSizeInUnits; ++i) {
var newTick = roundedStart.clone().add(i, this.tickUnit);
// Are we greater than the max time
@ -8927,13 +8944,18 @@ module.exports = function(Chart) {
}
// Always show the right tick
if (this.ticks[this.ticks.length - 1].diff(this.lastTick, this.tickUnit) !== 0 || this.scaleSizeInUnits === 0) {
// this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart
// but the last tick was not rounded.
if (this.options.time.max) {
this.ticks.push(this.lastTick.clone());
} else if (this.ticks[this.ticks.length - 1].diff(this.lastTick, this.tickUnit, true) !== 0) {
this.tickRange = Math.ceil(this.tickRange / this.unitScale) * this.unitScale;
this.ticks.push(this.firstTick.clone().add(this.tickRange, this.tickUnit));
this.scaleSizeInUnits = this.lastTick.diff(this.ticks[0], this.tickUnit, true);
} else {
this.scaleSizeInUnits = Math.ceil(this.scaleSizeInUnits / this.unitScale) * this.unitScale;
this.ticks.push(this.firstTick.clone().add(this.scaleSizeInUnits, this.tickUnit));
this.lastTick = this.ticks[this.ticks.length - 1].clone();
}
}
},
// Get tooltip label
getLabelForIndex: function(index, datasetIndex) {
@ -8950,8 +8972,8 @@ module.exports = function(Chart) {
return label;
},
convertTicksToLabels: function() {
this.ticks = this.ticks.map(function(tick, index, ticks) {
// Function to format an individual tick mark
tickFormatFunction: function tickFormatFunction(tick, index, ticks) {
var formattedTick = tick.format(this.displayFormat);
if (this.options.ticks.userCallback) {
@ -8959,7 +8981,9 @@ module.exports = function(Chart) {
} else {
return formattedTick;
}
}, this);
},
convertTicksToLabels: function() {
this.ticks = this.ticks.map(this.tickFormatFunction, this);
},
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
var labelMoment = this.getLabelMoment(datasetIndex, index);
@ -8967,7 +8991,7 @@ module.exports = function(Chart) {
if (labelMoment) {
var offset = labelMoment.diff(this.firstTick, this.tickUnit, true);
var decimal = offset / this.tickRange;
var decimal = offset / this.scaleSizeInUnits;
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
@ -8985,6 +9009,12 @@ module.exports = function(Chart) {
}
},
parseTime: function(label) {
if (typeof this.options.time.parser === 'string') {
return moment(label, this.options.time.parser);
}
if (typeof this.options.time.parser === 'function') {
return this.options.time.parser(label);
}
// Date objects
if (typeof label.getMonth === 'function' || typeof label === 'number') {
return moment(label);
@ -8995,6 +9025,7 @@ module.exports = function(Chart) {
}
// Custom parsing (return an instance of moment)
if (typeof this.options.time.format !== 'string' && this.options.time.format.call) {
console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale");
return this.options.time.format(label);
}
// Moment format parsing

10
dist/Chart.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -134,7 +134,7 @@ It also provides additional configuration options:
Name | Type | Default | Description
--- |:---:| --- | ---
*ticks*.fixedStepSize | Number | - | User defined fixed step size for the scale. If set, the scale ticks will be enumerated by multiple of fixedStepSize, having one tick per increment. If not set, the ticks are labeled automatically using the nice numbers algorithm.
*ticks*.stepSize | Number | - | User defined fixed step size for the scale. If set, the scale ticks will be enumerated by multiple of stepSize, having one tick per increment. If not set, the ticks are labeled automatically using the nice numbers algorithm.
#### Logarithmic Scale
The logarithmic scale is used to display logarithmic data of course. It can be placed on either the x or y axis.

View File

@ -177,9 +177,9 @@ module.exports = function(Chart) {
// for details.
var spacing;
var fixedStepSizeSet = this.options.ticks.fixedStepSize && this.options.ticks.fixedStepSize > 0;
var fixedStepSizeSet = (this.options.ticks.fixedStepSize && this.options.ticks.fixedStepSize > 0) || (this.options.ticks.stepSize && this.options.ticks.stepSize > 0);
if (fixedStepSizeSet) {
spacing = this.options.ticks.fixedStepSize;
spacing = helpers.getValueOrDefault(this.options.ticks.fixedStepSize, this.options.ticks.stepSize);
} else {
var niceRange = helpers.niceNum(this.max - this.min, false);
spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);