diff --git a/src/plots/array_container_defaults.js b/src/plots/array_container_defaults.js index 5f258544309..f03c5253f98 100644 --- a/src/plots/array_container_defaults.js +++ b/src/plots/array_container_defaults.js @@ -48,7 +48,7 @@ module.exports = function handleArrayContainerDefaults(parentObjIn, parentObjOut var previousContOut = parentObjOut[name]; - var contIn = Lib.isArrayOrTypedArray(parentObjIn[name]) ? parentObjIn[name] : []; + var contIn = Lib.isArrayOrTypedArray(parentObjIn[name]) ? parentObjIn[name] : (opts.fromTemplate || []); var contOut = parentObjOut[name] = []; var templater = Template.arrayTemplater(parentObjOut, name, inclusionAttr); var i, itemOut; diff --git a/src/plots/cartesian/axis_defaults.js b/src/plots/cartesian/axis_defaults.js index b1cae96206d..10f697b3618 100644 --- a/src/plots/cartesian/axis_defaults.js +++ b/src/plots/cartesian/axis_defaults.js @@ -51,7 +51,7 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce, var visible = coerce('visible', !options.visibleDflt); - var axType = containerOut.type; + var axType = containerOut.type || options.axTemplate.type || '-'; if(axType === 'date') { var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleDefaults'); @@ -125,9 +125,12 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce, } if(containerOut.type === 'date') { - var rangebreaks = containerIn.rangebreaks; + var fromTemplate = (options.axTemplate || {}).rangebreaks; + var rangebreaks = containerIn.rangebreaks || fromTemplate; + if(Array.isArray(rangebreaks) && rangebreaks.length) { handleArrayContainerDefaults(containerIn, containerOut, { + fromTemplate: fromTemplate, name: 'rangebreaks', inclusionAttr: 'enabled', handleItemDefaults: rangebreaksDefaults diff --git a/src/plots/cartesian/layout_defaults.js b/src/plots/cartesian/layout_defaults.js index 9e163329c7b..9640509a030 100644 --- a/src/plots/cartesian/layout_defaults.js +++ b/src/plots/cartesian/layout_defaults.js @@ -230,7 +230,13 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { axHasImage[axName] )); + var axTemplate; + if(Lib.isPlainObject(layoutOut._template)) { + axTemplate = layoutOut._template[axLayoutOut._name]; + } + var defaultOptions = { + axTemplate: axTemplate || {}, letter: axLetter, font: layoutOut.font, outerTicks: outerTicks[axName], @@ -295,7 +301,13 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { axLayoutOut = Template.newContainer(layoutOut, axName, axLetter + 'axis'); newAxLayoutOut(); + var axTemplate2; + if(Lib.isPlainObject(layoutOut._template)) { + axTemplate2 = layoutOut._template[axLayoutOut._name]; + } + var defaultOptions2 = { + axTemplate: axTemplate2 || {}, letter: axLetter, font: layoutOut.font, outerTicks: outerTicks[axName], diff --git a/src/plots/cartesian/tick_label_defaults.js b/src/plots/cartesian/tick_label_defaults.js index 877c1acb40e..bf26dcacaef 100644 --- a/src/plots/cartesian/tick_label_defaults.js +++ b/src/plots/cartesian/tick_label_defaults.js @@ -59,9 +59,12 @@ function handleOtherDefaults(containerIn, containerOut, coerce, axType, options) if(axType !== 'category') { var tickFormat = coerce('tickformat'); - var tickformatStops = containerIn.tickformatstops; + var fromTemplate = (options.axTemplate || {}).tickformatstops; + var tickformatStops = containerIn.tickformatstops || fromTemplate; + if(Array.isArray(tickformatStops) && tickformatStops.length) { handleArrayContainerDefaults(containerIn, containerOut, { + fromTemplate: fromTemplate, name: 'tickformatstops', inclusionAttr: 'enabled', handleItemDefaults: tickformatstopDefaults diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index ad06ff73e53..43662ec3ee4 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -5411,3 +5411,49 @@ describe('Test tickformatstops:', function() { .then(done); }); }); + +describe('Test template:', function() { + 'use strict'; + + var gd; + beforeEach(function() { + gd = createGraphDiv(); + }); + afterEach(destroyGraphDiv); + + it('apply axis *type*, *rangebreaks* and *tickformatstops* from template', function(done) { + Plotly.newPlot(gd, { + data: [{ + x: [1e10, 2e10, 3e10, 4e10, 5e10, 6e10, 7e10], + y: [1, 2, 3, 4, 5, 6, 7] + }], + layout: { + template: { + layout: { + xaxis: { + type: 'date', + rangebreaks: [{ + bounds: ['sat', 'mon'] + }], + tickformatstops: [{ + enabled: true, + dtickrange: [1000, 60000], + value: '%H:%M:%S s' + }] + } + } + } + } + }) + .then(function() { + var xaxis = gd._fullLayout.xaxis; + expect(xaxis.type).toBe('date'); + expect(xaxis.rangebreaks).not.toBe(undefined, 'rangebreaks'); + expect(xaxis.rangebreaks.length).toBe(1); + expect(xaxis.tickformatstops).not.toBe(undefined, 'tickformatstops'); + expect(xaxis.tickformatstops.length).toBe(1); + }) + .catch(failTest) + .then(done); + }); +});