Skip to content

Commit

Permalink
Merge pull request #6990 from plotly/font-weight-integer
Browse files Browse the repository at this point in the history
Add support for numeric font `weight`
  • Loading branch information
archmoj committed May 8, 2024
2 parents 8cb1191 + 48d057f commit d135fff
Show file tree
Hide file tree
Showing 36 changed files with 3,855 additions and 1,059 deletions.
1 change: 1 addition & 0 deletions draftlogs/6990_add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add support for numeric text font `weight` [[#6990](https://github.com/plotly/plotly.js/pull/6990)]
15 changes: 14 additions & 1 deletion src/lib/coerce.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ exports.valObjectMeta = {
requiredOpts: [],
otherOpts: ['dflt', 'min', 'max', 'arrayOk'],
coerceFunction: function(v, propOut, dflt, opts) {
if(isTypedArraySpec(v)) v = decodeTypedArraySpec(v);

if(!isNumeric(v) ||
(opts.min !== undefined && v < opts.min) ||
(opts.max !== undefined && v > opts.max)) {
Expand All @@ -114,8 +116,15 @@ exports.valObjectMeta = {
'are coerced to the `dflt`.'
].join(' '),
requiredOpts: [],
otherOpts: ['dflt', 'min', 'max', 'arrayOk'],
otherOpts: ['dflt', 'min', 'max', 'arrayOk', 'extras'],
coerceFunction: function(v, propOut, dflt, opts) {
if((opts.extras || []).indexOf(v) !== -1) {
propOut.set(v);
return;
}

if(isTypedArraySpec(v)) v = decodeTypedArraySpec(v);

if(v % 1 || !isNumeric(v) ||
(opts.min !== undefined && v < opts.min) ||
(opts.max !== undefined && v > opts.max)) {
Expand Down Expand Up @@ -156,6 +165,8 @@ exports.valObjectMeta = {
requiredOpts: [],
otherOpts: ['dflt', 'arrayOk'],
coerceFunction: function(v, propOut, dflt) {
if(isTypedArraySpec(v)) v = decodeTypedArraySpec(v);

if(tinycolor(v).isValid()) propOut.set(v);
else propOut.set(dflt);
}
Expand Down Expand Up @@ -198,6 +209,8 @@ exports.valObjectMeta = {
requiredOpts: [],
otherOpts: ['dflt', 'arrayOk'],
coerceFunction: function(v, propOut, dflt) {
if(isTypedArraySpec(v)) v = decodeTypedArraySpec(v);

if(v === 'auto') propOut.set('auto');
else if(!isNumeric(v)) propOut.set(dflt);
else propOut.set(modHalf(+v, 360));
Expand Down
31 changes: 22 additions & 9 deletions src/plots/font_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ module.exports = function(opts) {
var editType = opts.editType;
var colorEditType = opts.colorEditType;
if(colorEditType === undefined) colorEditType = editType;

var weight = {
editType: editType,
valType: 'integer',
min: 1,
max: 1000,
extras: ['normal', 'bold'],
dflt: 'normal',
description: [
'Sets the weight (or boldness) of the font.'
].join(' ')
};

if(opts.noNumericWeightValues) {
weight.valType = 'enumerated';
weight.values = weight.extras;
weight.extras = undefined;
weight.min = undefined;
weight.max = undefined;
}

var attrs = {
family: {
valType: 'string',
Expand Down Expand Up @@ -49,15 +70,7 @@ module.exports = function(opts) {
editType: colorEditType
},

weight: {
editType: editType,
valType: 'enumerated',
values: ['normal', 'bold'],
dflt: 'normal',
description: [
'Sets the weight (or boldness) of the font.'
].join(' ')
},
weight: weight,

style: {
editType: editType,
Expand Down
2 changes: 1 addition & 1 deletion src/snapshot/tosvg.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ module.exports = function toSVG(gd, format, scale) {

// Drop normal font-weight, font-style and font-variant to reduce the size
var fw = this.style.fontWeight;
if(fw && fw === 'normal') {
if(fw && (fw === 'normal' || fw === '400')) { // font-weight 400 is similar to normal
txt.style('font-weight', undefined);
}
var fs = this.style.fontStyle;
Expand Down
1 change: 1 addition & 0 deletions src/traces/scattergl/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var attrs = module.exports = overrideAll({
editType: 'calc',
colorEditType: 'style',
arrayOk: true,
noNumericWeightValues: true,
variantValues: ['normal', 'small-caps'],
description: 'Sets the text font.'
}),
Expand Down
14 changes: 11 additions & 3 deletions src/traces/scattergl/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function convertTextStyle(gd, trace) {
if(
isArrayOrTypedArray(tfs) ||
Array.isArray(tff) ||
Array.isArray(tfw) ||
isArrayOrTypedArray(tfw) ||
Array.isArray(tfy) ||
Array.isArray(tfv)
) {
Expand All @@ -207,7 +207,7 @@ function convertTextStyle(gd, trace) {
) * plotGlPixelRatio;

fonti.family = Array.isArray(tff) ? tff[i] : tff;
fonti.weight = Array.isArray(tfw) ? tfw[i] : tfw;
fonti.weight = weightFallBack(isArrayOrTypedArray(tfw) ? tfw[i] : tfw);
fonti.style = Array.isArray(tfy) ? tfy[i] : tfy;
fonti.variant = Array.isArray(tfv) ? tfv[i] : tfv;
}
Expand All @@ -216,7 +216,7 @@ function convertTextStyle(gd, trace) {
optsOut.font = {
size: tfs * plotGlPixelRatio,
family: tff,
weight: tfw,
weight: weightFallBack(tfw),
style: tfy,
variant: tfv
};
Expand All @@ -225,6 +225,14 @@ function convertTextStyle(gd, trace) {
return optsOut;
}

// scattergl rendering pipeline has limited support of numeric weight values
// Here we map the numbers to be either bold or normal.
function weightFallBack(w) {
if(w <= 1000) {
return w > 500 ? 'bold' : 'normal';
}
return w;
}

function convertMarkerStyle(gd, trace) {
var count = trace._length;
Expand Down
45 changes: 45 additions & 0 deletions src/traces/scattermapbox/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use strict';

// Must use one of the following fonts as the family, else default to 'Open Sans Regular'
// See https://github.com/openmaptiles/fonts/blob/gh-pages/fontstacks.json
var supportedFonts = [
'Metropolis Black Italic',
'Metropolis Black',
'Metropolis Bold Italic',
'Metropolis Bold',
'Metropolis Extra Bold Italic',
'Metropolis Extra Bold',
'Metropolis Extra Light Italic',
'Metropolis Extra Light',
'Metropolis Light Italic',
'Metropolis Light',
'Metropolis Medium Italic',
'Metropolis Medium',
'Metropolis Regular Italic',
'Metropolis Regular',
'Metropolis Semi Bold Italic',
'Metropolis Semi Bold',
'Metropolis Thin Italic',
'Metropolis Thin',
'Open Sans Bold Italic',
'Open Sans Bold',
'Open Sans Extrabold Italic',
'Open Sans Extrabold',
'Open Sans Italic',
'Open Sans Light Italic',
'Open Sans Light',
'Open Sans Regular',
'Open Sans Semibold Italic',
'Open Sans Semibold',
'Klokantech Noto Sans Bold',
'Klokantech Noto Sans CJK Bold',
'Klokantech Noto Sans CJK Regular',
'Klokantech Noto Sans Italic',
'Klokantech Noto Sans Regular'
];

module.exports = {
isSupportedFont: function(a) {
return supportedFonts.indexOf(a) !== -1;
}
};
60 changes: 54 additions & 6 deletions src/traces/scattermapbox/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var Colorscale = require('../../components/colorscale');
var Drawing = require('../../components/drawing');
var makeBubbleSizeFn = require('../scatter/make_bubble_size_func');
var subTypes = require('../scatter/subtypes');
var isSupportedFont = require('./constants').isSupportedFont;
var convertTextOpts = require('../../plots/mapbox/convert_text_opts');
var appendArrayPointValue = require('../../components/fx/helpers').appendArrayPointValue;

Expand Down Expand Up @@ -369,11 +370,58 @@ function arrayifyAttribute(values, step) {

function getTextFont(trace) {
var font = trace.textfont;
var str = '';
if(font.weight === 'bold') str += ' Bold';
if(font.style === 'italic') str += ' Italic';
var textFont = font.family;
if(str) textFont = textFont.replace(' Regular', str);
textFont = textFont.split(', ');
var family = font.family;
var style = font.style;
var weight = font.weight;

var parts = family.split(' ');
var isItalic = parts[parts.length - 1] === 'Italic';
if(isItalic) parts.pop();
isItalic = isItalic || style === 'italic';

var str = parts.join(' ');
if(weight === 'bold' && parts.indexOf('Bold') === -1) {
str += ' Bold';
} else if(weight <= 1000) { // numeric font-weight
// See supportedFonts

if(parts[0] === 'Metropolis') {
str = 'Metropolis';
if(weight > 850) str += ' Black';
else if(weight > 750) str += ' Extra Bold';
else if(weight > 650) str += ' Bold';
else if(weight > 550) str += ' Semi Bold';
else if(weight > 450) str += ' Medium';
else if(weight > 350) str += ' Regular';
else if(weight > 250) str += ' Light';
else if(weight > 150) str += ' Extra Light';
else str += ' Thin';
} else if(parts.slice(0, 2).join(' ') === 'Open Sans') {
str = 'Open Sans';
if(weight > 750) str += ' Extrabold';
else if(weight > 650) str += ' Bold';
else if(weight > 550) str += ' Semibold';
else if(weight > 350) str += ' Regular';
else str += ' Light';
} else if(parts.slice(0, 3).join(' ') === 'Klokantech Noto Sans') {
str = 'Klokantech Noto Sans';
if(parts[3] === 'CJK') str += ' CJK';
str += (weight > 500) ? ' Bold' : ' Regular';
}
}

if(isItalic) str += ' Italic';

if(str === 'Open Sans Regular Italic') str = 'Open Sans Italic';
else if(str === 'Open Sans Regular Bold') str = 'Open Sans Bold';
else if(str === 'Open Sans Regular Bold Italic') str = 'Open Sans Bold Italic';
else if(str === 'Klokantech Noto Sans Regular Italic') str = 'Klokantech Noto Sans Italic';

// Ensure the result is a supported font
if(!isSupportedFont(str)) {
str = family;
}

var textFont = str.split(', ');
return textFont;
}
43 changes: 4 additions & 39 deletions src/traces/scattermapbox/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,7 @@ var handleLineDefaults = require('../scatter/line_defaults');
var handleTextDefaults = require('../scatter/text_defaults');
var handleFillColorDefaults = require('../scatter/fillcolor_defaults');
var attributes = require('./attributes');

// Must use one of the following fonts as the family, else default to 'Open Sans Regular'
// See https://github.com/openmaptiles/fonts/blob/gh-pages/fontstacks.json
var supportedFonts = [
'Metropolis Black Italic',
'Metropolis Black',
'Metropolis Bold Italic',
'Metropolis Bold',
'Metropolis Extra Bold Italic',
'Metropolis Extra Bold',
'Metropolis Extra Light Italic',
'Metropolis Extra Light',
'Metropolis Light Italic',
'Metropolis Light',
'Metropolis Medium Italic',
'Metropolis Medium',
'Metropolis Regular Italic',
'Metropolis Regular',
'Metropolis Semi Bold Italic',
'Metropolis Semi Bold',
'Metropolis Thin Italic',
'Metropolis Thin',
'Open Sans Bold Italic',
'Open Sans Bold',
'Open Sans Extra Bold Italic',
'Open Sans Extra Bold',
'Open Sans Italic',
'Open Sans Light Italic',
'Open Sans Light',
'Open Sans Regular',
'Open Sans Semibold Italic',
'Open Sans Semibold',
'Klokantech Noto Sans Bold',
'Klokantech Noto Sans CJK Bold',
'Klokantech Noto Sans CJK Regular',
'Klokantech Noto Sans Italic',
'Klokantech Noto Sans Regular'
];
var isSupportedFont = require('./constants').isSupportedFont;

module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
function coerce(attr, dflt) {
Expand Down Expand Up @@ -104,12 +67,14 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
var clusterEnabled = coerce('cluster.enabled', clusterEnabledDflt);

if(clusterEnabled || subTypes.hasText(traceOut)) {
var layoutFontFamily = layout.font.family;

handleTextDefaults(traceIn, traceOut, layout, coerce,
{
noSelect: true,
noFontVariant: true,
font: {
family: supportedFonts.indexOf(layout.font.family) !== -1 ? layout.font.family : 'Open Sans Regular',
family: isSupportedFont(layoutFontFamily) ? layoutFontFamily : 'Open Sans Regular',
weight: layout.font.weight,
style: layout.font.style,
size: layout.font.size,
Expand Down
Loading

0 comments on commit d135fff

Please sign in to comment.