Skip to content

Commit b06a80a

Browse files
committed
bar: accept font family, size and color arrays
* Before this commit, font attributes accepted: [{family: family0, size: size0, color: color0}, {family: family1, size: size1, color: color1}, ...] * With this commit, font attributes accept: {family: [family0, family1, ...], size: [size0, size1, ...], color: [color0, color1, ...]}
1 parent 4a45032 commit b06a80a

File tree

2 files changed

+129
-56
lines changed

2 files changed

+129
-56
lines changed

src/traces/bar/attributes.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ var colorbarAttrs = require('../../components/colorbar/attributes');
1515
var fontAttrs = require('../../plots/font_attributes');
1616

1717
var extendFlat = require('../../lib/extend').extendFlat;
18+
var extendDeep = require('../../lib/extend').extendDeep;
19+
20+
var textFontAttrs = extendDeep({}, fontAttrs);
21+
textFontAttrs.family.arrayOk = true;
22+
textFontAttrs.size.arrayOk = true;
23+
textFontAttrs.color.arrayOk = true;
1824

1925
var scatterMarkerAttrs = scatterAttrs.marker;
2026
var scatterMarkerLineAttrs = scatterMarkerAttrs.line;
@@ -55,18 +61,15 @@ module.exports = {
5561
].join(' ')
5662
},
5763

