mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-21 07:36:52 +01:00
Merge pull request #1206 from etimberg/feature/v2.0-scale-refactor
Category scale now has defaults.
This commit is contained in:
@@ -12,38 +12,17 @@
|
||||
|
||||
scales: {
|
||||
xAxes: [{
|
||||
type: "category", // scatter should not use a dataset axis
|
||||
display: true,
|
||||
position: "bottom",
|
||||
id: "x-axis-1", // need an ID so datasets can reference the scale
|
||||
|
||||
type: "category",
|
||||
categorySpacing: 10,
|
||||
spacing: 1,
|
||||
|
||||
// grid line settings
|
||||
gridLines: {
|
||||
show: true,
|
||||
color: "rgba(0, 0, 0, 0.05)",
|
||||
lineWidth: 1,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true,
|
||||
zeroLineWidth: 1,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
offsetGridLines: true,
|
||||
},
|
||||
|
||||
// label settings
|
||||
labels: {
|
||||
show: true,
|
||||
template: "<%=value%>",
|
||||
fontSize: 12,
|
||||
fontStyle: "normal",
|
||||
fontColor: "#666",
|
||||
fontFamily: "Helvetica Neue",
|
||||
},
|
||||
}],
|
||||
yAxes: [{
|
||||
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
||||
type: "linear",
|
||||
display: true,
|
||||
position: "left",
|
||||
id: "y-axis-1",
|
||||
|
||||
@@ -13,31 +13,6 @@
|
||||
scales: {
|
||||
xAxes: [{
|
||||
type: "category", // scatter should not use a dataset axis
|
||||
display: true,
|
||||
position: "bottom",
|
||||
id: "x-axis-1", // need an ID so datasets can reference the scale
|
||||
|
||||
// grid line settings
|
||||
gridLines: {
|
||||
show: true,
|
||||
color: "rgba(0, 0, 0, 0.05)",
|
||||
lineWidth: 1,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true,
|
||||
zeroLineWidth: 1,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
offsetGridLines: false,
|
||||
},
|
||||
|
||||
// label settings
|
||||
labels: {
|
||||
show: true,
|
||||
template: "<%=value%>",
|
||||
fontSize: 12,
|
||||
fontStyle: "normal",
|
||||
fontColor: "#666",
|
||||
fontFamily: "Helvetica Neue",
|
||||
},
|
||||
}],
|
||||
yAxes: [{
|
||||
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
||||
|
||||
@@ -108,7 +108,9 @@
|
||||
var objClone = {};
|
||||
each(obj, function(value, key) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
if (helpers.isArray(value)) {
|
||||
objClone[key] = value.slice(0);
|
||||
} else if (typeof value === 'object' && value !== null) {
|
||||
objClone[key] = clone(value);
|
||||
} else {
|
||||
objClone[key] = value;
|
||||
@@ -139,21 +141,28 @@
|
||||
helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {
|
||||
helpers.each(extension, function(value, key) {
|
||||
if (extension.hasOwnProperty(key)) {
|
||||
if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) {
|
||||
if (key === 'scales') {
|
||||
// Scale config merging is complex. Add out own function here for that
|
||||
base[key] = helpers.scaleMerge(base.hasOwnProperty(key) ? base[key] : {}, value);
|
||||
|
||||
} else if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) {
|
||||
// In this case we have an array of objects replacing another array. Rather than doing a strict replace,
|
||||
// merge. This allows easy scale option merging
|
||||
var baseArray = base[key];
|
||||
|
||||
helpers.each(value, function(valueObj, index) {
|
||||
|
||||
if (index < baseArray.length) {
|
||||
baseArray[index] = helpers.configMerge(baseArray[index], valueObj);
|
||||
} else {
|
||||
baseArray.push(valueObj); // nothing to merge
|
||||
}
|
||||
});
|
||||
|
||||
} else if (base.hasOwnProperty(key) && typeof base[key] == "object" && base[key] !== null && typeof value == "object") {
|
||||
// If we are overwriting an object with an object, do a merge of the properties.
|
||||
base[key] = helpers.configMerge(base[key], value);
|
||||
|
||||
} else {
|
||||
// can just overwrite the value in this case
|
||||
base[key] = value;
|
||||
@@ -164,6 +173,44 @@
|
||||
|
||||
return base;
|
||||
},
|
||||
scaleMerge = helpers.scaleMerge = function(_base, extension) {
|
||||
var base = clone(_base);
|
||||
|
||||
helpers.each(extension, function(value, key) {
|
||||
if (extension.hasOwnProperty(key)) {
|
||||
if (key === 'xAxes' || key === 'yAxes') {
|
||||
// These properties are arrays of items
|
||||
if (base.hasOwnProperty(key)) {
|
||||
helpers.each(value, function(valueObj, index) {
|
||||
if (index >= base[key].length || !base[key][index].type) {
|
||||
base[key].push(helpers.configMerge(valueObj.type ? Chart.scaleService.getScaleDefaults(valueObj.type) : {}, valueObj));
|
||||
} else if (valueObj.type !== base[key][index].type) {
|
||||
// Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults
|
||||
base[key][index] = helpers.configMerge(base[key][index], valueObj.type ? Chart.scaleService.getScaleDefaults(valueObj.type) : {}, valueObj)
|
||||
} else {
|
||||
// Type is the same
|
||||
base[key][index] = helpers.configMerge(base[key][index], valueObj);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
base[key] = [];
|
||||
helpers.each(value, function(valueObj) {
|
||||
base[key].push(helpers.configMerge(valueObj.type ? Chart.scaleService.getScaleDefaults(valueObj.type) : {}, valueObj));
|
||||
});
|
||||
}
|
||||
} else if (base.hasOwnProperty(key) && typeof base[key] == "object" && base[key] !== null && typeof value == "object") {
|
||||
// If we are overwriting an object with an object, do a merge of the properties.
|
||||
base[key] = helpers.configMerge(base[key], value);
|
||||
|
||||
} else {
|
||||
// can just overwrite the value in this case
|
||||
base[key] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return base;
|
||||
},
|
||||
getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {
|
||||
if (!value) {
|
||||
return defaultValue;
|
||||
|
||||
@@ -14,13 +14,18 @@
|
||||
constructors: {},
|
||||
// Use a registration function so that we can move to an ES6 map when we no longer need to support
|
||||
// old browsers
|
||||
registerScaleType: function(type, scaleConstructor) {
|
||||
// Scale config defaults
|
||||
defaults: {},
|
||||
registerScaleType: function(type, scaleConstructor, defaults) {
|
||||
this.constructors[type] = scaleConstructor;
|
||||
this.defaults[type] = defaults;
|
||||
},
|
||||
getScaleConstructor: function(type) {
|
||||
return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
|
||||
},
|
||||
|
||||
getScaleDefaults: function(type) {
|
||||
return this.defaults.hasOwnProperty(type) ? this.defaults[type] : {};
|
||||
},
|
||||
// The interesting function
|
||||
fitScalesForChart: function(chartInstance, width, height) {
|
||||
var xPadding = width > 30 ? 5 : 2;
|
||||
@@ -40,44 +45,6 @@
|
||||
return scaleInstance.options.position == "bottom";
|
||||
});
|
||||
|
||||
var visibleLeftScales = helpers.where(chartInstance.scales, function(scaleInstance) {
|
||||
return scaleInstance.options.position == "left";
|
||||
});
|
||||
var visibleRightScales = helpers.where(chartInstance.scales, function(scaleInstance) {
|
||||
return scaleInstance.options.position == "right";
|
||||
});
|
||||
var visibleTopScales = helpers.where(chartInstance.scales, function(scaleInstance) {
|
||||
return scaleInstance.options.position == "top";
|
||||
});
|
||||
var visibleBottomScales = helpers.where(chartInstance.scales, function(scaleInstance) {
|
||||
return scaleInstance.options.position == "bottom";
|
||||
});
|
||||
|
||||
// // Adjust the padding to take into account displaying labels
|
||||
// if (topScales.length === 0 || bottomScales.length === 0) {
|
||||
// var maxFontHeight = 0;
|
||||
|
||||
// var maxFontHeightFunction = function(scaleInstance) {
|
||||
// if (scaleInstance.options.labels.show) {
|
||||
// // Only consider font sizes for axes that actually show labels
|
||||
// maxFontHeight = Math.max(maxFontHeight, scaleInstance.options.labels.fontSize);
|
||||
// }
|
||||
// };
|
||||
|
||||
// helpers.each(leftScales, maxFontHeightFunction);
|
||||
// helpers.each(rightScales, maxFontHeightFunction);
|
||||
|
||||
// if (topScales.length === 0) {
|
||||
// // Add padding so that we can handle drawing the top nicely
|
||||
// yPadding += 0.75 * maxFontHeight; // 0.75 since padding added on both sides
|
||||
// }
|
||||
|
||||
// if (bottomScales.length === 0) {
|
||||
// // Add padding so that we can handle drawing the bottom nicely
|
||||
// yPadding += 1.5 * maxFontHeight;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Essentially we now have any number of scales on each of the 4 sides.
|
||||
// Our canvas looks like the following.
|
||||
// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
|
||||
|
||||
@@ -5,6 +5,35 @@
|
||||
Chart = root.Chart,
|
||||
helpers = Chart.helpers;
|
||||
|
||||
// Default config for a category scale
|
||||
var defaultConfig = {
|
||||
display: true,
|
||||
position: "bottom",
|
||||
id: "x-axis-1", // need an ID so datasets can reference the scale
|
||||
|
||||
// grid line settings
|
||||
gridLines: {
|
||||
show: true,
|
||||
color: "rgba(0, 0, 0, 0.1)",
|
||||
lineWidth: 1,
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true,
|
||||
zeroLineWidth: 1,
|
||||
zeroLineColor: "rgba(0,0,0,0.25)",
|
||||
offsetGridLines: false,
|
||||
},
|
||||
|
||||
// label settings
|
||||
labels: {
|
||||
show: true,
|
||||
template: "<%=value%>",
|
||||
fontSize: 12,
|
||||
fontStyle: "normal",
|
||||
fontColor: "#666",
|
||||
fontFamily: "Helvetica Neue",
|
||||
},
|
||||
};
|
||||
|
||||
var DatasetScale = Chart.Element.extend({
|
||||
isHorizontal: function() {
|
||||
return this.options.position == "top" || this.options.position == "bottom";
|
||||
@@ -233,5 +262,5 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
Chart.scaleService.registerScaleType("category", DatasetScale);
|
||||
Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig);
|
||||
}).call(this);
|
||||
|
||||
Reference in New Issue
Block a user