Skip to content

Upgrade d3 formats #5023

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

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -69,8 +69,10 @@
"country-regex": "^1.1.0",
"d3": "^3.5.17",
"d3-force": "^1.2.1",
"d3-format": "^1.4.4",
"d3-hierarchy": "^1.1.9",
"d3-interpolate": "^1.4.0",
"d3-time-format": "^2.2.3",
"delaunay-triangulate": "^1.1.6",
"es6-promise": "^4.2.8",
"fast-isnumeric": "^1.1.4",
3 changes: 2 additions & 1 deletion src/components/drawing/index.js
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
'use strict';

var d3 = require('d3');
var numberFormat = require('d3-format').format;
var isNumeric = require('fast-isnumeric');
var tinycolor = require('tinycolor2');

@@ -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},
4 changes: 2 additions & 2 deletions src/constants/docs.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,6 @@
'use strict';

module.exports = {
FORMAT_LINK: 'https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format',
DATE_FORMAT_LINK: 'https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format'
FORMAT_LINK: 'https://github.com/d3/d3-format#format',
DATE_FORMAT_LINK: 'https://github.com/d3/d3-time-format#locale_format'
};
2 changes: 1 addition & 1 deletion src/lib/dates.js
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ var EPOCHJD = constants.EPOCHJD;

var Registry = require('../registry');

var utcFormat = d3.time.format.utc;
var utcFormat = require('d3-time-format').utcFormat;

var DATETIME_REGEXP = /^\s*(-?\d\d\d\d|\d\d)(-(\d?\d)(-(\d?\d)([ Tt]([01]?\d|2[0-3])(:([0-5]\d)(:([0-5]\d(\.\d+)?))?(Z|z|[+\-]\d\d(:?\d\d)?)?)?)?)?)?\s*$/m;
// special regex for chinese calendars to support yyyy-mmi-dd etc for intercalary months
7 changes: 4 additions & 3 deletions src/lib/index.js
Original file line number Diff line number Diff line change
@@ -8,7 +8,8 @@

'use strict';

var d3 = require('d3');
var numberFormat = require('d3-format').format;
var utcFormat = require('d3-time-format').utcFormat;
var isNumeric = require('fast-isnumeric');

var numConstants = require('../constants/numerical');
@@ -1077,12 +1078,12 @@ function templateFormatString(string, labels, d3locale) {
if(format) {
var fmt;
if(format[0] === ':') {
fmt = d3locale ? d3locale.numberFormat : d3.format;
fmt = numberFormat;
value = fmt(format.replace(TEMPLATE_STRING_FORMAT_SEPARATOR, ''))(value);
}

if(format[0] === '|') {
fmt = d3locale ? d3locale.timeFormat.utc : d3.time.format.utc;
fmt = d3locale ? d3locale.utcFormat : utcFormat;
var ms = lib.dateTime2ms(value);
value = lib.formatDate(ms, format.replace(TEMPLATE_STRING_FORMAT_SEPARATOR, ''), false, fmt);
}
5 changes: 3 additions & 2 deletions src/plots/cartesian/dragbox.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
'use strict';

var d3 = require('d3');
var numberFormat = require('d3-format').format;
var tinycolor = require('tinycolor2');
var supportsPassive = require('has-passive-events');

@@ -983,11 +984,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);
}
}

6 changes: 4 additions & 2 deletions src/plots/cartesian/set_convert.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@
'use strict';

var d3 = require('d3');
var numberFormat = require('d3-format').format;
var utcFormat = require('d3-time-format').utcFormat;
var isNumeric = require('fast-isnumeric');

var Lib = require('../../lib');
@@ -954,13 +956,13 @@ module.exports = function setConvert(ax, fullLayout) {
// Fall back on default format for dummy axes that don't care about formatting
var locale = fullLayout._d3locale;
if(ax.type === 'date') {
ax._dateFormat = locale ? locale.timeFormat.utc : d3.time.format.utc;
ax._dateFormat = locale ? locale.utcFormat : utcFormat;
ax._extraFormat = fullLayout._extraFormat;
}
// 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 = numberFormat;

// and for bar charts and box plots: reset forced minimum tick spacing
delete ax._minDtick;
3 changes: 2 additions & 1 deletion src/plots/plots.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
'use strict';

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

var Registry = require('../registry');
@@ -723,7 +724,7 @@ function getFormatter(formatObj, separators) {
formatObj.decimal = separators.charAt(0);
formatObj.thousands = separators.charAt(1);

return d3.locale(formatObj);
return timeFormatLocale(formatObj);
}

function fillMetaTextHelpers(newFullData, newFullLayout) {
2 changes: 1 addition & 1 deletion src/traces/indicator/defaults.js
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
}
coerce('delta.reference', traceOut.value);
coerce('delta.relative');
coerce('delta.valueformat', traceOut.delta.relative ? '2%' : '');
coerce('delta.valueformat', traceOut.delta.relative ? '.0%' : '');
coerce('delta.increasing.symbol');
coerce('delta.increasing.color');
coerce('delta.decreasing.symbol');
5 changes: 3 additions & 2 deletions src/traces/parcoords/parcoords.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
'use strict';

var d3 = require('d3');
var numberFormat = require('d3-format').format;
var rgba = require('color-rgba');

var Axes = require('../../plots/cartesian/axes');
@@ -85,7 +86,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]);
@@ -272,7 +273,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) {
9 changes: 5 additions & 4 deletions src/traces/sankey/plot.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
'use strict';

var d3 = require('d3');
var numberFormat = require('d3-format').format;
var render = require('./render');
var Fx = require('../../components/fx');
var Color = require('../../components/color');
@@ -200,7 +201,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],
@@ -210,7 +211,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'),
@@ -289,14 +290,14 @@ 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;

