mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Allow updating the config of a chart at runtime
This commit is contained in:
parent
7e5e29e3ee
commit
2e5df0ff42
@ -168,6 +168,26 @@ module.exports = function(Chart) {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the config of the chart
|
||||
* @param chart {Chart.Controller} chart to update the options for
|
||||
*/
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
// Tooltip
|
||||
chart.tooltip._options = newOptions.tooltips;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Chart.Controller
|
||||
* The main controller of a chart.
|
||||
@ -435,8 +455,11 @@ module.exports = function(Chart) {
|
||||
this.tooltip.initialize();
|
||||
},
|
||||
|
||||
|
||||
update: function(animationDuration, lazy) {
|
||||
var me = this;
|
||||
|
||||
updateConfig(me);
|
||||
Chart.plugins.notify('beforeUpdate', [me]);
|
||||
|
||||
// In case the entire data object changed
|
||||
|
||||
@ -489,20 +489,39 @@ module.exports = function(Chart) {
|
||||
}
|
||||
});
|
||||
|
||||
function createNewLegendAndAttach(chartInstance, legendOpts) {
|
||||
var legend = new Chart.Legend({
|
||||
ctx: chartInstance.chart.ctx,
|
||||
options: legendOpts,
|
||||
chart: chartInstance
|
||||
});
|
||||
chartInstance.legend = legend;
|
||||
Chart.layoutService.addBox(chartInstance, legend);
|
||||
}
|
||||
|
||||
// Register the legend plugin
|
||||
Chart.plugins.register({
|
||||
beforeInit: function(chartInstance) {
|
||||
var opts = chartInstance.options;
|
||||
var legendOpts = opts.legend;
|
||||
var legendOpts = chartInstance.options.legend;
|
||||
|
||||
if (legendOpts) {
|
||||
chartInstance.legend = new Chart.Legend({
|
||||
ctx: chartInstance.chart.ctx,
|
||||
options: legendOpts,
|
||||
chart: chartInstance
|
||||
});
|
||||
createNewLegendAndAttach(chartInstance, legendOpts);
|
||||
}
|
||||
},
|
||||
beforeUpdate: function(chartInstance) {
|
||||
var legendOpts = chartInstance.options.legend;
|
||||
|
||||
Chart.layoutService.addBox(chartInstance, chartInstance.legend);
|
||||
if (legendOpts) {
|
||||
legendOpts = helpers.configMerge(Chart.defaults.global.legend, legendOpts);
|
||||
|
||||
if (chartInstance.legend) {
|
||||
chartInstance.legend.options = legendOpts;
|
||||
} else {
|
||||
createNewLegendAndAttach(chartInstance, legendOpts);
|
||||
}
|
||||
} else {
|
||||
Chart.layoutService.removeBox(chartInstance, chartInstance.legend);
|
||||
delete chartInstance.legend;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -22,7 +22,6 @@ module.exports = function(Chart) {
|
||||
initialize: function(config) {
|
||||
var me = this;
|
||||
helpers.extend(me, config);
|
||||
me.options = helpers.configMerge(Chart.defaults.global.title, config.options);
|
||||
|
||||
// Contains hit boxes for each dataset (in dataset order)
|
||||
me.legendHitBoxes = [];
|
||||
@ -30,12 +29,7 @@ module.exports = function(Chart) {
|
||||
|
||||
// These methods are ordered by lifecycle. Utilities then follow.
|
||||
|
||||
beforeUpdate: function() {
|
||||
var chartOpts = this.chart.options;
|
||||
if (chartOpts && chartOpts.title) {
|
||||
this.options = helpers.configMerge(Chart.defaults.global.title, chartOpts.title);
|
||||
}
|
||||
},
|
||||
beforeUpdate: noop,
|
||||
update: function(maxWidth, maxHeight, margins) {
|
||||
var me = this;
|
||||
|
||||
@ -187,20 +181,39 @@ module.exports = function(Chart) {
|
||||
}
|
||||
});
|
||||
|
||||
function createNewTitleBlockAndAttach(chartInstance, titleOpts) {
|
||||
var title = new Chart.Title({
|
||||
ctx: chartInstance.chart.ctx,
|
||||
options: titleOpts,
|
||||
chart: chartInstance
|
||||
});
|
||||
chartInstance.titleBlock = title;
|
||||
Chart.layoutService.addBox(chartInstance, title);
|
||||
}
|
||||
|
||||
// Register the title plugin
|
||||
Chart.plugins.register({
|
||||
beforeInit: function(chartInstance) {
|
||||
var opts = chartInstance.options;
|
||||
var titleOpts = opts.title;
|
||||
var titleOpts = chartInstance.options.title;
|
||||
|
||||
if (titleOpts) {
|
||||
chartInstance.titleBlock = new Chart.Title({
|
||||
ctx: chartInstance.chart.ctx,
|
||||
options: titleOpts,
|
||||
chart: chartInstance
|
||||
});
|
||||
createNewTitleBlockAndAttach(chartInstance, titleOpts);
|
||||
}
|
||||
},
|
||||
beforeUpdate: function(chartInstance) {
|
||||
var titleOpts = chartInstance.options.title;
|
||||
|
||||
Chart.layoutService.addBox(chartInstance, chartInstance.titleBlock);
|
||||
if (titleOpts) {
|
||||
titleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);
|
||||
|
||||
if (chartInstance.titleBlock) {
|
||||
chartInstance.titleBlock.options = titleOpts;
|
||||
} else {
|
||||
createNewTitleBlockAndAttach(chartInstance, titleOpts);
|
||||
}
|
||||
} else {
|
||||
Chart.layoutService.removeBox(chartInstance, chartInstance.titleBlock);
|
||||
delete chartInstance.titleBlock;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -830,4 +830,53 @@ describe('Chart.Controller', function() {
|
||||
expect(meta.data[3]._model.y).toBe(484);
|
||||
});
|
||||
});
|
||||
|
||||
describe('config update', function() {
|
||||
it ('should update scales options', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['A', 'B', 'C', 'D'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30, 100]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true
|
||||
}
|
||||
});
|
||||
|
||||
chart.options.scales.yAxes[0].ticks.min = 0;
|
||||
chart.options.scales.yAxes[0].ticks.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 tooltip options', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['A', 'B', 'C', 'D'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30, 100]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true
|
||||
}
|
||||
});
|
||||
|
||||
var newTooltipConfig = {
|
||||
mode: 'dataset',
|
||||
intersect: false
|
||||
};
|
||||
chart.options.tooltips = newTooltipConfig;
|
||||
|
||||
chart.update();
|
||||
expect(chart.tooltip._options).toEqual(jasmine.objectContaining(newTooltipConfig));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -367,4 +367,66 @@ describe('Legend block tests', function() {
|
||||
"args": ["dataset3", 228, 132]
|
||||
}]);*/
|
||||
});
|
||||
|
||||
describe('config update', function() {
|
||||
it ('should update the options', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['A', 'B', 'C', 'D'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30, 100]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
display: true
|
||||
}
|
||||
}
|
||||
});
|
||||
expect(chart.legend.options.display).toBe(true);
|
||||
|
||||
chart.options.legend.display = false;
|
||||
chart.update();
|
||||
expect(chart.legend.options.display).toBe(false);
|
||||
});
|
||||
|
||||
it ('should remove the legend if the new options are false', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['A', 'B', 'C', 'D'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30, 100]
|
||||
}]
|
||||
}
|
||||
});
|
||||
expect(chart.legend).not.toBe(undefined);
|
||||
|
||||
chart.options.legend = false;
|
||||
chart.update();
|
||||
expect(chart.legend).toBe(undefined);
|
||||
});
|
||||
|
||||
it ('should create the legend if the legend options are changed to exist', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['A', 'B', 'C', 'D'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30, 100]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
legend: false
|
||||
}
|
||||
});
|
||||
expect(chart.legend).toBe(undefined);
|
||||
|
||||
chart.options.legend = {};
|
||||
chart.update();
|
||||
expect(chart.legend).not.toBe(undefined);
|
||||
expect(chart.legend.options).toEqual(jasmine.objectContaining(Chart.defaults.global.legend));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -207,4 +207,66 @@ describe('Title block tests', function() {
|
||||
args: []
|
||||
}]);
|
||||
});
|
||||
|
||||
describe('config update', function() {
|
||||
it ('should update the options', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['A', 'B', 'C', 'D'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30, 100]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true
|
||||
}
|
||||
}
|
||||
});
|
||||
expect(chart.titleBlock.options.display).toBe(true);
|
||||
|
||||
chart.options.title.display = false;
|
||||
chart.update();
|
||||
expect(chart.titleBlock.options.display).toBe(false);
|
||||
});
|
||||
|
||||
it ('should remove the title if the new options are false', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['A', 'B', 'C', 'D'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30, 100]
|
||||
}]
|
||||
}
|
||||
});
|
||||
expect(chart.titleBlock).not.toBe(undefined);
|
||||
|
||||
chart.options.title = false;
|
||||
chart.update();
|
||||
expect(chart.titleBlock).toBe(undefined);
|
||||
});
|
||||
|
||||
it ('should create the title if the title options are changed to exist', function() {
|
||||
var chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['A', 'B', 'C', 'D'],
|
||||
datasets: [{
|
||||
data: [10, 20, 30, 100]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
title: false
|
||||
}
|
||||
});
|
||||
expect(chart.titleBlock).toBe(undefined);
|
||||
|
||||
chart.options.title = {};
|
||||
chart.update();
|
||||
expect(chart.titleBlock).not.toBe(undefined);
|
||||
expect(chart.titleBlock.options).toEqual(jasmine.objectContaining(Chart.defaults.global.title));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user