-
Notifications
You must be signed in to change notification settings - Fork 0
Implement bar texts (issue 34) #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
cd2f59d
7d7017c
c2cb2c8
2526e83
a1683ee
4124e8a
d41b74d
bddcaff
2cbf725
1fd202c
6ab7a0b
ffe5dae
3455861
a3fea79
31d389c
af3f30b
a0504d1
77dc2c3
6a78175
0289c18
3b1f162
3c2ff52
a9a13f1
7d13f80
aa8d68e
f8e9554
435b614
c52f908
57803a0
3e53cef
ce5d53f
8cefb5b
4bf9320
54272da
97699c2
fea2b05
cdc298d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
|
||
var scatterAttrs = require('../scatter/attributes'); | ||
var colorAttributes = require('../../components/colorscale/color_attributes'); | ||
var fontAttrs = require('../../plots/font_attributes'); | ||
var extendFlat = require('../../lib/extend').extendFlat; | ||
|
||
var scatterMarkerAttrs = scatterAttrs.marker; | ||
|
@@ -35,8 +36,35 @@ module.exports = { | |
y: scatterAttrs.y, | ||
y0: scatterAttrs.y0, | ||
dy: scatterAttrs.dy, | ||
|
||
text: scatterAttrs.text, | ||
|
||
textposition: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @n-riesco what are your thoughts on adding a The default value would be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What would be the meaning of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm thinking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @etpinard I think this is doable. I can compute the total at the some point I determine which bars are the outmost bars. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Great. That's all I wanted to here for now. No action required in this iteration. |
||
valType: 'enumerated', | ||
role: 'info', | ||
values: ['inside', 'outside', 'auto', 'none'], | ||
dflt: 'none', | ||
arrayOk: true, | ||
description: [ | ||
'Specifies the location of the `textinfo`.' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @n-riesco this would be a great place to add info about the inside / outside algorithm you implemented. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ⬆️ blocking before making a PR to plotly.js |
||
].join(' ') | ||
}, | ||
|
||
textfont: extendFlat({}, fontAttrs, { | ||
arrayOk: true, | ||
description: 'Sets the font used for `textinfo`.' | ||
}), | ||
|
||
insidetextfont: extendFlat({}, fontAttrs, { | ||
arrayOk: true, | ||
description: 'Sets the font used for `textinfo` lying inside the bar.' | ||
}), | ||
|
||
outsidetextfont: extendFlat({}, fontAttrs, { | ||
arrayOk: true, | ||
description: 'Sets the font used for `textinfo` lying outside the bar.' | ||
}), | ||
|
||
orientation: { | ||
valType: 'enumerated', | ||
role: 'info', | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,9 @@ | |
|
||
'use strict'; | ||
|
||
var isNumeric = require('fast-isnumeric'); | ||
var tinycolor = require('tinycolor2'); | ||
|
||
var Lib = require('../../lib'); | ||
var Color = require('../../components/color'); | ||
|
||
|
@@ -23,6 +26,125 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout | |
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); | ||
} | ||
|
||
function coerceEnumerated(attributeDefinition, value, defaultValue) { | ||
if(attributeDefinition.coerceNumber) value = +value; | ||
|
||
if(attributeDefinition.values.indexOf(value) !== -1) return value; | ||
|
||
return (defaultValue !== undefined) ? | ||
defaultValue : | ||
attributeDefinition.dflt; | ||
} | ||
|
||
function coerceString(attributeDefinition, value, defaultValue) { | ||
if(typeof value === 'string') { | ||
if(value || !attributeDefinition.noBlank) return value; | ||
} | ||
else if(typeof value === 'number') { | ||
if(!attributeDefinition.strict) return String(value); | ||
} | ||
|
||
return (defaultValue !== undefined) ? | ||
defaultValue : | ||
attributeDefinition.dflt; | ||
} | ||
|
||
function coerceNumber(attributeDefinition, value, defaultValue) { | ||
if(isNumeric(value)) { | ||
value = +value; | ||
|
||
var min = attributeDefinition.min, | ||
max = attributeDefinition.max, | ||
isOutOfBounds = (min !== undefined && value < min) || | ||
(max !== undefined && value > max); | ||
|
||
if(!isOutOfBounds) return value; | ||
} | ||
|
||
return (defaultValue !== undefined) ? | ||
defaultValue : | ||
attributeDefinition.dflt; | ||
} | ||
|
||
function coerceColor(attributeDefinition, value, defaultValue) { | ||
if(tinycolor(value).isValid()) return value; | ||
|
||
return (defaultValue !== undefined) ? | ||
defaultValue : | ||
attributeDefinition.dflt; | ||
} | ||
|
||
function coerceFont(attributeDefinition, value, defaultValue) { | ||
value = value || {}; | ||
defaultValue = defaultValue || {}; | ||
|
||
return { | ||
family: coerceString( | ||
attributeDefinition.family, value.family, defaultValue.family), | ||
size: coerceNumber( | ||
attributeDefinition.size, value.size, defaultValue.size), | ||
color: coerceColor( | ||
attributeDefinition.color, value.color, defaultValue.color) | ||
}; | ||
} | ||
|
||
function coerceArray(attribute, coerceFunction, defaultValue, defaultValue2) { | ||
var attributeDefinition = attributes[attribute], | ||
arrayOk = attributeDefinition.arrayOk, | ||
inValue = traceIn[attribute], | ||
inValueIsArray = Array.isArray(inValue), | ||
defaultValueIsArray = Array.isArray(defaultValue), | ||
outValue, | ||
i; | ||
|
||
// Case: inValue and defaultValue not treated as arrays | ||
if(!arrayOk || (!inValueIsArray && !defaultValueIsArray)) { | ||
outValue = coerceFunction( | ||
attributeDefinition, inValue, defaultValue); | ||
traceOut[attribute] = outValue; | ||
return outValue; | ||
} | ||
|
||
// Coerce into an array | ||
outValue = []; | ||
|
||
// Case: defaultValue is an array and inValue isn't | ||
if(!inValueIsArray) { | ||
for(i = 0; i < defaultValue.length; i++) { | ||
outValue.push( | ||
coerceFunction( | ||
attributeDefinition, inValue, defaultValue[i])); | ||
} | ||
} | ||
|
||
// Case: inValue is an array and defaultValue isn't | ||
else if(!defaultValueIsArray) { | ||
for(i = 0; i < inValue.length; i++) { | ||
outValue.push( | ||
coerceFunction( | ||
attributeDefinition, inValue[i], defaultValue)); | ||
} | ||
} | ||
|
||
// Case: inValue and defaultValue are both arrays | ||
else { | ||
for(i = 0; i < defaultValue.length; i++) { | ||
outValue.push( | ||
coerceFunction( | ||
attributeDefinition, inValue[i], defaultValue[i])); | ||
} | ||
for(; i < inValue.length; i++) { | ||
outValue.push( | ||
coerceFunction( | ||
attributeDefinition, inValue[i], defaultValue2)); | ||
} | ||
} | ||
|
||
traceOut[attribute] = outValue; | ||
|
||
return outValue; | ||
} | ||
|
||
var len = handleXYDefaults(traceIn, traceOut, coerce); | ||
if(!len) { | ||
traceOut.visible = false; | ||
|
@@ -33,7 +155,23 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout | |
coerce('base'); | ||
coerce('offset'); | ||
coerce('width'); | ||
coerce('text'); | ||
|
||
coerceArray('text', coerceString); | ||
|
||
var textPosition = coerceArray('textposition', coerceEnumerated); | ||
|
||
var hasBoth = Array.isArray(textPosition) || textPosition === 'auto', | ||
hasInside = hasBoth || textPosition === 'inside', | ||
hasOutside = hasBoth || textPosition === 'outside'; | ||
if(hasInside || hasOutside) { | ||
var textFont = coerceArray('textfont', coerceFont, layout.font); | ||
if(hasInside) { | ||
coerceArray('insidetextfont', coerceFont, textFont, layout.font); | ||
} | ||
if(hasOutside) { | ||
coerceArray('outsidetextfont', coerceFont, textFont, layout.font); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like you've based this on pie/defaults but you've got more logic around arrays in the input. So two questions:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I've tried to replicate the behaviour of pie traces. This is tested here. The test is a good example of the extra cases handled here. The main difference is that these attributes now also accept arrays (so that fonts can be defined per bar). I think a lot of the functionality implemented in this file could be moved to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool. Looks like the inheritance for non-arrays is as I'd expect 👍 . For arrays though, I'm not sure about the structure - I'd think for consistency with data attributes and src tags, it would be better to have family, size, and color be arrays, rather than have font be an array of objects. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't coerce entries inside data arrays or Non-text entries are usually via fallbacks later on in the pipeline e.g. in the drawing step for scatter The reason being: we try to make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What the pie trace type is currently doing (here) looks sufficient to me at the default step. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @etpinard I don't understand the phrase There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As in: there are about as many coerce statements as there are attributes. What you added above has about as many coerce statements as there are items in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @etpinard What are the reasons against making Having uncoerced data in arrays after running Another disadvantage of moving the code for array coercion from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perf over DRY.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @etpinard OK, I understand. Thx for the explanation. |
||
|
||
handleStyleDefaults(traceIn, traceOut, coerce, defaultColor, layout); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to clean (plotly.js lingo for backward-compatible mappings) attribute that have never been released.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what this line change is meant for; i.e. to exclude bar's
textposition
from those mappings.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. You're right. My mistake. 😄