var tooltip = Fx.loneHover({
x0: hoverCenterX0,
x1: hoverCenterX1,
y: 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,
3 changes: 2 additions & 1 deletion src/traces/table/plot.js
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@

var c = require('./constants');
var d3 = require('d3');
var numberFormat = require('d3-format').format;
var gup = require('../../lib/gup');
var Drawing = require('../../components/drawing');
var svgUtil = require('../../lib/svg_text_utils');
@@ -534,7 +535,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));
2 changes: 1 addition & 1 deletion test/image/mocks/texttemplate_scatter.json
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
"Toronto",
"Vancouver"
],
"texttemplate": "%{text}: (%{lon:.0f}, %{lat:0.f}): %{customdata:.2s}",
"texttemplate": "%{text}: (%{lon:.0f}, %{lat:~f}): %{customdata:.2s}",
"textposition": "top center",
"customdata": [1780000, 2930000, 675218],
"geo": "geo"
3 changes: 2 additions & 1 deletion test/jasmine/tests/axes_test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var Plotly = require('@lib/index');
var d3 = require('d3');
var utcFormat = require('d3-time-format').utcFormat;

var Plots = require('@src/plots/plots');
var Lib = require('@src/lib');
@@ -5206,7 +5207,7 @@ function getZoomOutButton(gd) {
}

function getFormatter(format) {
return d3.time.format.utc(format);
return utcFormat(format);
}

describe('Test Axes.getTickformat', function() {
8 changes: 4 additions & 4 deletions test/jasmine/tests/indicator_test.js
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ describe('Indicator defaults', function() {

it('defaults to displaying relative changes in percentage', function() {
var out = _supply({type: 'indicator', mode: 'delta', delta: {relative: true}, value: 1});
expect(out.delta.valueformat).toBe('2%');
expect(out.delta.valueformat).toBe('.0%');
});

it('should not ignore empty valueformat', function() {
@@ -164,7 +164,7 @@ describe('Indicator plot', function() {
Plotly.newPlot(gd, [{
type: 'indicator',
value: 500,
number: {valueformat: '0.f'}
number: {valueformat: '~f'}
}], {width: 400, height: 400})
.then(function() {
checkNumbersScale(1, 'initialy at normal scale');
@@ -185,7 +185,7 @@ describe('Indicator plot', function() {
Plotly.newPlot(gd, [{
type: 'indicator',
value: 1,
number: {valueformat: '0.f'}
number: {valueformat: '~f'}
}], {width: 400, height: 400})
.then(function() {
checkNumbersScale(1, 'initialy at normal scale');
@@ -208,7 +208,7 @@ describe('Indicator plot', function() {
type: 'indicator',
mode: 'number+delta',
value: 1,
number: {valueformat: '0.f'}
number: {valueformat: '~f'}
};
figure[numberType] = {font: {size: 100}};
Plotly.newPlot(gd, [figure], {width: 400, height: 400})
10 changes: 3 additions & 7 deletions test/jasmine/tests/localize_test.js
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ var _ = Lib._;
var Registry = require('@src/registry');

var d3 = require('d3');
var utcFormat = require('d3-time-format').utcFormat;

var Plotly = require('@lib');
var createGraphDiv = require('../assets/create_graph_div');
@@ -236,7 +237,7 @@ describe('localization', function() {
expect(firstYLabel()).toBe('0~5');
var d0 = new Date(0); // thursday, Jan 1 1970 (UTC)
// sanity check that d0 is what we think...
expect(d3.time.format.utc('%a %b %A %B')(d0)).toBe('Thu Jan Thursday January');
expect(utcFormat('%a %b %A %B')(d0)).toBe('Thu Jan Thursday January');
// full names were not overridden, so fall back on english
expect(gd._fullLayout.xaxis._dateFormat('%a %b %A %B')(d0)).toBe('t !1 Thursday January');
})
@@ -306,15 +307,10 @@ describe('localization', function() {
.then(function() {
expect(firstYLabel()).toBe('0p5');

return Plotly.relayout(gd, {'yaxis.tickformat': '.3f'});
})
.then(function() {
expect(firstYLabel()).toBe('0p500');

return Plotly.relayout(gd, {separators: null});
})
.then(function() {
expect(firstYLabel()).toBe('0D500');
expect(firstYLabel()).toBe('0D5');
})
.catch(failTest)
.then(done);