58-
textfont: extendFlat({}, fontAttrs, {
59-
arrayOk: true,
64+
textfont: extendFlat({}, textFontAttrs, {
6065
description: 'Sets the font used for `textinfo`.'
6166
}),
6267

63-
insidetextfont: extendFlat({}, fontAttrs, {
64-
arrayOk: true,
68+
insidetextfont: extendFlat({}, textFontAttrs, {
6569
description: 'Sets the font used for `textinfo` lying inside the bar.'
6670
}),
6771

68-
outsidetextfont: extendFlat({}, fontAttrs, {
69-
arrayOk: true,
72+
outsidetextfont: extendFlat({}, textFontAttrs, {
7073
description: 'Sets the font used for `textinfo` lying outside the bar.'
7174
}),
7275

src/traces/bar/plot.js

Lines changed: 120 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
var d3 = require('d3');
1313
var isNumeric = require('fast-isnumeric');
14+
var tinycolor = require('tinycolor2');
1415

1516
var Lib = require('../../lib');
1617
var svgTextUtils = require('../../lib/svg_text_utils');
@@ -21,6 +22,13 @@ var ErrorBars = require('../../components/errorbars');
2122

2223
var arraysToCalcdata = require('./arrays_to_calcdata');
2324

25+
var attributes = require('./attributes'),
26+
attributeText = attributes.text,
27+
attributeTextPosition = attributes.textposition,
28+
attributeTextFont = attributes.textfont,
29+
attributeInsideTextFont = attributes.insidetextfont,
30+
attributeOutsideTextFont = attributes.outsidetextfont;
31+
2432
// padding in pixels around text
2533
var TEXTPAD = 3;
2634

@@ -134,55 +142,6 @@ module.exports = function plot(gd, plotinfo, cdbar) {
134142
};
135143

136144
function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) {
137-
var trace = calcTrace[0].trace;
138-
139-
// get bar text
140-
var traceText = trace.text;
141-
if(!traceText) return;
142-
143-
var text;
144-
if(Array.isArray(traceText)) {
145-
if(i >= traceText.length) return;
146-
text = traceText[i];
147-
}
148-
else {
149-
text = traceText;
150-
}
151-
152-
if(!text) return;
153-
154-
// get text position
155-
var traceTextPosition = trace.textposition,
156-
textPosition;
157-
if(Array.isArray(traceTextPosition)) {
158-
if(i >= traceTextPosition.length) return;
159-
textPosition = traceTextPosition[i];
160-
}
161-
else {
162-
textPosition = traceTextPosition;
163-
}
164-
165-
if(textPosition === 'none') return;
166-
167-
// get text font
168-
var traceTextFont = trace.textfont,
169-
textFont = (Array.isArray(traceTextFont)) ?
170-
traceTextFont[i] : traceTextFont;
171-
textFont = textFont || gd._fullLayout.font;
172-
173-
// get outside text font
174-
var traceOutsideTextFont = trace.outsidetextfont,
175-
outsideTextFont = (Array.isArray(traceOutsideTextFont)) ?
176-
traceOutsideTextFont[i] : traceOutsideTextFont;
177-
outsideTextFont = outsideTextFont || textFont;
178-
179-
// get inside text font
180-
var traceInsideTextFont = trace.insidetextfont,
181-
insideTextFont = (Array.isArray(traceInsideTextFont)) ?
182-
traceInsideTextFont[i] : traceInsideTextFont;
183-
insideTextFont = insideTextFont || textFont;
184-
185-
// append text node
186145
function appendTextNode(bar, text, textFont) {
187146
var textSelection = bar.append('text')
188147
// prohibit tex interpretation until we can handle
@@ -205,6 +164,20 @@ function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) {
205164
return textSelection;
206165
}
207166

167+
// get trace attributes
168+
var trace = calcTrace[0].trace;
169+
170+
var text = getText(trace, i);
171+
if(!text) return;
172+
173+
var textPosition = getTextPosition(trace, i);
174+
if(textPosition === 'none') return;
175+
176+
var textFont = getTextFont(trace, i, gd._fullLayout.font),
177+
insideTextFont = getInsideTextFont(trace, i, textFont),
178+
outsideTextFont = getOutsideTextFont(trace, i, textFont);
179+
180+
// compute text position
208181
var barmode = gd._fullLayout.barmode,
209182
inStackMode = (barmode === 'stack'),
210183
inRelativeMode = (barmode === 'relative'),
@@ -266,7 +239,7 @@ function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) {
266239
}
267240
}
268241

269-
// set text transform
242+
// compute text transform
270243
var transform;
271244
if(textPosition === 'outside') {
272245
transform = getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB,
@@ -482,3 +455,100 @@ function getTransform(textX, textY, targetX, targetY, scale, rotate) {
482455

483456
return transformTranslate + transformScale + transformRotate;
484457
}
458+
459+
function getText(trace, index) {
460+
var value = getValue(trace.text, index);
461+
return coerceString(attributeText, value);
462+
}
463+
464+
function getTextPosition(trace, index) {
465+
var value = getValue(trace.textposition, index);
466+
return coerceEnumerated(attributeTextPosition, value);
467+
}
468+
469+
function getTextFont(trace, index, defaultValue) {
470+
return getFontValue(
471+
attributeTextFont, trace.textfont, index, defaultValue);
472+
}
473+
474+
function getInsideTextFont(trace, index, defaultValue) {
475+
return getFontValue(
476+
attributeInsideTextFont, trace.insidetextfont, index, defaultValue);
477+
}
478+
479+
function getOutsideTextFont(trace, index, defaultValue) {
480+
return getFontValue(
481+
attributeOutsideTextFont, trace.outsidetextfont, index, defaultValue);
482+
}
483+
484+
function getFontValue(attributeDefinition, attributeValue, index, defaultValue) {
485+
attributeValue = attributeValue || {};
486+
487+
var familyValue = getValue(attributeValue.family, index),
488+
sizeValue = getValue(attributeValue.size, index),
489+
colorValue = getValue(attributeValue.color, index);
490+
491+
return {
492+
family: coerceString(
493+
attributeDefinition.family, familyValue, defaultValue.family),
494+
size: coerceNumber(
495+
attributeDefinition.size, sizeValue, defaultValue.size),
496+
color: coerceColor(
497+
attributeDefinition.color, colorValue, defaultValue.color)
498+
};
499+
}
500+
501+
function getValue(arrayOrScalar, index) {
502+
var value;
503+
if(!Array.isArray(arrayOrScalar)) value = arrayOrScalar;
504+
else if(index < arrayOrScalar.length) value = arrayOrScalar[index];
505+
return value;
506+
}
507+
508+
function coerceString(attributeDefinition, value, defaultValue) {
509+
if(typeof value === 'string') {
510+
if(value || !attributeDefinition.noBlank) return value;
511+
}
512+
else if(typeof value === 'number') {
513+
if(!attributeDefinition.strict) return String(value);
514+
}
515+
516+
return (defaultValue !== undefined) ?
517+
defaultValue :
518+
attributeDefinition.dflt;
519+
}
520+
521+
function coerceEnumerated(attributeDefinition, value, defaultValue) {
522+
if(attributeDefinition.coerceNumber) value = +value;
523+
524+
if(attributeDefinition.values.indexOf(value) !== -1) return value;
525+
526+
return (defaultValue !== undefined) ?
527+
defaultValue :
528+
attributeDefinition.dflt;
529+
}
530+
531+
function coerceNumber(attributeDefinition, value, defaultValue) {
532+
if(isNumeric(value)) {
533+
value = +value;
534+
535+
var min = attributeDefinition.min,
536+
max = attributeDefinition.max,
537+
isOutOfBounds = (min !== undefined && value < min) ||
538+
(max !== undefined && value > max);
539+
540+
if(!isOutOfBounds) return value;
541+
}
542+
543+
return (defaultValue !== undefined) ?
544+
defaultValue :
545+
attributeDefinition.dflt;
546+
}
547+
548+
function coerceColor(attributeDefinition, value, defaultValue) {
549+
if(tinycolor(value).isValid()) return value;
550+
551+
return (defaultValue !== undefined) ?
552+
defaultValue :
553+
attributeDefinition.dflt;
554+
}

0 commit comments

Comments
 (0)