From 3adf2f689e0cb7db9dcf04d0545c2fc4cf43d57e Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 9 Jun 2025 11:23:44 -0400 Subject: [PATCH 1/2] add unifiedhovertemplate --- src/components/fx/hover.js | 18 +++++++++++++++++- src/plots/cartesian/axis_defaults.js | 5 ++++- src/plots/cartesian/layout_attributes.js | 4 ++++ src/plots/gl3d/layout/axis_defaults.js | 1 + src/plots/template_attributes.js | 4 +++- test/plot-schema.json | 24 ++++++++++++++++++++++++ 6 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js index 80fc4a07cf3..2153d70dbb7 100644 --- a/src/components/fx/hover.js +++ b/src/components/fx/hover.js @@ -1211,10 +1211,26 @@ function createHoverText(hoverData, opts) { // mock legend var hoverlabel = fullLayout.hoverlabel; var font = hoverlabel.font; + + var item0 = groupedHoverData[0]; + + var unifiedhovertemplate = ( + hovermode === 'y unified' ? + item0.xa : + item0.ya + ).unifiedhovertemplate; + + var mainText = !unifiedhovertemplate ? t0 : + Lib.hovertemplateString(unifiedhovertemplate, {}, fullLayout._d3locale, + hovermode === 'y unified' ? + {xa: item0.xa, x: item0.xVal} : + {ya: item0.ya, y: item0.yVal} + ); + var mockLayoutIn = { showlegend: true, legend: { - title: {text: t0, font: font}, + title: {text: mainText, font: font}, font: font, bgcolor: hoverlabel.bgcolor, bordercolor: hoverlabel.bordercolor, diff --git a/src/plots/cartesian/axis_defaults.js b/src/plots/cartesian/axis_defaults.js index 4531785cd2f..a1c091863e1 100644 --- a/src/plots/cartesian/axis_defaults.js +++ b/src/plots/cartesian/axis_defaults.js @@ -100,7 +100,10 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce, handleCategoryOrderDefaults(containerIn, containerOut, coerce, options); - if(axType !== 'category' && !options.noHover) coerce('hoverformat'); + if(!options.noHover) { + if(axType !== 'category') coerce('hoverformat'); + if(!options.noUnifiedhovertemplate) coerce('unifiedhovertemplate'); + } var dfltColor = coerce('color'); // if axis.color was provided, use it for fonts too; otherwise, diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index f1b7bbbe5d6..7b255e75006 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -5,6 +5,7 @@ var colorAttrs = require('../../components/color/attributes'); var dash = require('../../components/drawing/attributes').dash; var extendFlat = require('../../lib/extend').extendFlat; var templatedArray = require('../../plot_api/plot_template').templatedArray; +var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs; var descriptionWithDates = require('../../plots/cartesian/axis_format_attributes').descriptionWithDates; var ONEDAY = require('../../constants/numerical').ONEDAY; @@ -975,6 +976,9 @@ module.exports = { editType: 'none', description: descriptionWithDates('hover text') }, + unifiedhovertemplate: hovertemplateAttrs({ + noSupportOther: true + }), // lines and grids showline: { valType: 'boolean', diff --git a/src/plots/gl3d/layout/axis_defaults.js b/src/plots/gl3d/layout/axis_defaults.js index e3d71be24cb..d8df3f46032 100644 --- a/src/plots/gl3d/layout/axis_defaults.js +++ b/src/plots/gl3d/layout/axis_defaults.js @@ -51,6 +51,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, options) { noTicklabelposition: true, noTicklabeloverflow: true, noInsiderange: true, + noUnifiedhovertemplate: true, bgColor: options.bgColor, calendar: options.calendar }, diff --git a/src/plots/template_attributes.js b/src/plots/template_attributes.js index 9f01f920688..80e3d77d886 100644 --- a/src/plots/template_attributes.js +++ b/src/plots/template_attributes.js @@ -71,7 +71,9 @@ exports.hovertemplateAttrs = function(opts, extra) { description: [ 'Template string used for rendering the information that appear on hover box.', 'Note that this will override `hoverinfo`.', - templateFormatStringDescription({supportOther: true}), + templateFormatStringDescription({ + supportOther: opts.noSupportOther ? false : true + }), 'The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data.', 'Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available.', descPart, diff --git a/test/plot-schema.json b/test/plot-schema.json index df08db9d5c3..7904e8038a8 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -14949,6 +14949,18 @@ "editType": "none", "valType": "any" }, + "unifiedhovertemplate": { + "arrayOk": true, + "description": "Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Anything contained in tag `` is displayed in the secondary box, for example \"{fullData.name}\". To hide the secondary box completely, use an empty tag ``.", + "dflt": "", + "editType": "none", + "valType": "string" + }, + "unifiedhovertemplatesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `unifiedhovertemplate`.", + "editType": "none", + "valType": "string" + }, "visible": { "description": "A single toggle to hide the axis while preserving interaction like dragging. Default is true when a cheater plot is present on the axis, otherwise false", "editType": "plot", @@ -16193,6 +16205,18 @@ "editType": "none", "valType": "any" }, + "unifiedhovertemplate": { + "arrayOk": true, + "description": "Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Anything contained in tag `` is displayed in the secondary box, for example \"{fullData.name}\". To hide the secondary box completely, use an empty tag ``.", + "dflt": "", + "editType": "none", + "valType": "string" + }, + "unifiedhovertemplatesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `unifiedhovertemplate`.", + "editType": "none", + "valType": "string" + }, "visible": { "description": "A single toggle to hide the axis while preserving interaction like dragging. Default is true when a cheater plot is present on the axis, otherwise false", "editType": "plot", From 9dcc03fe07974cc9e4b7e5deeb10ad14a76efbb1 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 10 Jun 2025 11:43:49 -0400 Subject: [PATCH 2/2] revise attribute description --- src/plots/cartesian/layout_attributes.js | 14 ++++++++++---- src/plots/template_attributes.js | 5 ++--- test/plot-schema.json | 16 ++-------------- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/plots/cartesian/layout_attributes.js b/src/plots/cartesian/layout_attributes.js index 7b255e75006..fc0e70e2345 100644 --- a/src/plots/cartesian/layout_attributes.js +++ b/src/plots/cartesian/layout_attributes.js @@ -5,7 +5,7 @@ var colorAttrs = require('../../components/color/attributes'); var dash = require('../../components/drawing/attributes').dash; var extendFlat = require('../../lib/extend').extendFlat; var templatedArray = require('../../plot_api/plot_template').templatedArray; -var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs; +var templateFormatStringDescription = require('../../plots/template_attributes').templateFormatStringDescription; var descriptionWithDates = require('../../plots/cartesian/axis_format_attributes').descriptionWithDates; var ONEDAY = require('../../constants/numerical').ONEDAY; @@ -976,9 +976,15 @@ module.exports = { editType: 'none', description: descriptionWithDates('hover text') }, - unifiedhovertemplate: hovertemplateAttrs({ - noSupportOther: true - }), + unifiedhovertemplate: { + valType: 'string', + dflt: '', + editType: 'none', + description: [ + 'Template string used for rendering the title that appear on x or y unified hover box.', + templateFormatStringDescription() + ].join(' ') + }, // lines and grids showline: { valType: 'boolean', diff --git a/src/plots/template_attributes.js b/src/plots/template_attributes.js index 80e3d77d886..5d5193c3f30 100644 --- a/src/plots/template_attributes.js +++ b/src/plots/template_attributes.js @@ -22,6 +22,7 @@ function templateFormatStringDescription(opts) { 'for details on the date formatting syntax.' ].join(' '); } +exports.templateFormatStringDescription = templateFormatStringDescription; function shapeTemplateFormatStringDescription() { return [ @@ -71,9 +72,7 @@ exports.hovertemplateAttrs = function(opts, extra) { description: [ 'Template string used for rendering the information that appear on hover box.', 'Note that this will override `hoverinfo`.', - templateFormatStringDescription({ - supportOther: opts.noSupportOther ? false : true - }), + templateFormatStringDescription({supportOther: true}), 'The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data.', 'Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available.', descPart, diff --git a/test/plot-schema.json b/test/plot-schema.json index 7904e8038a8..249bcc278ba 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -14950,17 +14950,11 @@ "valType": "any" }, "unifiedhovertemplate": { - "arrayOk": true, - "description": "Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Anything contained in tag `` is displayed in the secondary box, for example \"{fullData.name}\". To hide the secondary box completely, use an empty tag ``.", + "description": "Template string used for rendering the title that appear on x or y unified hover box. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax.", "dflt": "", "editType": "none", "valType": "string" }, - "unifiedhovertemplatesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `unifiedhovertemplate`.", - "editType": "none", - "valType": "string" - }, "visible": { "description": "A single toggle to hide the axis while preserving interaction like dragging. Default is true when a cheater plot is present on the axis, otherwise false", "editType": "plot", @@ -16206,17 +16200,11 @@ "valType": "any" }, "unifiedhovertemplate": { - "arrayOk": true, - "description": "Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Anything contained in tag `` is displayed in the secondary box, for example \"{fullData.name}\". To hide the secondary box completely, use an empty tag ``.", + "description": "Template string used for rendering the title that appear on x or y unified hover box. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax.", "dflt": "", "editType": "none", "valType": "string" }, - "unifiedhovertemplatesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `unifiedhovertemplate`.", - "editType": "none", - "valType": "string" - }, "visible": { "description": "A single toggle to hide the axis while preserving interaction like dragging. Default is true when a cheater plot is present on the axis, otherwise false", "editType": "plot",