Skip to content

Commit 24ac0ec

Browse files
authored
Merge pull request #4185 from plotly/treemap-finalist
Treemap new trace type
2 parents 1dee68b + 3c12bf6 commit 24ac0ec

File tree

86 files changed

+18639
-444
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+18639
-444
lines changed

lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Plotly.register([
2626

2727
require('./pie'),
2828
require('./sunburst'),
29+
require('./treemap'),
2930
require('./funnelarea'),
3031

3132
require('./scatter3d'),

lib/treemap.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright 2012-2019, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
module.exports = require('../src/traces/treemap');

src/lib/index.js

+33
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,10 @@ lib.isValidTextValue = function(v) {
11591159
return v || v === 0;
11601160
};
11611161

1162+
/**
1163+
* @param {number} ratio
1164+
* @param {number} n (number of decimal places)
1165+
*/
11621166
lib.formatPercent = function(ratio, n) {
11631167
n = n || 0;
11641168
var str = (Math.round(100 * ratio * Math.pow(10, n)) * Math.pow(0.1, n)).toFixed(n) + '%';
@@ -1175,3 +1179,32 @@ lib.isHidden = function(gd) {
11751179
var display = window.getComputedStyle(gd).display;
11761180
return !display || display === 'none';
11771181
};
1182+
1183+
lib.getTextTransform = function(opts) {
1184+
var textX = opts.textX;
1185+
var textY = opts.textY;
1186+
var targetX = opts.targetX;
1187+
var targetY = opts.targetY;
1188+
var scale = opts.scale;
1189+
var rotate = opts.rotate;
1190+
1191+
var transformScale;
1192+
var transformRotate;
1193+
var transformTranslate;
1194+
1195+
if(scale < 1) transformScale = 'scale(' + scale + ') ';
1196+
else {
1197+
scale = 1;
1198+
transformScale = '';
1199+
}
1200+
1201+
transformRotate = (rotate) ?
1202+
'rotate(' + rotate + ' ' + textX + ' ' + textY + ') ' : '';
1203+
1204+
// Note that scaling also affects the center of the text box
1205+
var translateX = (targetX - scale * textX);
1206+
var translateY = (targetY - scale * textY);
1207+
transformTranslate = 'translate(' + translateX + ' ' + translateY + ')';
1208+
1209+
return transformTranslate + transformScale + transformRotate;
1210+
};

src/plot_api/plot_api.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -2450,7 +2450,7 @@ var traceUIControlPatterns = [
24502450
{pattern: /(^|value\.)visible$/, attr: 'legend.uirevision'},
24512451
{pattern: /^dimensions\[\d+\]\.constraintrange/},
24522452
{pattern: /^node\.(x|y|groups)/}, // for Sankey nodes
2453-
{pattern: /^level$/}, // for Sunburst traces
2453+
{pattern: /^level$/}, // for Sunburst & Treemap traces
24542454

24552455
// below this you must be in editable: true mode
24562456
// TODO: I still put name and title with `trace.uirevision`
@@ -3781,6 +3781,9 @@ function makePlotFramework(gd) {
37813781
// single pie layer for the whole plot
37823782
fullLayout._pielayer = fullLayout._paper.append('g').classed('pielayer', true);
37833783

3784+
// single treemap layer for the whole plot
3785+
fullLayout._treemaplayer = fullLayout._paper.append('g').classed('treemaplayer', true);
3786+
37843787
// single sunburst layer for the whole plot
37853788
fullLayout._sunburstlayer = fullLayout._paper.append('g').classed('sunburstlayer', true);
37863789

src/plots/plots.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ var axisIDs = require('./cartesian/axis_ids');
2323
var animationAttrs = require('./animation_attributes');
2424
var frameAttrs = require('./frame_attributes');
2525

26+
var getModuleCalcData = require('../plots/get_data').getModuleCalcData;
27+
2628
var relinkPrivateKeys = Lib.relinkPrivateKeys;
2729
var _ = Lib._;
2830

@@ -2789,9 +2791,10 @@ plots.doCalcdata = function(gd, traces) {
27892791
gd._hmpixcount = 0;
27902792
gd._hmlumcount = 0;
27912793

2792-
// for sharing colors across pies / sunbursts / funnelarea (and for legend)
2794+
// for sharing colors across pies / sunbursts / treemap / funnelarea (and for legend)
27932795
fullLayout._piecolormap = {};
27942796
fullLayout._sunburstcolormap = {};
2797+
fullLayout._treemapcolormap = {};
27952798
fullLayout._funnelareacolormap = {};
27962799

27972800
// If traces were specified and this trace was not included,
@@ -3221,3 +3224,18 @@ plots.generalUpdatePerTraceModule = function(gd, subplot, subplotCalcData, subpl
32213224
// update moduleName -> calcData hash
32223225
subplot.traceHash = traceHash;
32233226
};
3227+
3228+
plots.plotBasePlot = function(desiredType, gd, traces, transitionOpts, makeOnCompleteCallback) {
3229+
var _module = Registry.getModule(desiredType);
3230+
var cdmodule = getModuleCalcData(gd.calcdata, _module)[0];
3231+
_module.plot(gd, cdmodule, transitionOpts, makeOnCompleteCallback);
3232+
};
3233+
3234+
plots.cleanBasePlot = function(desiredType, newFullData, newFullLayout, oldFullData, oldFullLayout) {
3235+
var had = (oldFullLayout._has && oldFullLayout._has(desiredType));
3236+
var has = (newFullLayout._has && newFullLayout._has(desiredType));
3237+
3238+
if(had && !has) {
3239+
oldFullLayout['_' + desiredType + 'layer'].selectAll('g.trace').remove();
3240+
}
3241+
};

src/traces/bar/attributes.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplat
1313
var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs;
1414
var colorScaleAttrs = require('../../components/colorscale/attributes');
1515
var fontAttrs = require('../../plots/font_attributes');
16-
var constants = require('./constants.js');
16+
var constants = require('./constants');
1717

1818
var extendFlat = require('../../lib/extend').extendFlat;
1919

src/traces/bar/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
'use strict';
1111

1212
module.exports = {
13+
TEXTPAD: 3, // padding in pixels around text
1314
eventDataKeys: []
1415
};

src/traces/bar/plot.js

+4-34
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ var tickText = require('../../plots/cartesian/axes').tickText;
2121

2222
var style = require('./style');
2323
var helpers = require('./helpers');
24+
var constants = require('./constants');
2425
var attributes = require('./attributes');
2526

2627
var attributeText = attributes.text;
2728
var attributeTextPosition = attributes.textposition;
2829

2930
var appendArrayPointValue = require('../../components/fx/helpers').appendArrayPointValue;
3031

31-
// padding in pixels around text
32-
var TEXTPAD = 3;
32+
var TEXTPAD = constants.TEXTPAD;
3333

3434
function keyFunc(d) {return d.id;}
3535
function getKeyFunc(trace) {
@@ -381,7 +381,7 @@ function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, ma
381381
trace.constraintext === 'both' ||
382382
trace.constraintext === 'outside';
383383

384-
transform = getTransform(toMoveOutsideBar(x0, x1, y0, y1, textBB, {
384+
transform = Lib.getTextTransform(toMoveOutsideBar(x0, x1, y0, y1, textBB, {
385385
isHorizontal: isHorizontal,
386386
constrained: constrained,
387387
angle: trace.textangle
@@ -391,7 +391,7 @@ function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, ma
391391
trace.constraintext === 'both' ||
392392
trace.constraintext === 'inside';
393393

394-
transform = getTransform(toMoveInsideBar(x0, x1, y0, y1, textBB, {
394+
transform = Lib.getTextTransform(toMoveInsideBar(x0, x1, y0, y1, textBB, {
395395
isHorizontal: isHorizontal,
396396
constrained: constrained,
397397
angle: trace.textangle,
@@ -549,35 +549,6 @@ function toMoveOutsideBar(x0, x1, y0, y1, textBB, opts) {
549549
};
550550
}
551551

552-
function getTransform(opts) {
553-
var textX = opts.textX;
554-
var textY = opts.textY;
555-
var targetX = opts.targetX;
556-
var targetY = opts.targetY;
557-
var scale = opts.scale;
558-
var rotate = opts.rotate;
559-
560-
var transformScale;
561-
var transformRotate;
562-
var transformTranslate;
563-
564-
if(scale < 1) transformScale = 'scale(' + scale + ') ';
565-
else {
566-
scale = 1;
567-
transformScale = '';
568-
}
569-
570-
transformRotate = (rotate) ?
571-
'rotate(' + rotate + ' ' + textX + ' ' + textY + ') ' : '';
572-
573-
// Note that scaling also affects the center of the text box
574-
var translateX = (targetX - scale * textX);
575-
var translateY = (targetY - scale * textY);
576-
transformTranslate = 'translate(' + translateX + ' ' + translateY + ')';
577-
578-
return transformTranslate + transformScale + transformRotate;
579-
}
580-
581552
function getText(fullLayout, calcTrace, index, xa, ya) {
582553
var trace = calcTrace[0].trace;
583554
var texttemplate = trace.texttemplate;
@@ -734,7 +705,6 @@ function calcTextinfo(calcTrace, index, xa, ya) {
734705

735706
module.exports = {
736707
plot: plot,
737-
getTransform: getTransform,
738708
toMoveInsideBar: toMoveInsideBar,
739709
toMoveOutsideBar: toMoveOutsideBar
740710
};

src/traces/funnelarea/base_plot.js

+4-12
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,14 @@
88

99
'use strict';
1010

11-
var Registry = require('../../registry');
12-
var getModuleCalcData = require('../../plots/get_data').getModuleCalcData;
11+
var plots = require('../../plots/plots');
1312

1413
exports.name = 'funnelarea';
1514

16-
exports.plot = function(gd) {
17-
var Funnelarea = Registry.getModule('funnelarea');
18-
var cdFunnelarea = getModuleCalcData(gd.calcdata, Funnelarea)[0];
19-
Funnelarea.plot(gd, cdFunnelarea);
15+
exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
16+
plots.plotBasePlot(exports.name, gd, traces, transitionOpts, makeOnCompleteCallback);
2017
};
2118

2219
exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {
23-
var hadFunnelarea = (oldFullLayout._has && oldFullLayout._has('funnelarea'));
24-
var hasFunnelarea = (newFullLayout._has && newFullLayout._has('funnelarea'));
25-
26-
if(hadFunnelarea && !hasFunnelarea) {
27-
oldFullLayout._funnelarealayer.selectAll('g.trace').remove();
28-
}
20+
plots.cleanBasePlot(exports.name, newFullData, newFullLayout, oldFullData, oldFullLayout);
2921
};

src/traces/funnelarea/plot.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ var Lib = require('../../lib');
1515
var svgTextUtils = require('../../lib/svg_text_utils');
1616

1717
var barPlot = require('../bar/plot');
18-
var getTransform = barPlot.getTransform;
1918
var toMoveInsideBar = barPlot.toMoveInsideBar;
2019

2120
var pieHelpers = require('../pie/helpers');
@@ -115,7 +114,7 @@ module.exports = function plot(gd, cdModule) {
115114
x0 = Math.max(pt.TL[0], pt.BL[0]);
116115
x1 = Math.min(pt.TR[0], pt.BR[0]);
117116

118-
transform = getTransform(toMoveInsideBar(x0, x1, y0, y1, textBB, {
117+
transform = Lib.getTextTransform(toMoveInsideBar(x0, x1, y0, y1, textBB, {
119118
isHorizontal: true,
120119
constrained: true,
121120
angle: 0,

src/traces/indicator/base_plot.js

+4-12
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,14 @@
88

99
'use strict';
1010

11-
var Registry = require('../../registry');
12-
var getModuleCalcData = require('../../plots/get_data').getModuleCalcData;
11+
var plots = require('../../plots/plots');
1312

14-
var name = exports.name = 'indicator';
13+
exports.name = 'indicator';
1514

1615
exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
17-
var _module = Registry.getModule(name);
18-
var cdmodule = getModuleCalcData(gd.calcdata, _module)[0];
19-
_module.plot(gd, cdmodule, transitionOpts, makeOnCompleteCallback);
16+
plots.plotBasePlot(exports.name, gd, traces, transitionOpts, makeOnCompleteCallback);
2017
};
2118

2219
exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {
23-
var had = (oldFullLayout._has && oldFullLayout._has(name));
24-
var has = (newFullLayout._has && newFullLayout._has(name));
25-
26-
if(had && !has) {
27-
oldFullLayout._indicatorlayer.selectAll('g.trace').remove();
28-
}
20+
plots.cleanBasePlot(exports.name, newFullData, newFullLayout, oldFullData, oldFullLayout);
2921
};

src/traces/pie/base_plot.js

+4-12
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,14 @@
88

99
'use strict';
1010

11-
var Registry = require('../../registry');
12-
var getModuleCalcData = require('../../plots/get_data').getModuleCalcData;
11+
var plots = require('../../plots/plots');
1312

1413
exports.name = 'pie';
1514

16-
exports.plot = function(gd) {
17-
var Pie = Registry.getModule('pie');
18-
var cdPie = getModuleCalcData(gd.calcdata, Pie)[0];
19-
Pie.plot(gd, cdPie);
15+
exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
16+
plots.plotBasePlot(exports.name, gd, traces, transitionOpts, makeOnCompleteCallback);
2017
};
2118

2219
exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {
23-
var hadPie = (oldFullLayout._has && oldFullLayout._has('pie'));
24-
var hasPie = (newFullLayout._has && newFullLayout._has('pie'));
25-
26-
if(hadPie && !hasPie) {
27-
oldFullLayout._pielayer.selectAll('g.trace').remove();
28-
}
20+
plots.cleanBasePlot(exports.name, newFullData, newFullLayout, oldFullData, oldFullLayout);
2921
};

0 commit comments

Comments
 (0)