Merge pull request #1206 from etimberg/feature/v2.0-scale-refactor

Category scale now has defaults.
This commit is contained in:
Evert Timberg
2015-06-13 13:33:05 -04:00
5 changed files with 88 additions and 91 deletions

View File

@@ -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",

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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);