Skip to content

Add new formatting options by replacing d3.format method with more recent d3-format module #5125

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

Merged
merged 26 commits into from
Jul 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5092c19
apply latest d3 number format instead of d3 v3 format
archmoj Jun 26, 2021
cd0d392
update baselines
archmoj Jun 26, 2021
c7ecdc7
reflect schema changes
archmoj Jul 7, 2021
320b270
draft log for PR 5615
archmoj Jul 7, 2021
3ea8d90
refactor adjustFormat
archmoj Jul 12, 2021
a5fd000
refactor number format functions
archmoj Jul 12, 2021
6b93e61
Merge remote-tracking branch 'origin/master' into new-d3-number-format
archmoj Jul 12, 2021
25a30a8
catch and handle bad d3 number format instead of throwing error
archmoj Jul 12, 2021
05b221c
point to d3-format v1.4.5 options not higher
archmoj Jul 12, 2021
a5a94cd
Merge remote-tracking branch 'origin/master' into new-d3-number-format
archmoj Jul 12, 2021
e88a134
link d3 v3 without d3.format
archmoj Jul 12, 2021
d5d282d
edit draft log
archmoj Jul 12, 2021
68fe2b7
Merge remote-tracking branch 'origin/master' into new-d3-number-format
archmoj Jul 12, 2021
17e73b6
cast to string in the case of bad format
archmoj Jul 12, 2021
785f128
add jasmine tests
archmoj Jul 12, 2021
dc0d9cb
removed d3.time now switch to use d3-time
archmoj Jul 13, 2021
a425925
correct comment
archmoj Jul 13, 2021
11a75d9
centralized fn Lib.beginCap to work with new d3 methods
archmoj Jul 13, 2021
dc94854
Merge remote-tracking branch 'origin/master' into new-d3-number-format
archmoj Jul 13, 2021
bdb69fc
Merge remote-tracking branch 'origin/master' into new-d3-number-format
archmoj Jul 14, 2021
693ebd7
Update src/lib/index.js
archmoj Jul 17, 2021
1efc41e
use titleCase function
archmoj Jul 17, 2021
878034b
warn once encountered a bad format
archmoj Jul 17, 2021
80d37d2
Merge remote-tracking branch 'origin/master' into new-d3-number-format
archmoj Jul 17, 2021
518029a
update baseline using Raleway font instead of Dosis
archmoj Jul 17, 2021
32898a1
bump plotly/d3 to v3.8.0
archmoj Jul 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions draftlogs/5615_add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add new formatting options by replacing `d3.format` method with more recent `d3-format` module [[#5615](https://github.com/plotly/plotly.js/pull/5615)]
18 changes: 15 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
]
},
"dependencies": {
"@plotly/d3": "3.7.0",
"@plotly/d3": "3.8.0",
"@plotly/d3-sankey": "0.7.2",
"@plotly/d3-sankey-circular": "0.33.1",
"@plotly/point-cluster": "^3.1.9",
Expand All @@ -82,10 +82,12 @@
"convex-hull": "^1.0.3",
"country-regex": "^1.1.0",
"d3-force": "^1.2.1",
"d3-format": "^1.4.5",
"d3-geo": "^1.12.1",
"d3-geo-projection": "^2.9.0",
"d3-hierarchy": "^1.1.9",
"d3-interpolate": "^1.4.0",
"d3-time": "^1.1.0",
"d3-time-format": "^2.2.3",
"delaunay-triangulate": "^1.1.6",
"fast-isnumeric": "^1.1.4",
Expand Down
5 changes: 3 additions & 2 deletions src/components/drawing/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
'use strict';

var d3 = require('@plotly/d3');
var Lib = require('../../lib');
var numberFormat = Lib.numberFormat;
var isNumeric = require('fast-isnumeric');
var tinycolor = require('tinycolor2');

var Registry = require('../../registry');
var Color = require('../color');
var Colorscale = require('../colorscale');
var Lib = require('../../lib');
var strTranslate = Lib.strTranslate;
var svgTextUtils = require('../../lib/svg_text_utils');

Expand Down Expand Up @@ -275,7 +276,7 @@ function makePointPath(symbolNumber, r) {

var HORZGRADIENT = {x1: 1, x2: 0, y1: 0, y2: 0};
var VERTGRADIENT = {x1: 0, x2: 0, y1: 1, y2: 0};
var stopFormatter = d3.format('~.1f');
var stopFormatter = numberFormat('~f');
var gradientInfo = {
radial: {node: 'radialGradient'},
radialreversed: {node: 'radialGradient', reversed: true},
Expand Down
12 changes: 8 additions & 4 deletions src/components/rangeselector/get_update_object.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var d3 = require('@plotly/d3');
var d3Time = require('d3-time');
var titleCase = require('../../lib').titleCase;

module.exports = function getUpdateObject(axisLayout, buttonLayout) {
var axName = axisLayout._name;
Expand All @@ -22,18 +23,21 @@ function getXRange(axisLayout, buttonLayout) {
var currentRange = axisLayout.range;
var base = new Date(axisLayout.r2l(currentRange[1]));
var step = buttonLayout.step;

var utcStep = d3Time['utc' + titleCase(step)];

var count = buttonLayout.count;
var range0;

switch(buttonLayout.stepmode) {
case 'backward':
range0 = axisLayout.l2r(+d3.time[step].utc.offset(base, -count));
range0 = axisLayout.l2r(+utcStep.offset(base, -count));
break;

case 'todate':
var base2 = d3.time[step].utc.offset(base, -count);
var base2 = utcStep.offset(base, -count);

range0 = axisLayout.l2r(+d3.time[step].utc.ceil(base2));
range0 = axisLayout.l2r(+utcStep.ceil(base2));
break;
}

Expand Down
2 changes: 1 addition & 1 deletion src/constants/docs.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

module.exports = {
FORMAT_LINK: 'https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format',
FORMAT_LINK: 'https://github.com/d3/d3-format/tree/v1.4.5#d3-format',
DATE_FORMAT_LINK: 'https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format'
};
47 changes: 44 additions & 3 deletions src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,56 @@

var d3 = require('@plotly/d3');
var utcFormat = require('d3-time-format').utcFormat;
var d3Format = require('d3-format').format;
var isNumeric = require('fast-isnumeric');

var numConstants = require('../constants/numerical');
var MAX_SAFE = numConstants.FP_SAFE;
var MIN_SAFE = -MAX_SAFE;
var BADNUM = numConstants.BADNUM;

var lib = module.exports = {
_numberFormat: d3.format // simply to test d3.format before switching to d3-format
var lib = module.exports = {};

lib.adjustFormat = function adjustFormat(formatStr) {
if(
!formatStr ||
/^\d[.]\df/.test(formatStr) ||
/[.]\d%/.test(formatStr)
) return formatStr;

if(formatStr === '0.f') return '~f';
if(/^\d%/.test(formatStr)) return '~%';
if(/^\ds/.test(formatStr)) return '~s';

// try adding tilde to the start of format in order to trim
if(!(/^[~,.0$]/.test(formatStr)) && /[&fps]/.test(formatStr)) return '~' + formatStr;

return formatStr;
};

var seenBadFormats = {};
lib.warnBadFormat = function(f) {
var key = String(f);
if(!seenBadFormats[key]) {
seenBadFormats[key] = 1;
lib.warn('encountered bad format: "' + key + '"');
}
};

lib.noFormat = function(value) {
return String(value);
};

lib.numberFormat = function(formatStr) {
var fn;
try {
fn = d3Format(lib.adjustFormat(formatStr));
} catch(e) {
lib.warnBadFormat(formatStr);
return lib.noFormat;
}

return fn;
};

lib.nestedProperty = require('./nested_property');
Expand Down Expand Up @@ -1122,7 +1163,7 @@ function templateFormatString(string, labels, d3locale) {
if(format) {
var fmt;
if(format[0] === ':') {
fmt = d3locale ? d3locale.numberFormat : d3.format;
fmt = d3locale ? d3locale.numberFormat : lib.numberFormat;
value = fmt(format.replace(TEMPLATE_STRING_FORMAT_SEPARATOR, ''))(value);
}

Expand Down
7 changes: 4 additions & 3 deletions src/plots/cartesian/dragbox.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'use strict';

var d3 = require('@plotly/d3');
var Lib = require('../../lib');
var numberFormat = Lib.numberFormat;
var tinycolor = require('tinycolor2');
var supportsPassive = require('has-passive-events');

var Registry = require('../../registry');
var Lib = require('../../lib');
var strTranslate = Lib.strTranslate;
var svgTextUtils = require('../../lib/svg_text_utils');
var Color = require('../../components/color');
Expand Down Expand Up @@ -1029,11 +1030,11 @@ function getEndText(ax, end) {
return initialVal;
} else if(ax.type === 'log') {
dig = Math.ceil(Math.max(0, -Math.log(diff) / Math.LN10)) + 3;
return d3.format('.' + dig + 'g')(Math.pow(10, initialVal));
return numberFormat('.' + dig + 'g')(Math.pow(10, initialVal));
} else { // linear numeric (or category... but just show numbers here)
dig = Math.floor(Math.log(Math.abs(initialVal)) / Math.LN10) -
Math.floor(Math.log(diff) / Math.LN10) + 4;
return d3.format('.' + String(dig) + 'g')(initialVal);
return numberFormat('.' + String(dig) + 'g')(initialVal);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/plots/cartesian/set_convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

var d3 = require('@plotly/d3');
var utcFormat = require('d3-time-format').utcFormat;
var Lib = require('../../lib');
var numberFormat = Lib.numberFormat;
var isNumeric = require('fast-isnumeric');

var Lib = require('../../lib');
var cleanNumber = Lib.cleanNumber;
var ms2DateTime = Lib.ms2DateTime;
var dateTime2ms = Lib.dateTime2ms;
Expand Down Expand Up @@ -953,7 +954,7 @@ module.exports = function setConvert(ax, fullLayout) {
// occasionally we need _numFormat to pass through
// even though it won't be needed by this axis
ax._separators = fullLayout.separators;
ax._numFormat = locale ? locale.numberFormat : d3.format;
ax._numFormat = locale ? locale.numberFormat : numberFormat;

// and for bar charts and box plots: reset forced minimum tick spacing
delete ax._minDtick;
Expand Down
2 changes: 1 addition & 1 deletion src/plots/geo/geo.js
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ function getProjection(geoLayout) {

var projName = constants.projNames[projType];
// uppercase the first letter and add geo to the start of method name
projName = 'geo' + projName.charAt(0).toUpperCase() + projName.slice(1);
projName = 'geo' + Lib.titleCase(projName);
var projFn = geo[projName] || geoProjection[projName];
var projection = projFn();

Expand Down
14 changes: 13 additions & 1 deletion src/plots/plots.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

var d3 = require('@plotly/d3');
var timeFormatLocale = require('d3-time-format').timeFormatLocale;
var formatLocale = require('d3-format').formatLocale;
var isNumeric = require('fast-isnumeric');

var Registry = require('../registry');
Expand Down Expand Up @@ -702,7 +703,18 @@ function getFormatter(formatObj, separators) {
formatObj.thousands = separators.charAt(1);

return {
numberFormat: d3.locale(formatObj).numberFormat,
numberFormat: function(formatStr) {
try {
formatStr = formatLocale(formatObj).format(
Lib.adjustFormat(formatStr)
);
} catch(e) {
Lib.warnBadFormat(formatStr);
return Lib.noFormat;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this catching invalid format strings? Do we want to lib.warn when this happens, to help people fix it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 878034b

}

return formatStr;
},
timeFormat: timeFormatLocale(formatObj).utcFormat
};
}
Expand Down
7 changes: 4 additions & 3 deletions src/traces/parcoords/parcoords.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use strict';

var d3 = require('@plotly/d3');
var Lib = require('../../lib');
var numberFormat = Lib.numberFormat;
var rgba = require('color-rgba');

var Axes = require('../../plots/cartesian/axes');
var Lib = require('../../lib');
var strRotate = Lib.strRotate;
var strTranslate = Lib.strTranslate;
var svgTextUtils = require('../../lib/svg_text_utils');
Expand Down Expand Up @@ -79,7 +80,7 @@ function domainScale(height, padding, dimension, tickvals, ticktext) {
var extent = dimensionExtent(dimension);
if(tickvals) {
return d3.scale.ordinal()
.domain(tickvals.map(toText(d3.format(dimension.tickformat), ticktext)))
.domain(tickvals.map(toText(numberFormat(dimension.tickformat), ticktext)))
.range(tickvals
.map(function(d) {
var unitVal = (d - extent[0]) / (extent[1] - extent[0]);
Expand Down Expand Up @@ -266,7 +267,7 @@ function viewModel(state, callbacks, model) {

// ensure ticktext and tickvals have same length
if(!Array.isArray(ticktext) || !ticktext.length) {
ticktext = tickvals.map(d3.format(dimension.tickformat));
ticktext = tickvals.map(numberFormat(dimension.tickformat));
} else if(ticktext.length > tickvals.length) {
ticktext = ticktext.slice(0, tickvals.length);
} else if(tickvals.length > ticktext.length) {
Expand Down
11 changes: 6 additions & 5 deletions src/traces/sankey/plot.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use strict';

var d3 = require('@plotly/d3');
var Lib = require('../../lib');
var numberFormat = Lib.numberFormat;
var render = require('./render');
var Fx = require('../../components/fx');
var Color = require('../../components/color');
var Lib = require('../../lib');
var cn = require('./constants').cn;

var _ = Lib._;
Expand Down Expand Up @@ -192,7 +193,7 @@ module.exports = function plot(gd, calcData) {
link.fullData = link.trace;
obj = d.link.trace.link;
var hoverCenter = hoverCenterPosition(link);
var hovertemplateLabels = {valueLabel: d3.format(d.valueFormat)(link.value) + d.valueSuffix};
var hovertemplateLabels = {valueLabel: numberFormat(d.valueFormat)(link.value) + d.valueSuffix};

hoverItems.push({
x: hoverCenter[0],
Expand All @@ -202,7 +203,7 @@ module.exports = function plot(gd, calcData) {
link.label || '',
sourceLabel + link.source.label,
targetLabel + link.target.label,
link.concentrationscale ? concentrationLabel + d3.format('%0.2f')(link.flow.labelConcentration) : ''
link.concentrationscale ? concentrationLabel + numberFormat('%0.2f')(link.flow.labelConcentration) : ''
].filter(renderableValuePresent).join('<br>'),
color: castHoverOption(obj, 'bgcolor') || Color.addOpacity(link.color, 1),
borderColor: castHoverOption(obj, 'bordercolor'),
Expand Down Expand Up @@ -281,7 +282,7 @@ module.exports = function plot(gd, calcData) {
var hoverCenterX1 = boundingBox.right + 2 - rootBBox.left;
var hoverCenterY = boundingBox.top + boundingBox.height / 4 - rootBBox.top;

var hovertemplateLabels = {valueLabel: d3.format(d.valueFormat)(d.node.value) + d.valueSuffix};
var hovertemplateLabels = {valueLabel: numberFormat(d.valueFormat)(d.node.value) + d.valueSuffix};
d.node.fullData = d.node.trace;

gd._fullLayout._calcInverseTransform(gd);
Expand All @@ -292,7 +293,7 @@ module.exports = function plot(gd, calcData) {
x0: scaleX * hoverCenterX0,
x1: scaleX * hoverCenterX1,
y: scaleY * hoverCenterY,
name: d3.format(d.valueFormat)(d.node.value) + d.valueSuffix,
name: numberFormat(d.valueFormat)(d.node.value) + d.valueSuffix,
text: [
d.node.label,
incomingLabel + d.node.targetLinks.length,
Expand Down
4 changes: 3 additions & 1 deletion src/traces/table/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

var c = require('./constants');
var d3 = require('@plotly/d3');
var Lib = require('../../lib');
var numberFormat = Lib.numberFormat;
var gup = require('../../lib/gup');
var Drawing = require('../../components/drawing');
var svgUtil = require('../../lib/svg_text_utils');
Expand Down Expand Up @@ -528,7 +530,7 @@ function populateCellText(cellText, tableControlView, allColumnBlock, gd) {
var suffix = latex ? '' : gridPick(d.calcdata.cells.suffix, col, row) || '';
var format = latex ? null : gridPick(d.calcdata.cells.format, col, row) || null;

var prefixSuffixedText = prefix + (format ? d3.format(format)(d.value) : d.value) + suffix;
var prefixSuffixedText = prefix + (format ? numberFormat(format)(d.value) : d.value) + suffix;

var hasWrapSplitCharacter;
d.wrappingNeeded = !d.wrapped && !userBrokenText && !latex && (hasWrapSplitCharacter = hasWrapCharacter(prefixSuffixedText));
Expand Down
Binary file modified test/image/baselines/indicator_bignumber.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/tick-percent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading