Skip to content

Commit

Permalink
Introduce option update
Browse files Browse the repository at this point in the history
- allow options be updated inplace or as a new object
- remerge new options and rebuild scales&tooltips
- preserve reference to old scale if id/type not changed
- related tests and new sample also added.
  • Loading branch information
xg-wang committed Aug 21, 2017
1 parent 4697226 commit 123bf03
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 25 deletions.
3 changes: 3 additions & 0 deletions samples/samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@
}, {
title: 'Non numeric Y Axis',
path: 'scales/non-numeric-y.html'
}, {
title: 'Toggle Scale Type',
path: 'scales/toggle-scale-type.html'
}]
}, {
title: 'Legend',
Expand Down
104 changes: 104 additions & 0 deletions samples/scales/toggle-scale-type.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<!doctype html>
<html>

<head>
<title>Toggle Scale Type</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>

<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<button id="toggleScale">Toggle Scale Type</button>
<script>
var randomScalingFactor = function() {
return Math.ceil(Math.random() * 10.0) * Math.pow(10, Math.ceil(Math.random() * 5));
};

var type = 'linear';

var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Second dataset",
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}]
},
options: {
responsive: true,
title:{
display: true,
text: 'Chart.js Line Chart - ' + type
},
scales: {
xAxes: [{
display: true,
}],
yAxes: [{
display: true,
type: type
}]
}
}
};

window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};

document.getElementById('toggleScale').addEventListener('click', function() {
type = type === 'linear' ? 'logarithmic' : 'linear';
window.myLine.options.title.text = 'Chart.js Line Chart - ' + type;
window.myLine.options.scales = {
xAxes: [{
display: true
}],
yAxes: [{
display: true,
type: type
}]
}

window.myLine.update();
});
</script>
</body>

