Skip to content

Commit 20553d5

Browse files
authored
Merge pull request #3594 from plotly/sunburst
Sunburst traces
2 parents e0e7a1a + 4a2f7a5 commit 20553d5

37 files changed

+4282
-223
lines changed

lib/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ Plotly.register([
1818
require('./histogram'),
1919
require('./histogram2d'),
2020
require('./histogram2dcontour'),
21-
require('./pie'),
2221
require('./contour'),
2322
require('./scatterternary'),
2423
require('./violin'),
2524

25+
require('./pie'),
26+
require('./sunburst'),
27+
2628
require('./scatter3d'),
2729
require('./surface'),
2830
require('./isosurface'),

lib/sunburst.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/sunburst');

package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"country-regex": "^1.1.0",
6666
"d3": "^3.5.12",
6767
"d3-force": "^1.0.6",
68+
"d3-hierarchy": "^1.1.8",
6869
"d3-interpolate": "1",
6970
"d3-sankey-circular": "0.33.0",
7071
"delaunay-triangulate": "^1.1.6",

src/components/fx/helpers.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ var pointKeyMap = {
223223
locations: 'location',
224224
labels: 'label',
225225
values: 'value',
226-
'marker.colors': 'color'
226+
'marker.colors': 'color',
227+
parents: 'parent'
227228
};
228229

229230
function getPointKey(astr) {

src/lib/angles.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function rad2deg(rad) { return rad / PI * 180; }
2929
* @return {boolean}
3030
*/
3131
function isFullCircle(aBnds) {
32-
return Math.abs(aBnds[1] - aBnds[0]) > twoPI - 1e-15;
32+
return Math.abs(aBnds[1] - aBnds[0]) > twoPI - 1e-14;
3333
}
3434

3535
/**

src/plot_api/plot_api.js

+4
Original file line numberDiff line numberDiff line change
@@ -2528,6 +2528,7 @@ var traceUIControlPatterns = [
25282528
{pattern: /(^|value\.)visible$/, attr: 'legend.uirevision'},
25292529
{pattern: /^dimensions\[\d+\]\.constraintrange/},
25302530
{pattern: /^node\.(x|y)/}, // for Sankey nodes
2531+
{pattern: /^level$/}, // for Sunburst traces
25312532

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

3878+
// single sunbursrt layer for the whole plot
3879+
fullLayout._sunburstlayer = fullLayout._paper.append('g').classed('sunburstlayer', true);
3880+
38773881
// fill in image server scrape-svg
38783882
fullLayout._glimages = fullLayout._paper.append('g').classed('glimages', true);
38793883

src/plots/plots.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -2723,8 +2723,9 @@ plots.doCalcdata = function(gd, traces) {
27232723
gd._hmpixcount = 0;
27242724
gd._hmlumcount = 0;
27252725

2726-
// for sharing colors across pies (and for legend)
2726+
// for sharing colors across pies / sunbursts (and for legend)
27272727
fullLayout._piecolormap = {};
2728+
fullLayout._sunburstcolormap = {};
27282729

27292730
// If traces were specified and this trace was not included,
27302731
// then transfer it over from the old calcdata:

src/traces/pie/calc.js

+36-28
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ var tinycolor = require('tinycolor2');
1515
var Color = require('../../components/color');
1616
var helpers = require('./helpers');
1717

18-
exports.calc = function calc(gd, trace) {
18+
var pieExtendedColorWays = {};
19+
20+
function calc(gd, trace) {
1921
var vals = trace.values;
2022
var hasVals = isArrayOrTypedArray(vals) && vals.length;
2123
var labels = trace.labels;
2224
var colors = trace.marker.colors || [];
2325
var cd = [];
2426
var fullLayout = gd._fullLayout;
25-
var colorMap = fullLayout._piecolormap;
2627
var allThisTraceLabels = {};
2728
var vTotal = 0;
2829
var hiddenLabels = fullLayout.hiddenlabels || [];
@@ -36,18 +37,7 @@ exports.calc = function calc(gd, trace) {
3637
}
3738
}
3839

39-
function pullColor(color, label) {
40-
if(!color) return false;
41-
42-
color = tinycolor(color);
43-
if(!color.isValid()) return false;
44-
45-
color = Color.addOpacity(color, color.getAlpha());
46-
if(!colorMap[label]) colorMap[label] = color;
47-
48-
return color;
49-
}
50-
40+
var pullColor = makePullColorFn(fullLayout._piecolormap);
5141
var seriesLen = (hasVals ? vals : labels).length;
5242

5343
for(i = 0; i < seriesLen; i++) {
@@ -121,7 +111,21 @@ exports.calc = function calc(gd, trace) {
121111
}
122112

123113
return cd;
124-
};
114+
}
115+
116+
function makePullColorFn(colorMap) {
117+
return function pullColor(color, id) {
118+
if(!color) return false;
119+
120+
color = tinycolor(color);
121+
if(!color.isValid()) return false;
122+
123+
color = Color.addOpacity(color, color.getAlpha());
124+
if(!colorMap[id]) colorMap[id] = color;
125+
126+
return color;
127+
};
128+
}
125129

126130
/*
127131
* `calc` filled in (and collated) explicit colors.
@@ -130,45 +134,41 @@ exports.calc = function calc(gd, trace) {
130134
* This is done after sorting, so we pick defaults
131135
* in the order slices will be displayed
132136
*/
133-
exports.crossTraceCalc = function(gd) {
137+
function crossTraceCalc(gd) {
134138
var fullLayout = gd._fullLayout;
135139
var calcdata = gd.calcdata;
136140
var pieColorWay = fullLayout.piecolorway;
137141
var colorMap = fullLayout._piecolormap;
138142

139143
if(fullLayout.extendpiecolors) {
140-
pieColorWay = generateExtendedColors(pieColorWay);
144+
pieColorWay = generateExtendedColors(pieColorWay, pieExtendedColorWays);
141145
}
142146
var dfltColorCount = 0;
143147

144-
var i, j, cd, pt;
145-
for(i = 0; i < calcdata.length; i++) {
146-
cd = calcdata[i];
148+
for(var i = 0; i < calcdata.length; i++) {
149+
var cd = calcdata[i];
147150
if(cd[0].trace.type !== 'pie') continue;
148151

149-
for(j = 0; j < cd.length; j++) {
150-
pt = cd[j];
152+
for(var j = 0; j < cd.length; j++) {
153+
var pt = cd[j];
151154
if(pt.color === false) {
152155
// have we seen this label and assigned a color to it in a previous trace?
153156
if(colorMap[pt.label]) {
154157
pt.color = colorMap[pt.label];
155-
}
156-
else {
158+
} else {
157159
colorMap[pt.label] = pt.color = pieColorWay[dfltColorCount % pieColorWay.length];
158160
dfltColorCount++;
159161
}
160162
}
161163
}
162164
}
163-
};
165+
}
164166

165167
/**
166168
* pick a default color from the main default set, augmented by
167169
* itself lighter then darker before repeating
168170
*/
169-
var extendedColorWays = {};
170-
171-
function generateExtendedColors(colorList) {
171+
function generateExtendedColors(colorList, extendedColorWays) {
172172
var i;
173173
var colorString = JSON.stringify(colorList);
174174
var pieColors = extendedColorWays[colorString];
@@ -187,3 +187,11 @@ function generateExtendedColors(colorList) {
187187

188188
return pieColors;
189189
}
190+
191+
module.exports = {
192+
calc: calc,
193+
crossTraceCalc: crossTraceCalc,
194+
195+
makePullColorFn: makePullColorFn,
196+
generateExtendedColors: generateExtendedColors
197+
};

src/traces/pie/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var calcModule = require('./calc');
1919
Pie.calc = calcModule.calc;
2020
Pie.crossTraceCalc = calcModule.crossTraceCalc;
2121

22-
Pie.plot = require('./plot');
22+
Pie.plot = require('./plot').plot;
2323
Pie.style = require('./style');
2424
Pie.styleOne = require('./style_one');
2525

0 commit comments

Comments
 (0)