plotly.js 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +3 -3
- package/dist/README.md +26 -26
- package/dist/plot-schema.json +898 -407
- package/dist/plotly-basic.js +489 -185
- package/dist/plotly-basic.min.js +4 -4
- package/dist/plotly-cartesian.js +894 -326
- package/dist/plotly-cartesian.min.js +3 -3
- package/dist/plotly-finance.js +489 -185
- package/dist/plotly-finance.min.js +4 -4
- package/dist/plotly-geo-assets.js +2 -2
- package/dist/plotly-geo.js +486 -184
- package/dist/plotly-geo.min.js +4 -4
- package/dist/plotly-gl2d.js +502 -185
- package/dist/plotly-gl2d.min.js +2 -2
- package/dist/plotly-gl3d.js +486 -184
- package/dist/plotly-gl3d.min.js +2 -2
- package/dist/plotly-mapbox.js +486 -184
- package/dist/plotly-mapbox.min.js +2 -2
- package/dist/plotly-strict.js +1112 -544
- package/dist/plotly-strict.min.js +3 -3
- package/dist/plotly-with-meta.js +1201 -606
- package/dist/plotly.js +1166 -598
- package/dist/plotly.min.js +10 -10
- package/package.json +4 -4
- package/src/components/colorbar/attributes.js +29 -20
- package/src/components/colorbar/defaults.js +30 -8
- package/src/components/colorbar/draw.js +374 -128
- package/src/components/fx/hover.js +5 -2
- package/src/components/fx/hoverlabel_defaults.js +4 -2
- package/src/components/fx/layout_attributes.js +14 -4
- package/src/components/fx/layout_defaults.js +2 -0
- package/src/components/legend/attributes.js +7 -0
- package/src/components/legend/defaults.js +24 -7
- package/src/components/titles/index.js +8 -2
- package/src/plot_api/plot_api.js +1 -1
- package/src/plots/font_attributes.js +3 -0
- package/src/plots/layout_attributes.js +1 -0
- package/src/plots/plots.js +7 -15
- package/src/traces/contour/attributes.js +12 -0
- package/src/traces/contour/defaults.js +9 -1
- package/src/traces/heatmap/attributes.js +16 -0
- package/src/traces/heatmap/defaults.js +2 -0
- package/src/traces/heatmap/label_defaults.js +13 -0
- package/src/traces/heatmap/plot.js +203 -4
- package/src/traces/histogram2d/attributes.js +8 -0
- package/src/traces/histogram2d/defaults.js +4 -0
- package/src/traces/histogram2dcontour/attributes.js +3 -1
- package/src/traces/histogram2dcontour/defaults.js +8 -1
- package/src/traces/pie/calc.js +3 -1
- package/src/version.js +1 -1
- package/tasks/test_mock.js +1 -0
|
@@ -1103,7 +1103,9 @@ function createHoverText(hoverData, opts) {
|
|
|
1103
1103
|
orientation: 'v'
|
|
1104
1104
|
}
|
|
1105
1105
|
};
|
|
1106
|
-
var mockLayoutOut = {
|
|
1106
|
+
var mockLayoutOut = {
|
|
1107
|
+
font: font
|
|
1108
|
+
};
|
|
1107
1109
|
legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
|
|
1108
1110
|
var mockLegend = mockLayoutOut.legend;
|
|
1109
1111
|
|
|
@@ -1144,7 +1146,8 @@ function createHoverText(hoverData, opts) {
|
|
|
1144
1146
|
|
|
1145
1147
|
// Draw unified hover label
|
|
1146
1148
|
mockLegend._inHover = true;
|
|
1147
|
-
mockLegend._groupTitleFont =
|
|
1149
|
+
mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
|
|
1150
|
+
|
|
1148
1151
|
legendDraw(gd, mockLegend);
|
|
1149
1152
|
|
|
1150
1153
|
// Position the hover
|
|
@@ -7,9 +7,11 @@ var isUnifiedHover = require('./helpers').isUnifiedHover;
|
|
|
7
7
|
module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
|
|
8
8
|
opts = opts || {};
|
|
9
9
|
|
|
10
|
+
var hasLegend = contOut.legend;
|
|
11
|
+
|
|
10
12
|
function inheritFontAttr(attr) {
|
|
11
13
|
if(!opts.font[attr]) {
|
|
12
|
-
opts.font[attr] =
|
|
14
|
+
opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
|
|
@@ -20,7 +22,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
|
|
|
20
22
|
inheritFontAttr('family');
|
|
21
23
|
inheritFontAttr('color');
|
|
22
24
|
|
|
23
|
-
if(
|
|
25
|
+
if(hasLegend) {
|
|
24
26
|
if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
|
|
25
27
|
if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
|
|
26
28
|
} else {
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
var constants = require('./constants');
|
|
4
4
|
|
|
5
|
-
var fontAttrs = require('../../plots/font_attributes')
|
|
5
|
+
var fontAttrs = require('../../plots/font_attributes');
|
|
6
|
+
|
|
7
|
+
var font = fontAttrs({
|
|
6
8
|
editType: 'none',
|
|
7
9
|
description: 'Sets the default hover label font used by all traces on the graph.'
|
|
8
10
|
});
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
font.family.dflt = constants.HOVERFONT;
|
|
12
|
+
font.size.dflt = constants.HOVERFONTSIZE;
|
|
11
13
|
|
|
12
14
|
module.exports = {
|
|
13
15
|
clickmode: {
|
|
@@ -118,7 +120,14 @@ module.exports = {
|
|
|
118
120
|
'Sets the border color of all hover labels on graph.'
|
|
119
121
|
].join(' ')
|
|
120
122
|
},
|
|
121
|
-
font:
|
|
123
|
+
font: font,
|
|
124
|
+
grouptitlefont: fontAttrs({
|
|
125
|
+
editType: 'none',
|
|
126
|
+
description: [
|
|
127
|
+
'Sets the font for group titles in hover (unified modes).',
|
|
128
|
+
'Defaults to `hoverlabel.font`.'
|
|
129
|
+
].join(' ')
|
|
130
|
+
}),
|
|
122
131
|
align: {
|
|
123
132
|
valType: 'enumerated',
|
|
124
133
|
values: ['left', 'right', 'auto'],
|
|
@@ -143,6 +152,7 @@ module.exports = {
|
|
|
143
152
|
'`namelength - 3` characters and add an ellipsis.'
|
|
144
153
|
].join(' ')
|
|
145
154
|
},
|
|
155
|
+
|
|
146
156
|
editType: 'none'
|
|
147
157
|
},
|
|
148
158
|
selectdirection: {
|
|
@@ -30,6 +30,13 @@ module.exports = {
|
|
|
30
30
|
editType: 'legend',
|
|
31
31
|
description: 'Sets the font used to text the legend items.'
|
|
32
32
|
}),
|
|
33
|
+
grouptitlefont: fontAttrs({
|
|
34
|
+
editType: 'legend',
|
|
35
|
+
description: [
|
|
36
|
+
'Sets the font for group titles in legend.',
|
|
37
|
+
'Defaults to `legend.font` with its size increased about 10%.'
|
|
38
|
+
].join(' ')
|
|
39
|
+
}),
|
|
33
40
|
orientation: {
|
|
34
41
|
valType: 'enumerated',
|
|
35
42
|
values: ['v', 'h'],
|
|
@@ -4,6 +4,7 @@ var Registry = require('../../registry');
|
|
|
4
4
|
var Lib = require('../../lib');
|
|
5
5
|
var Template = require('../../plot_api/plot_template');
|
|
6
6
|
|
|
7
|
+
var plotsAttrs = require('../../plots/attributes');
|
|
7
8
|
var attributes = require('./attributes');
|
|
8
9
|
var basePlotLayoutAttributes = require('../../plots/layout_attributes');
|
|
9
10
|
var helpers = require('./helpers');
|
|
@@ -11,13 +12,30 @@ var helpers = require('./helpers');
|
|
|
11
12
|
|
|
12
13
|
module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
|
|
13
14
|
var containerIn = layoutIn.legend || {};
|
|
15
|
+
var containerOut = Template.newContainer(layoutOut, 'legend');
|
|
16
|
+
|
|
17
|
+
function coerce(attr, dflt) {
|
|
18
|
+
return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var trace;
|
|
22
|
+
var traceCoerce = function(attr, dflt) {
|
|
23
|
+
var traceIn = trace._input;
|
|
24
|
+
var traceOut = trace;
|
|
25
|
+
return Lib.coerce(traceIn, traceOut, plotsAttrs, attr, dflt);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
var globalFont = layoutOut.font || {};
|
|
29
|
+
var grouptitlefont = Lib.coerceFont(coerce, 'grouptitlefont', Lib.extendFlat({}, globalFont, {
|
|
30
|
+
size: Math.round(globalFont.size * 1.1)
|
|
31
|
+
}));
|
|
14
32
|
|
|
15
33
|
var legendTraceCount = 0;
|
|
16
34
|
var legendReallyHasATrace = false;
|
|
17
35
|
var defaultOrder = 'normal';
|
|
18
36
|
|
|
19
37
|
for(var i = 0; i < fullData.length; i++) {
|
|
20
|
-
|
|
38
|
+
trace = fullData[i];
|
|
21
39
|
|
|
22
40
|
if(!trace.visible) continue;
|
|
23
41
|
|
|
@@ -44,6 +62,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
|
|
|
44
62
|
legendTraceCount++;
|
|
45
63
|
}
|
|
46
64
|
}
|
|
65
|
+
|
|
66
|
+
Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
|
|
47
67
|
}
|
|
48
68
|
|
|
49
69
|
if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
|
|
@@ -62,13 +82,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
|
|
|
62
82
|
basePlotLayoutAttributes, 'showlegend',
|
|
63
83
|
legendReallyHasATrace && legendTraceCount > 1);
|
|
64
84
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
var containerOut = Template.newContainer(layoutOut, 'legend');
|
|
85
|
+
// delete legend
|
|
86
|
+
if(showLegend === false) layoutOut.legend = undefined;
|
|
68
87
|
|
|
69
|
-
|
|
70
|
-
return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
|
|
71
|
-
}
|
|
88
|
+
if(showLegend === false && !containerIn.uirevision) return;
|
|
72
89
|
|
|
73
90
|
coerce('uirevision', layoutOut.uirevision);
|
|
74
91
|
|
|
@@ -96,8 +96,10 @@ function draw(gd, titleClass, options) {
|
|
|
96
96
|
|
|
97
97
|
var elShouldExist = txt || editable;
|
|
98
98
|
|
|
99
|
+
var hColorbarMoveTitle;
|
|
99
100
|
if(!group) {
|
|
100
101
|
group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
|
|
102
|
+
hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
var el = group.selectAll('text')
|
|
@@ -121,13 +123,17 @@ function draw(gd, titleClass, options) {
|
|
|
121
123
|
function drawTitle(titleEl) {
|
|
122
124
|
var transformVal;
|
|
123
125
|
|
|
126
|
+
if(!transform && hColorbarMoveTitle) {
|
|
127
|
+
transform = {};
|
|
128
|
+
}
|
|
129
|
+
|
|
124
130
|
if(transform) {
|
|
125
131
|
transformVal = '';
|
|
126
132
|
if(transform.rotate) {
|
|
127
133
|
transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
|
|
128
134
|
}
|
|
129
|
-
if(transform.offset) {
|
|
130
|
-
transformVal += strTranslate(0, transform.offset);
|
|
135
|
+
if(transform.offset || hColorbarMoveTitle) {
|
|
136
|
+
transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
|
|
131
137
|
}
|
|
132
138
|
} else {
|
|
133
139
|
transformVal = null;
|
package/src/plot_api/plot_api.js
CHANGED
|
@@ -1719,7 +1719,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
|
|
|
1719
1719
|
if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
|
|
1720
1720
|
(typeof value === 'string' || typeof value === 'number')) {
|
|
1721
1721
|
replace(key, key.replace('title', 'title.text'));
|
|
1722
|
-
} else if(key.indexOf('titlefont') > -1) {
|
|
1722
|
+
} else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
|
|
1723
1723
|
replace(key, key.replace('titlefont', 'title.font'));
|
|
1724
1724
|
} else if(key.indexOf('titleposition') > -1) {
|
|
1725
1725
|
replace(key, key.replace('titleposition', 'title.position'));
|
|
@@ -53,6 +53,9 @@ module.exports = function(opts) {
|
|
|
53
53
|
description: '' + (opts.description || '') + ''
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
if(opts.autoSize) attrs.size.dflt = 'auto';
|
|
57
|
+
if(opts.autoColor) attrs.color.dflt = 'auto';
|
|
58
|
+
|
|
56
59
|
if(opts.arrayOk) {
|
|
57
60
|
attrs.family.arrayOk = true;
|
|
58
61
|
attrs.size.arrayOk = true;
|
package/src/plots/plots.js
CHANGED
|
@@ -1321,13 +1321,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
|
|
|
1321
1321
|
);
|
|
1322
1322
|
|
|
1323
1323
|
coerce('legendgroup');
|
|
1324
|
-
|
|
1325
|
-
if(titleText) {
|
|
1326
|
-
Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
|
|
1327
|
-
size: Math.round(layout.font.size * 1.1) // default to larger font size
|
|
1328
|
-
}));
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1324
|
+
coerce('legendgrouptitle.text');
|
|
1331
1325
|
coerce('legendrank');
|
|
1332
1326
|
|
|
1333
1327
|
traceOut._dfltShowLegend = true;
|
|
@@ -1475,16 +1469,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
|
|
|
1475
1469
|
|
|
1476
1470
|
coerce('autotypenumbers');
|
|
1477
1471
|
|
|
1478
|
-
var
|
|
1479
|
-
|
|
1480
|
-
coerce('title.text', layoutOut._dfltTitle.plot);
|
|
1472
|
+
var font = Lib.coerceFont(coerce, 'font');
|
|
1473
|
+
var fontSize = font.size;
|
|
1481
1474
|
|
|
1482
|
-
Lib.coerceFont(coerce, 'title.font', {
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
color: globalFont.color
|
|
1486
|
-
});
|
|
1475
|
+
Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
|
|
1476
|
+
size: Math.round(fontSize * 1.4)
|
|
1477
|
+
}));
|
|
1487
1478
|
|
|
1479
|
+
coerce('title.text', layoutOut._dfltTitle.plot);
|
|
1488
1480
|
coerce('title.xref');
|
|
1489
1481
|
coerce('title.yref');
|
|
1490
1482
|
coerce('title.x');
|
|
@@ -42,6 +42,18 @@ module.exports = extendFlat({
|
|
|
42
42
|
yhoverformat: axisHoverFormat('y'),
|
|
43
43
|
zhoverformat: axisHoverFormat('z', 1),
|
|
44
44
|
hovertemplate: heatmapAttrs.hovertemplate,
|
|
45
|
+
texttemplate: extendFlat({}, heatmapAttrs.texttemplate, {
|
|
46
|
+
description: [
|
|
47
|
+
'For this trace it only has an effect if `coloring` is set to *heatmap*.',
|
|
48
|
+
heatmapAttrs.texttemplate.description
|
|
49
|
+
].join(' ')
|
|
50
|
+
}),
|
|
51
|
+
textfont: extendFlat({}, heatmapAttrs.textfont, {
|
|
52
|
+
description: [
|
|
53
|
+
'For this trace it only has an effect if `coloring` is set to *heatmap*.',
|
|
54
|
+
heatmapAttrs.textfont.description
|
|
55
|
+
].join(' ')
|
|
56
|
+
}),
|
|
45
57
|
hoverongaps: heatmapAttrs.hoverongaps,
|
|
46
58
|
connectgaps: extendFlat({}, heatmapAttrs.connectgaps, {
|
|
47
59
|
description: [
|
|
@@ -7,6 +7,7 @@ var handlePeriodDefaults = require('../scatter/period_defaults');
|
|
|
7
7
|
var handleConstraintDefaults = require('./constraint_defaults');
|
|
8
8
|
var handleContoursDefaults = require('./contours_defaults');
|
|
9
9
|
var handleStyleDefaults = require('./style_defaults');
|
|
10
|
+
var handleHeatmapLabelDefaults = require('../heatmap/label_defaults');
|
|
10
11
|
var attributes = require('./attributes');
|
|
11
12
|
|
|
12
13
|
|
|
@@ -31,8 +32,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
|
|
|
31
32
|
|
|
32
33
|
coerce('text');
|
|
33
34
|
coerce('hovertext');
|
|
34
|
-
coerce('hovertemplate');
|
|
35
35
|
coerce('hoverongaps');
|
|
36
|
+
coerce('hovertemplate');
|
|
36
37
|
|
|
37
38
|
var isConstraint = (coerce('contours.type') === 'constraint');
|
|
38
39
|
coerce('connectgaps', Lib.isArray1D(traceOut.z));
|
|
@@ -43,4 +44,11 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
|
|
|
43
44
|
handleContoursDefaults(traceIn, traceOut, coerce, coerce2);
|
|
44
45
|
handleStyleDefaults(traceIn, traceOut, coerce, layout);
|
|
45
46
|
}
|
|
47
|
+
|
|
48
|
+
if(
|
|
49
|
+
traceOut.contours &&
|
|
50
|
+
traceOut.contours.coloring === 'heatmap'
|
|
51
|
+
) {
|
|
52
|
+
handleHeatmapLabelDefaults(coerce, layout);
|
|
53
|
+
}
|
|
46
54
|
};
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
var scatterAttrs = require('../scatter/attributes');
|
|
4
4
|
var baseAttrs = require('../../plots/attributes');
|
|
5
|
+
var fontAttrs = require('../../plots/font_attributes');
|
|
5
6
|
var axisHoverFormat = require('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
|
|
6
7
|
var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs;
|
|
8
|
+
var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs;
|
|
7
9
|
var colorScaleAttrs = require('../../components/colorscale/attributes');
|
|
8
10
|
|
|
9
11
|
var extendFlat = require('../../lib/extend').extendFlat;
|
|
@@ -116,6 +118,20 @@ module.exports = extendFlat({
|
|
|
116
118
|
zhoverformat: axisHoverFormat('z', 1),
|
|
117
119
|
|
|
118
120
|
hovertemplate: hovertemplateAttrs(),
|
|
121
|
+
texttemplate: texttemplateAttrs({
|
|
122
|
+
arrayOk: false,
|
|
123
|
+
editType: 'plot'
|
|
124
|
+
}, {
|
|
125
|
+
keys: ['x', 'y', 'z', 'text']
|
|
126
|
+
}),
|
|
127
|
+
textfont: fontAttrs({
|
|
128
|
+
editType: 'plot',
|
|
129
|
+
autoSize: true,
|
|
130
|
+
autoColor: true,
|
|
131
|
+
colorEditType: 'style',
|
|
132
|
+
description: 'Sets the text font.'
|
|
133
|
+
}),
|
|
134
|
+
|
|
119
135
|
showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})
|
|
120
136
|
}, {
|
|
121
137
|
transforms: undefined
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var Lib = require('../../lib');
|
|
4
4
|
|
|
5
5
|
var handleXYZDefaults = require('./xyz_defaults');
|
|
6
|
+
var handleHeatmapLabelDefaults = require('./label_defaults');
|
|
6
7
|
var handlePeriodDefaults = require('../scatter/period_defaults');
|
|
7
8
|
var handleStyleDefaults = require('./style_defaults');
|
|
8
9
|
var colorscaleDefaults = require('../../components/colorscale/defaults');
|
|
@@ -28,6 +29,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
|
|
|
28
29
|
coerce('hovertext');
|
|
29
30
|
coerce('hovertemplate');
|
|
30
31
|
|
|
32
|
+
handleHeatmapLabelDefaults(coerce, layout);
|
|
31
33
|
handleStyleDefaults(traceIn, traceOut, coerce, layout);
|
|
32
34
|
|
|
33
35
|
coerce('hoverongaps');
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Lib = require('../../lib');
|
|
4
|
+
|
|
5
|
+
module.exports = function handleHeatmapLabelDefaults(coerce, layout) {
|
|
6
|
+
coerce('texttemplate');
|
|
7
|
+
|
|
8
|
+
var fontDflt = Lib.extendFlat({}, layout.font, {
|
|
9
|
+
color: 'auto',
|
|
10
|
+
size: 'auto'
|
|
11
|
+
});
|
|
12
|
+
Lib.coerceFont(coerce, 'textfont', fontDflt);
|
|
13
|
+
};
|
|
@@ -4,9 +4,27 @@ var d3 = require('@plotly/d3');
|
|
|
4
4
|
var tinycolor = require('tinycolor2');
|
|
5
5
|
|
|
6
6
|
var Registry = require('../../registry');
|
|
7
|
+
var Drawing = require('../../components/drawing');
|
|
8
|
+
var Axes = require('../../plots/cartesian/axes');
|
|
7
9
|
var Lib = require('../../lib');
|
|
10
|
+
var svgTextUtils = require('../../lib/svg_text_utils');
|
|
11
|
+
var formatLabels = require('../scatter/format_labels');
|
|
12
|
+
var Color = require('../../components/color');
|
|
13
|
+
var extractOpts = require('../../components/colorscale').extractOpts;
|
|
8
14
|
var makeColorScaleFuncFromTrace = require('../../components/colorscale').makeColorScaleFuncFromTrace;
|
|
9
15
|
var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
|
|
16
|
+
var alignmentConstants = require('../../constants/alignment');
|
|
17
|
+
var LINE_SPACING = alignmentConstants.LINE_SPACING;
|
|
18
|
+
|
|
19
|
+
var labelClass = 'heatmap-label';
|
|
20
|
+
|
|
21
|
+
function selectLabels(plotGroup) {
|
|
22
|
+
return plotGroup.selectAll('g.' + labelClass);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function removeLabels(plotGroup) {
|
|
26
|
+
selectLabels(plotGroup).remove();
|
|
27
|
+
}
|
|
10
28
|
|
|
11
29
|
module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
|
|
12
30
|
var xa = plotinfo.xaxis;
|
|
@@ -16,6 +34,8 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
|
|
|
16
34
|
var plotGroup = d3.select(this);
|
|
17
35
|
var cd0 = cd[0];
|
|
18
36
|
var trace = cd0.trace;
|
|
37
|
+
var xGap = trace.xgap || 0;
|
|
38
|
+
var yGap = trace.ygap || 0;
|
|
19
39
|
|
|
20
40
|
var z = cd0.z;
|
|
21
41
|
var x = cd0.x;
|
|
@@ -31,7 +51,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
|
|
|
31
51
|
var xrev = false;
|
|
32
52
|
var yrev = false;
|
|
33
53
|
|
|
34
|
-
var left, right, temp, top, bottom, i;
|
|
54
|
+
var left, right, temp, top, bottom, i, j, k;
|
|
35
55
|
|
|
36
56
|
// TODO: if there are multiple overlapping categorical heatmaps,
|
|
37
57
|
// or if we allow category sorting, then the categories may not be
|
|
@@ -112,6 +132,8 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
|
|
|
112
132
|
if(isOffScreen) {
|
|
113
133
|
var noImage = plotGroup.selectAll('image').data([]);
|
|
114
134
|
noImage.exit().remove();
|
|
135
|
+
|
|
136
|
+
removeLabels(plotGroup);
|
|
115
137
|
return;
|
|
116
138
|
}
|
|
117
139
|
|
|
@@ -167,7 +189,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
|
|
|
167
189
|
var gcount = 0;
|
|
168
190
|
var bcount = 0;
|
|
169
191
|
|
|
170
|
-
var xb,
|
|
192
|
+
var xb, xi, v, row, c;
|
|
171
193
|
|
|
172
194
|
function setColor(v, pixsize) {
|
|
173
195
|
if(v !== undefined) {
|
|
@@ -278,8 +300,6 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
|
|
|
278
300
|
} else { // zsmooth = false -> filling potentially large bricks works fastest with fillRect
|
|
279
301
|
// gaps do not need to be exact integers, but if they *are* we will get
|
|
280
302
|
// cleaner edges by rounding at least one edge
|
|
281
|
-
var xGap = trace.xgap;
|
|
282
|
-
var yGap = trace.ygap;
|
|
283
303
|
var xGapLeft = Math.floor(xGap / 2);
|
|
284
304
|
var yGapTop = Math.floor(yGap / 2);
|
|
285
305
|
|
|
@@ -332,6 +352,185 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
|
|
|
332
352
|
y: top,
|
|
333
353
|
'xlink:href': canvas.toDataURL('image/png')
|
|
334
354
|
});
|
|
355
|
+
|
|
356
|
+
removeLabels(plotGroup);
|
|
357
|
+
|
|
358
|
+
var texttemplate = trace.texttemplate;
|
|
359
|
+
if(texttemplate) {
|
|
360
|
+
// dummy axis for formatting the z value
|
|
361
|
+
var cOpts = extractOpts(trace);
|
|
362
|
+
var dummyAx = {
|
|
363
|
+
type: 'linear',
|
|
364
|
+
range: [cOpts.min, cOpts.max],
|
|
365
|
+
_separators: xa._separators,
|
|
366
|
+
_numFormat: xa._numFormat
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
var aHistogram2dContour = trace.type === 'histogram2dcontour';
|
|
370
|
+
var aContour = trace.type === 'contour';
|
|
371
|
+
var iStart = aContour ? 1 : 0;
|
|
372
|
+
var iStop = aContour ? m - 1 : m;
|
|
373
|
+
var jStart = aContour ? 1 : 0;
|
|
374
|
+
var jStop = aContour ? n - 1 : n;
|
|
375
|
+
|
|
376
|
+
var textData = [];
|
|
377
|
+
for(i = iStart; i < iStop; i++) {
|
|
378
|
+
var yVal;
|
|
379
|
+
if(aContour) {
|
|
380
|
+
yVal = cd0.y[i];
|
|
381
|
+
} else if(aHistogram2dContour) {
|
|
382
|
+
if(i === 0 || i === m - 1) continue;
|
|
383
|
+
yVal = cd0.y[i];
|
|
384
|
+
} else if(cd0.yCenter) {
|
|
385
|
+
yVal = cd0.yCenter[i];
|
|
386
|
+
} else {
|
|
387
|
+
if(i + 1 === m && cd0.y[i + 1] === undefined) continue;
|
|
388
|
+
yVal = (cd0.y[i] + cd0.y[i + 1]) / 2;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
var _y = Math.round(ya.c2p(yVal));
|
|
392
|
+
if(0 > _y || _y > ya._length) continue;
|
|
393
|
+
|
|
394
|
+
for(j = jStart; j < jStop; j++) {
|
|
395
|
+
var xVal;
|
|
396
|
+
if(aContour) {
|
|
397
|
+
xVal = cd0.x[j];
|
|
398
|
+
} else if(aHistogram2dContour) {
|
|
399
|
+
if(j === 0 || j === n - 1) continue;
|
|
400
|
+
xVal = cd0.x[j];
|
|
401
|
+
} else if(cd0.xCenter) {
|
|
402
|
+
xVal = cd0.xCenter[j];
|
|
403
|
+
} else {
|
|
404
|
+
if(j + 1 === n && cd0.x[j + 1] === undefined) continue;
|
|
405
|
+
xVal = (cd0.x[j] + cd0.x[j + 1]) / 2;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
var _x = Math.round(xa.c2p(xVal));
|
|
409
|
+
if(0 > _x || _x > xa._length) continue;
|
|
410
|
+
|
|
411
|
+
var obj = formatLabels({
|
|
412
|
+
x: xVal,
|
|
413
|
+
y: yVal
|
|
414
|
+
}, trace, gd._fullLayout);
|
|
415
|
+
|
|
416
|
+
obj.x = xVal;
|
|
417
|
+
obj.y = yVal;
|
|
418
|
+
|
|
419
|
+
var zVal = cd0.z[i][j];
|
|
420
|
+
if(zVal === undefined) {
|
|
421
|
+
obj.z = '';
|
|
422
|
+
obj.zLabel = '';
|
|
423
|
+
} else {
|
|
424
|
+
obj.z = zVal;
|
|
425
|
+
obj.zLabel = Axes.tickText(dummyAx, zVal, 'hover').text;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
var theText = cd0.text && cd0.text[i] && cd0.text[i][j];
|
|
429
|
+
if(theText === undefined || theText === false) theText = '';
|
|
430
|
+
obj.text = theText;
|
|
431
|
+
|
|
432
|
+
var _t = Lib.texttemplateString(texttemplate, obj, gd._fullLayout._d3locale, obj, trace._meta || {});
|
|
433
|
+
if(!_t) continue;
|
|
434
|
+
|
|
435
|
+
var lines = _t.split('<br>');
|
|
436
|
+
var nL = lines.length;
|
|
437
|
+
var nC = 0;
|
|
438
|
+
for(k = 0; k < nL; k++) {
|
|
439
|
+
nC = Math.max(nC, lines[k].length);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
textData.push({
|
|
443
|
+
l: nL, // number of lines
|
|
444
|
+
c: nC, // maximum number of chars in a line
|
|
445
|
+
t: _t, // text
|
|
446
|
+
x: _x,
|
|
447
|
+
y: _y,
|
|
448
|
+
z: zVal
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
var font = trace.textfont;
|
|
454
|
+
var fontFamily = font.family;
|
|
455
|
+
var fontSize = font.size;
|
|
456
|
+
|
|
457
|
+
if(!fontSize || fontSize === 'auto') {
|
|
458
|
+
var minW = Infinity;
|
|
459
|
+
var minH = Infinity;
|
|
460
|
+
var maxL = 0;
|
|
461
|
+
var maxC = 0;
|
|
462
|
+
|
|
463
|
+
for(k = 0; k < textData.length; k++) {
|
|
464
|
+
var d = textData[k];
|
|
465
|
+
maxL = Math.max(maxL, d.l);
|
|
466
|
+
maxC = Math.max(maxC, d.c);
|
|
467
|
+
|
|
468
|
+
if(k < textData.length - 1) {
|
|
469
|
+
var nextD = textData[k + 1];
|
|
470
|
+
var dx = Math.abs(nextD.x - d.x);
|
|
471
|
+
var dy = Math.abs(nextD.y - d.y);
|
|
472
|
+
|
|
473
|
+
if(dx) minW = Math.min(minW, dx);
|
|
474
|
+
if(dy) minH = Math.min(minH, dy);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if(
|
|
479
|
+
!isFinite(minW) ||
|
|
480
|
+
!isFinite(minH)
|
|
481
|
+
) {
|
|
482
|
+
fontSize = 12;
|
|
483
|
+
} else {
|
|
484
|
+
minW -= xGap;
|
|
485
|
+
minH -= yGap;
|
|
486
|
+
|
|
487
|
+
minW /= maxC;
|
|
488
|
+
minH /= maxL;
|
|
489
|
+
|
|
490
|
+
minW /= LINE_SPACING / 2;
|
|
491
|
+
minH /= LINE_SPACING;
|
|
492
|
+
|
|
493
|
+
fontSize = Math.min(
|
|
494
|
+
Math.floor(minW),
|
|
495
|
+
Math.floor(minH)
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
if(fontSize <= 0 || !isFinite(fontSize)) return;
|
|
500
|
+
|
|
501
|
+
var xFn = function(d) { return d.x; };
|
|
502
|
+
var yFn = function(d) {
|
|
503
|
+
return d.y - fontSize * ((d.l * LINE_SPACING) / 2 - 1);
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
var labels = selectLabels(plotGroup).data(textData);
|
|
507
|
+
|
|
508
|
+
labels
|
|
509
|
+
.enter()
|
|
510
|
+
.append('g')
|
|
511
|
+
.classed(labelClass, 1)
|
|
512
|
+
.append('text')
|
|
513
|
+
.attr('text-anchor', 'middle')
|
|
514
|
+
.each(function(d) {
|
|
515
|
+
var thisLabel = d3.select(this);
|
|
516
|
+
|
|
517
|
+
var fontColor = font.color;
|
|
518
|
+
if(!fontColor || fontColor === 'auto') {
|
|
519
|
+
fontColor = Color.contrast(
|
|
520
|
+
'rgba(' +
|
|
521
|
+
sclFunc(d.z).join() +
|
|
522
|
+
')'
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
thisLabel
|
|
527
|
+
.attr('data-notex', 1)
|
|
528
|
+
.call(svgTextUtils.positionText, xFn(d), yFn(d))
|
|
529
|
+
.call(Drawing.font, fontFamily, fontSize, fontColor)
|
|
530
|
+
.text(d.t)
|
|
531
|
+
.call(svgTextUtils.convertToTspans, gd);
|
|
532
|
+
});
|
|
533
|
+
}
|
|
335
534
|
});
|
|
336
535
|
};
|
|
337
536
|
|
|
@@ -6,6 +6,7 @@ var heatmapAttrs = require('../heatmap/attributes');
|
|
|
6
6
|
var baseAttrs = require('../../plots/attributes');
|
|
7
7
|
var axisHoverFormat = require('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
|
|
8
8
|
var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs;
|
|
9
|
+
var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs;
|
|
9
10
|
var colorScaleAttrs = require('../../components/colorscale/attributes');
|
|
10
11
|
|
|
11
12
|
var extendFlat = require('../../lib/extend').extendFlat;
|
|
@@ -69,6 +70,13 @@ module.exports = extendFlat(
|
|
|
69
70
|
yhoverformat: axisHoverFormat('y'),
|
|
70
71
|
zhoverformat: axisHoverFormat('z', 1),
|
|
71
72
|
hovertemplate: hovertemplateAttrs({}, {keys: 'z'}),
|
|
73
|
+
texttemplate: texttemplateAttrs({
|
|
74
|
+
arrayOk: false,
|
|
75
|
+
editType: 'plot'
|
|
76
|
+
}, {
|
|
77
|
+
keys: 'z'
|
|
78
|
+
}),
|
|
79
|
+
textfont: heatmapAttrs.textfont,
|
|
72
80
|
showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})
|
|
73
81
|
},
|
|
74
82
|
colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false})
|