* Register a box to a chart.
* A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.
* @param {Chart} chart - the chart to use
- * @param {ILayoutItem} layoutItem - the item to add to be layed out
+ * @param {ILayoutItem} item - the item to add to be layed out
*/
- addBox: function(chart, layoutItem) {
+ addBox: function(chart, item) {
if (!chart.boxes) {
chart.boxes = [];
}
- // Ensure that all layout items have a weight
- if (!layoutItem.weight) {
- layoutItem.weight = 0;
- }
- chart.boxes.push(layoutItem);
+ // initialize item with default values
+ item.fullWidth = item.fullWidth || false;
+ item.position = item.position || 'top';
+ item.weight = item.weight || 0;
+
+ chart.boxes.push(item);
},
/**
}
},
+ /**
+ * Sets (or updates) options on the given `item`.
+ * @param {Chart} chart - the chart in which the item lives (or will be added to)
+ * @param {Object} item - the item to configure with the given options
+ * @param {Object} options - the new item options.
+ */
+ configure: function(chart, item, options) {
+ var props = ['fullWidth', 'position', 'weight'];
+ var ilen = props.length;
+ var i = 0;
+ var prop;
+
+ for (; i<ilen; ++i) {
+ prop = props[i];
+ if (options.hasOwnProperty(prop)) {
+ item[prop] = options[prop];
+ }
+ }
+ },
+
/**
* Fits boxes of the given chart into the given size by having each box measure itself
* then running a fitting algorithm
module.exports = function(Chart) {
var helpers = Chart.helpers;
+ var layout = Chart.layoutService;
var noop = helpers.noop;
Chart.defaults.global.legend = {
-
display: true,
position: 'top',
- fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
+ fullWidth: true,
reverse: false,
+ weight: 1000,
// a callback that will handle
onClick: function(e, legendItem) {
var legend = new Chart.Legend({
ctx: chart.ctx,
options: legendOpts,
- chart: chart,
-
- // ILayoutItem parameters for layout service
- // pick a large number to ensure we are on the outside after any axes
- weight: 1000,
- position: legendOpts.position,
- fullWidth: legendOpts.fullWidth,
+ chart: chart
});
+
+ layout.configure(chart, legend, legendOpts);
+ layout.addBox(chart, legend);
chart.legend = legend;
- Chart.layoutService.addBox(chart, legend);
}
return {
createNewLegendAndAttach(chart, legendOpts);
}
},
+
beforeUpdate: function(chart) {
var legendOpts = chart.options.legend;
var legend = chart.legend;
legendOpts = helpers.configMerge(Chart.defaults.global.legend, legendOpts);
if (legend) {
+ layout.configure(chart, legend, legendOpts);
legend.options = legendOpts;
} else {
createNewLegendAndAttach(chart, legendOpts);
}
} else if (legend) {
- Chart.layoutService.removeBox(chart, legend);
+ layout.removeBox(chart, legend);
delete chart.legend;
}
},
+
afterEvent: function(chart, e) {
var legend = chart.legend;
if (legend) {
module.exports = function(Chart) {
var helpers = Chart.helpers;
+ var layout = Chart.layoutService;
var noop = helpers.noop;
Chart.defaults.global.title = {
display: false,
position: 'top',
- fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
-
+ fullWidth: true,
+ weight: 2000, // by default greater than legend (1000) to be above
fontStyle: 'bold',
padding: 10,
var title = new Chart.Title({
ctx: chart.ctx,
options: titleOpts,
- chart: chart,
-
- // ILayoutItem parameters
- weight: 2000, // greater than legend to be above
- position: titleOpts.position,
- fullWidth: titleOpts.fullWidth,
+ chart: chart
});
+
+ layout.configure(chart, title, titleOpts);
+ layout.addBox(chart, title);
chart.titleBlock = title;
- Chart.layoutService.addBox(chart, title);
}
return {
createNewTitleBlockAndAttach(chart, titleOpts);
}
},
+
beforeUpdate: function(chart) {
var titleOpts = chart.options.title;
var titleBlock = chart.titleBlock;
titleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);
if (titleBlock) {
+ layout.configure(chart, titleBlock, titleOpts);
titleBlock.options = titleOpts;
} else {
createNewTitleBlockAndAttach(chart, titleOpts);
position: 'top',
fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
reverse: false,
+ weight: 1000,
// a callback that will handle
onClick: jasmine.any(Function),
expect(chart.legend.options.display).toBe(false);
});
+ it ('should update the associated layout item', function() {
+ var chart = acquireChart({
+ type: 'line',
+ data: {},
+ options: {
+ legend: {
+ fullWidth: true,
+ position: 'top',
+ weight: 150
+ }
+ }
+ });
+
+ expect(chart.legend.fullWidth).toBe(true);
+ expect(chart.legend.position).toBe('top');
+ expect(chart.legend.weight).toBe(150);
+
+ chart.options.legend.fullWidth = false;
+ chart.options.legend.position = 'left';
+ chart.options.legend.weight = 42;
+ chart.update();
+
+ expect(chart.legend.fullWidth).toBe(false);
+ expect(chart.legend.position).toBe('left');
+ expect(chart.legend.weight).toBe(42);
+ });
+
it ('should remove the legend if the new options are false', function() {
var chart = acquireChart({
type: 'line',
display: false,
position: 'top',
fullWidth: true,
+ weight: 2000,
fontStyle: 'bold',
padding: 10,
text: ''
expect(chart.titleBlock.options.display).toBe(false);
});
+ it ('should update the associated layout item', function() {
+ var chart = acquireChart({
+ type: 'line',
+ data: {},
+ options: {
+ title: {
+ fullWidth: true,
+ position: 'top',
+ weight: 150
+ }
+ }
+ });
+
+ expect(chart.titleBlock.fullWidth).toBe(true);
+ expect(chart.titleBlock.position).toBe('top');
+ expect(chart.titleBlock.weight).toBe(150);
+
+ chart.options.title.fullWidth = false;
+ chart.options.title.position = 'left';
+ chart.options.title.weight = 42;
+ chart.update();
+
+ expect(chart.titleBlock.fullWidth).toBe(false);
+ expect(chart.titleBlock.position).toBe('left');
+ expect(chart.titleBlock.weight).toBe(42);
+ });
+
it ('should remove the title if the new options are false', function() {
var chart = acquireChart({
type: 'line',