Skip to content

Commit 7071ff9

Browse files
committed
support shape.label.texttemplate attribute
1 parent a19f685 commit 7071ff9

File tree

5 files changed

+67
-4
lines changed

5 files changed

+67
-4
lines changed

src/components/shapes/attributes.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ var annAttrs = require('../annotations/attributes');
44
var fontAttrs = require('../../plots/font_attributes');
55
var scatterLineAttrs = require('../../traces/scatter/attributes').line;
66
var dash = require('../drawing/attributes').dash;
7+
var templateFormatStringDescription = require('../../plots/template_attributes').templateFormatStringDescription;
8+
var describeVariables = require('../../plots/template_attributes').describeVariables;
79
var extendFlat = require('../../lib/extend').extendFlat;
810
var templatedArray = require('../../plot_api/plot_template').templatedArray;
911
var axisPlaceableObjs = require('../../constants/axis_placeable_objects');
@@ -232,6 +234,17 @@ module.exports = templatedArray('shape', {
232234
editType: 'arraydraw',
233235
description: 'Sets the text to display with shape.'
234236
},
237+
texttemplate: {
238+
valType: 'string',
239+
dflt: '',
240+
editType: 'calc+arraydraw',
241+
description: [
242+
'Template string used for rendering the shape\'s label.',
243+
'Note that this will override `text`.',
244+
templateFormatStringDescription(),
245+
describeVariables(['x0', 'y0', 'x1', 'y1', 'slope']),
246+
].join(' ')
247+
},
235248
font: fontAttrs({
236249
editType: 'calc+arraydraw',
237250
colorEditType: 'arraydraw',

src/components/shapes/defaults.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ function handleShapeDefaults(shapeIn, shapeOut, fullLayout) {
129129
// Label options
130130
var isLine = shapeType === 'line';
131131
var labelText = coerce('label.text');
132-
if(labelText) {
132+
var labelTextTemplate = coerce('label.texttemplate');
133+
if(labelText || labelTextTemplate) {
133134
coerce('label.textangle');
134135
var labelTextPosition = coerce('label.textposition', isLine ? 'middle' : 'middle center');
135136
coerce('label.xanchor');

src/components/shapes/draw.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -605,13 +605,27 @@ function drawLabel(gd, index, options, shapeGroup) {
605605
// Remove existing label
606606
shapeGroup.selectAll('.shape-label').remove();
607607

608-
// If no label, return
609-
if(!options.label.text) return;
608+
// If no label text or texttemplate, return
609+
if(!(options.label.text || options.label.texttemplate)) return;
610+
611+
// Text template overrides text
612+
var text = options.label.text;
613+
if(options.label.texttemplate) {
614+
text = Lib.texttemplateStringWithMath(options.label.texttemplate,
615+
{},
616+
gd._fullLayout._d3locale,
617+
{
618+
x0: options.x0,
619+
y0: options.y0,
620+
x1: options.x1,
621+
y1: options.y1,
622+
slope: (options.y1 - options.y0) / (options.x1 - options.x0),
623+
});
624+
}
610625

611626
var labelGroupAttrs = {
612627
'data-index': index,
613628
};
614-
var text = options.label.text;
615629
var font = options.label.font;
616630

617631
var labelTextAttrs = {

src/lib/index.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,22 @@ lib.texttemplateString = function() {
10741074
return templateFormatString.apply(texttemplateWarnings, arguments);
10751075
};
10761076

1077+
var MULT_DIV_REGEX = /^(\S+)([\*\/])(-?\d+(\.\d+)?)$/;
1078+
function parseMultDiv(inputStr) {
1079+
var match = inputStr.match(MULT_DIV_REGEX);
1080+
if(match) return { key: match[1], op: match[2], number: Number(match[3]) };
1081+
else return { key: inputStr, op: null, number: null };
1082+
}
1083+
var texttemplateWarningsWithMath = {
1084+
max: 10,
1085+
count: 0,
1086+
name: 'texttemplate',
1087+
parseMath: true,
1088+
};
1089+
lib.texttemplateStringWithMath = function() {
1090+
return templateFormatString.apply(texttemplateWarningsWithMath, arguments);
1091+
};
1092+
10771093
var TEMPLATE_STRING_FORMAT_SEPARATOR = /^[:|\|]/;
10781094
/**
10791095
* Substitute values from an object into a string and optionally formats them using d3-format,
@@ -1122,6 +1138,16 @@ function templateFormatString(string, labels, d3locale) {
11221138
if(isSpaceOther || isSpaceOtherSpace) key = key.substring(1);
11231139
if(isOtherSpace || isSpaceOtherSpace) key = key.substring(0, key.length - 1);
11241140

1141+
// Shape labels support * and / operators in template string
1142+
var parsedOp = null;
1143+
var parsedNumber = null;
1144+
if(opts.parseMath) {
1145+
var _match = parseMultDiv(key);
1146+
key = _match.key;
1147+
parsedOp = _match.op;
1148+
parsedNumber = _match.number;
1149+
}
1150+
11251151
var value;
11261152
if(hasOther) {
11271153
value = labels[key];
@@ -1145,6 +1171,13 @@ function templateFormatString(string, labels, d3locale) {
11451171
}
11461172
}
11471173

1174+
if(parsedOp) {
1175+
value = {
1176+
'*': (function(v) { return v * parsedNumber; }),
1177+
'/': (function(v) { return v / parsedNumber; }),
1178+
}[parsedOp](value);
1179+
}
1180+
11481181
if(value === undefined && opts) {
11491182
if(opts.count < opts.max) {
11501183
lib.warn('Variable \'' + key + '\' in ' + opts.name + ' could not be found!');

src/plots/template_attributes.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function templateFormatStringDescription(opts) {
2222
'for details on the date formatting syntax.'
2323
].join(' ');
2424
}
25+
exports.templateFormatStringDescription = templateFormatStringDescription;
2526

2627
function describeVariables(extra) {
2728
var descPart = extra.description ? ' ' + extra.description : '';
@@ -40,6 +41,7 @@ function describeVariables(extra) {
4041
}
4142
return descPart;
4243
}
44+
exports.describeVariables = describeVariables;
4345

4446
exports.hovertemplateAttrs = function(opts, extra) {
4547
opts = opts || {};

0 commit comments

Comments
 (0)