</html>
74 changes: 51 additions & 23 deletions src/core/core.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,21 @@ module.exports = function(Chart) {
function updateConfig(chart) {
var newOptions = chart.options;

// Update Scale(s) with options
if (newOptions.scale) {
chart.scale.options = newOptions.scale;
} else if (newOptions.scales) {
newOptions.scales.xAxes.concat(newOptions.scales.yAxes).forEach(function(scaleOptions) {
chart.scales[scaleOptions.id].options = scaleOptions;
});
}

helpers.each(chart.scales, function(scale) {
Chart.layoutService.removeBox(chart, scale);
});

newOptions = helpers.configMerge(
Chart.defaults.global,
Chart.defaults[chart.config.type],
newOptions);

chart.options = chart.config.options = newOptions;
chart.ensureScalesHaveIDs();
chart.buildOrUpdateScales();
// Tooltip
chart.tooltip._options = newOptions.tooltips;
chart.tooltip.initialize();
}

function positionIsHorizontal(position) {
Expand Down Expand Up @@ -143,7 +147,7 @@ module.exports = function(Chart) {

// Make sure scales have IDs and are built before we build any controllers.
me.ensureScalesHaveIDs();
me.buildScales();
me.buildOrUpdateScales();
me.initToolTip();

// After init plugin notification
Expand Down Expand Up @@ -223,11 +227,15 @@ module.exports = function(Chart) {
/**
* Builds a map of scale ID to scale object for future lookup.
*/
buildScales: function() {
buildOrUpdateScales: function() {
var me = this;
var options = me.options;
var scales = me.scales = {};
var scales = me.scales || {};
var items = [];
var updated = Object.keys(scales).reduce(function(obj, id) {
obj[id] = false;
return obj;
}, {});

if (options.scales) {
items = items.concat(
Expand All @@ -251,24 +259,35 @@ module.exports = function(Chart) {

helpers.each(items, function(item) {
var scaleOptions = item.options;
var id = scaleOptions.id;
var scaleType = helpers.valueOrDefault(scaleOptions.type, item.dtype);
var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
if (!scaleClass) {
return;
}

if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
scaleOptions.position = item.dposition;
}

var scale = new scaleClass({
id: scaleOptions.id,
options: scaleOptions,
ctx: me.ctx,
chart: me
});
updated[id] = true;
var scale = null;
if (id in scales && scales[id].type === scaleType) {
scale = scales[id];
scale.options = scaleOptions;
scale.ctx = me.ctx;
scale.chart = me;
} else {
var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
if (!scaleClass) {
return;
}
scale = new scaleClass({
id: id,
type: scaleType,
options: scaleOptions,
ctx: me.ctx,
chart: me
});
scales[scale.id] = scale;
}

scales[scale.id] = scale;
scale.mergeTicksOptions();

// TODO(SB): I think we should be able to remove this custom case (options.scale)
Expand All @@ -278,6 +297,14 @@ module.exports = function(Chart) {
me.scale = scale;
}
});
// clear up discarded scales
helpers.each(updated, function(hasUpdated, id) {
if (!hasUpdated) {
delete scales[id];
}
});

me.scales = scales;

Chart.scaleService.addScalesToLayout(this);
},
Expand All @@ -301,6 +328,7 @@ module.exports = function(Chart) {

if (meta.controller) {
meta.controller.updateIndex(datasetIndex);
meta.controller.linkScales();
} else {
var ControllerClass = Chart.controllers[meta.type];
if (ControllerClass === undefined) {
Expand Down
4 changes: 2 additions & 2 deletions src/core/core.datasetController.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ module.exports = function(Chart) {
var meta = me.getMeta();
var dataset = me.getDataset();

if (meta.xAxisID === null) {
if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) {
meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
}
if (meta.yAxisID === null) {
if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) {
meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;
}
},
Expand Down
105 changes: 105 additions & 0 deletions test/specs/core.controller.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,38 @@ describe('Chart', function() {
});

describe('config update', function() {
it ('should update options', function() {
var chart = acquireChart({
type: 'line',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
data: [10, 20, 30, 100]
}]
},
options: {
responsive: true
}
});

chart.options = {
responsive: false,
scales: {
yAxes: [{
ticks: {
min: 0,
max: 10
}
}]
}
};
chart.update();

var yScale = chart.scales['y-axis-0'];
expect(yScale.options.ticks.min).toBe(0);
expect(yScale.options.ticks.max).toBe(10);
});

it ('should update scales options', function() {
var chart = acquireChart({
type: 'line',
Expand All @@ -759,6 +791,79 @@ describe('Chart', function() {
expect(yScale.options.ticks.max).toBe(10);
});

it ('should update scales options from new object', function() {
var chart = acquireChart({
type: 'line',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
data: [10, 20, 30, 100]
}]
},
options: {
responsive: true
}
});

var newScalesConfig = {
yAxes: [{
ticks: {
min: 0,
max: 10
}
}]
};
chart.options.scales = newScalesConfig;

chart.update();

var yScale = chart.scales['y-axis-0'];
expect(yScale.options.ticks.min).toBe(0);
expect(yScale.options.ticks.max).toBe(10);
});

it ('should remove discarded scale', function() {
var chart = acquireChart({
type: 'line',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
data: [10, 20, 30, 100]
}]
},
options: {
responsive: true,
scales: {
yAxes: [{
id: 'yAxis0',
ticks: {
min: 0,
max: 10
}
}]
}
}
});

var newScalesConfig = {
yAxes: [{
ticks: {
min: 0,
max: 10
}
}]
};
chart.options.scales = newScalesConfig;

chart.update();

var yScale = chart.scales.yAxis0;
expect(yScale).toBeUndefined();
var newyScale = chart.scales['y-axis-0'];
expect(newyScale.options.ticks.min).toBe(0);
expect(newyScale.options.ticks.max).toBe(10);
});

it ('should update tooltip options', function() {
var chart = acquireChart({
type: 'line',
Expand Down

0 comments on commit 123bf03

Please sign in to comment.