Skip to content

Commit f3d38b8

Browse files
committed
revisit pathbar draw as well as transition
1 parent cceee49 commit f3d38b8

File tree

9 files changed

+61
-72
lines changed

9 files changed

+61
-72
lines changed

src/traces/sunburst/helpers.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ var Color = require('../../components/color');
1313
var setCursor = require('../../lib/setcursor');
1414
var getTransform = require('../bar/plot').getTransform;
1515

16-
function has(v) {
17-
return v || v === 0;
16+
function hasLabel(label) {
17+
return label || label === 0;
1818
}
1919

2020
exports.findEntryWithLevel = function(hierarchy, level) {
@@ -63,11 +63,11 @@ exports.findChildPt = function(hierarchy, childId) {
6363
};
6464

6565
exports.isEntry = function(pt) {
66-
return !has(pt.parent);
66+
return !pt.parent;
6767
};
6868

6969
exports.isLeaf = function(pt) {
70-
return !has(pt.children);
70+
return !pt.children;
7171
};
7272

7373
exports.getPtId = function(pt) {
@@ -172,7 +172,7 @@ exports.isHeader = function(pt, trace) { // it is only used in treemap.
172172
};
173173

174174
exports.getLabelStr = function(label) {
175-
return has(label) ? label.split('<br>').join(' ') : '';
175+
return hasLabel(label) ? label.split('<br>').join(' ') : '';
176176
};
177177

178178
exports.getLabelString = function(label) { // used in hover to reference to the "root"
@@ -182,5 +182,10 @@ exports.getLabelString = function(label) { // used in hover to reference to the
182182

183183
exports.getPath = function(d) {
184184
var labelStr = exports.getLabelStr(d.data.label) + '/';
185-
return has(d.parent) ? exports.getPath(d.parent) + labelStr : labelStr;
185+
return d.parent ? exports.getPath(d.parent) + labelStr : labelStr;
186+
};
187+
188+
exports.listPath = function(d, keyStr) {
189+
var list = keyStr ? [d.data[keyStr]] : [d];
190+
return d.parent ? exports.listPath(d.parent, keyStr).concat(list) : list;
186191
};

src/traces/sunburst/plot.js

+12-10
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ function plotOne(gd, cd, element, transitionOpts) {
231231
}
232232

233233
sliceTop
234-
.call(exports.attachFxHandlers, entry, gd, cd, styleOne, constants)
234+
.call(exports.attachFxHandlers, gd, cd, styleOne, constants)
235235
.call(helpers.setSliceCursor, gd, {isTransitioning: gd._transitioning});
236236

237237
slicePath.call(styleOne, pt, trace);
@@ -500,7 +500,7 @@ function makeEventData(pt, trace) {
500500
return out;
501501
}
502502

503-
exports.attachFxHandlers = function(sliceTop, entry, gd, cd, styleOne, constants) {
503+
exports.attachFxHandlers = function(sliceTop, gd, cd, styleOne, constants) {
504504
var cd0 = cd[0];
505505
var trace = cd0.trace;
506506
var hierarchy = cd0.hierarchy;
@@ -595,7 +595,7 @@ exports.attachFxHandlers = function(sliceTop, entry, gd, cd, styleOne, constants
595595
}
596596
}
597597

598-
var ref1 = entry;
598+
var ref1 = hierarchy;
599599
if(ref1 && getVal(ref1)) {
600600
hoverPt.percentVisible = pt.percentVisible = val / getVal(ref1);
601601
hoverPt.visibleLabel = pt.visibleLabel = helpers.getLabelString(ref1.data.data.label);
@@ -740,15 +740,17 @@ exports.attachFxHandlers = function(sliceTop, entry, gd, cd, styleOne, constants
740740
var id = helpers.getPtId(pt);
741741
var isEntry = helpers.isEntry(pt);
742742

743-
var passPathOr = function(v) {
744-
var q = pt.data.data._pathTo;
745-
return (q === undefined) ? v : q;
746-
};
747-
748743
if(isTreemap) {
744+
var zoomOut = true;
745+
var redirectId = pt._redirect;
746+
if(redirectId === undefined) {
747+
redirectId = id;
748+
if(!isEntry) zoomOut = false;
749+
}
750+
749751
traceNow._clickedInfo = {
750-
id: passPathOr(id),
751-
zoomOut: passPathOr(isEntry)
752+
id: redirectId,
753+
zoomOut: zoomOut
752754
};
753755
}
754756

src/traces/treemap/draw_ancestors.js

+23-10
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,43 @@ module.exports = function drawAncestors(gd, cd, entry, slices, opts) {
4242
var fullLayout = gd._fullLayout;
4343
var cd0 = cd[0];
4444
var trace = cd0.trace;
45+
var hierarchy = cd0.hierarchy;
4546

46-
var eachWidth = opts.width / entry.height;
47+
var entryDepth = entry.data.depth;
4748

48-
var sliceData = partition(entry, [width, height], {
49+
var eachWidth = opts.width / entryDepth;
50+
51+
var pathIds = helpers.listPath(entry.data, 'id');
52+
pathIds.pop(); // remove last one which is the entry point.
53+
54+
var sliceData = partition(hierarchy.copy(), [width, height], {
4955
packing: 'dice',
5056
pad: {
5157
inner: 0,
5258
top: 0,
53-
left: eachWidth,
59+
left: 0,
5460
right: 0,
5561
bottom: 0
5662
}
5763
}).descendants();
5864

59-
// filter out slices that won't show up on graph
60-
sliceData = sliceData.filter(function(pt) { return pt.height > 0; });
65+
// edit slices that show up on graph
66+
sliceData = sliceData.filter(function(pt) {
67+
var level = pathIds.indexOf(pt.data.id);
68+
if(level === -1) return false;
6169

62-
slices = slices.data(sliceData, function(pt) {
63-
if(isNaN(pt.x0)) pt.x0 = 0;
64-
if(isNaN(pt.x1)) pt.x1 = width;
70+
pt.x0 = eachWidth * level;
71+
pt.x1 = width;
72+
pt.y0 = 0;
73+
pt.y1 = height;
6574

66-
return helpers.getPtId(pt);
75+
pt._redirect = entry.data.id;
76+
77+
return true;
6778
});
6879

80+
slices = slices.data(sliceData, function(pt) { return helpers.getPtId(pt); });
81+
6982
slices.enter().append('g')
7083
.classed('pathbar', true);
7184

@@ -103,7 +116,7 @@ module.exports = function drawAncestors(gd, cd, entry, slices, opts) {
103116
}
104117

105118
sliceTop
106-
.call(attachFxHandlers, entry, gd, cd, styleOne, constants)
119+
.call(attachFxHandlers, gd, cd, styleOne, constants)
107120
.call(helpers.setSliceCursor, gd, { isTransitioning: gd._transitioning });
108121

109122
slicePath.call(styleOne, pt, trace);

src/traces/treemap/draw_descendants.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ module.exports = function drawDescendants(gd, cd, entry, slices, opts) {
118118
}
119119

120120
sliceTop
121-
.call(attachFxHandlers, entry, gd, cd, styleOne, constants)
121+
.call(attachFxHandlers, gd, cd, styleOne, constants)
122122
.call(helpers.setSliceCursor, gd, { isTransitioning: gd._transitioning });
123123

124124
slicePath.call(styleOne, pt, trace);

src/traces/treemap/plot.js

+14-45
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
'use strict';
1010

1111
var d3 = require('d3');
12-
var d3Hierarchy = require('d3-hierarchy');
1312

1413
var hasTransition = require('../sunburst/helpers').hasTransition;
1514
var helpers = require('../sunburst/helpers');
@@ -33,9 +32,12 @@ module.exports = function(gd, cdmodule, transitionOpts, makeOnCompleteCallback)
3332
join = layer.selectAll('g.trace.treemap')
3433
.data(cdmodule, function(cd) { return cd[0].trace.uid; });
3534

35+
// using same 'stroke-linejoin' as pie traces
3636
join.enter().append('g')
3737
.classed('trace', true)
38-
.classed('treemap', true);
38+
.classed('treemap', true)
39+
.attr('stroke-linejoin', 'round');
40+
3941
join.order();
4042

4143
if(hasTransition(transitionOpts)) {
@@ -88,7 +90,7 @@ function plotOne(gd, cd, element, transitionOpts) {
8890

8991
var getOrigin = function(pt, upDown, refRect, size) {
9092
var clicked = trace._clickedInfo;
91-
if(!clicked || !pt.parent) { // don't animate the entry point
93+
if(!clicked) {
9294
return pt;
9395
}
9496

@@ -97,11 +99,12 @@ function plotOne(gd, cd, element, transitionOpts) {
9799
var x0, x1, y0, y1;
98100

99101
if(upDown) {
100-
x0 = x1 = width; // always slide pathbar to the right
102+
x0 = width; // always slide pathbar to the right, unless it is the root node
103+
x1 = width;
101104
y0 = 0;
102105
y1 = height;
103106
} else {
104-
var ref = clicked.zoomOut ? refRect : (prevLookdown[clicked.id] || prevLookup[clicked.id]);
107+
var ref = clicked.zoomOut ? refRect : prevLookdown[clicked.id] || prevLookup[clicked.id];
105108

106109
var e = trace.tiling.pad;
107110
var isLeftOfRect = function(x) { return x - e <= ref.x0; };
@@ -128,13 +131,12 @@ function plotOne(gd, cd, element, transitionOpts) {
128131
var vpw = gs.w * (domain.x[1] - domain.x[0]);
129132
var vph = gs.h * (domain.y[1] - domain.y[0]);
130133

131-
var barEntry;
132-
var mapEntry = helpers.findEntryWithLevel(hierarchy, trace.level);
134+
var entry = helpers.findEntryWithLevel(hierarchy, trace.level);
133135
var maxDepth = helpers.getMaxDepth(trace);
134136
// N.B. handle multiple-root special case
135137
var mvX = 0;
136138
var mvY = 0;
137-
if(cd0.hasMultipleRoots && helpers.isHierarchyRoot(mapEntry)) {
139+
if(cd0.hasMultipleRoots && helpers.isHierarchyRoot(entry)) {
138140
maxDepth++;
139141
}
140142
trace._maxDepth = maxDepth;
@@ -445,7 +447,7 @@ function plotOne(gd, cd, element, transitionOpts) {
445447
var selAncestors = gTrace.selectAll('g.pathbar');
446448
var selDescendants = gTrace.selectAll('g.slice');
447449

448-
if(!mapEntry) {
450+
if(!entry) {
449451
return selDescendants.remove();
450452
}
451453

@@ -473,7 +475,7 @@ function plotOne(gd, cd, element, transitionOpts) {
473475
});
474476
}
475477

476-
drawDescendants(gd, cd, mapEntry, selDescendants, {
478+
drawDescendants(gd, cd, entry, selDescendants, {
477479
width: vpw,
478480
height: vph,
479481

@@ -497,41 +499,8 @@ function plotOne(gd, cd, element, transitionOpts) {
497499
hasTransition: hasTransition
498500
});
499501

500-
if(trace.pathbar.visible) {
501-
var rawAncestors = mapEntry.data.ancestors();
502-
503-
var ancestors = [];
504-
for(var q = 0; q < rawAncestors.length; q++) {
505-
var raw = rawAncestors[q].data;
506-
507-
ancestors[q] = {
508-
id: raw.id,
509-
pid: raw.pid,
510-
label: raw.label,
511-
color: raw.color,
512-
_pathTo: mapEntry.data.id,
513-
};
514-
515-
if(raw.hasOwnProperty('v')) {
516-
ancestors[q].v = raw.v;
517-
} else {
518-
ancestors[q].value = raw.value;
519-
}
520-
}
521-
522-
var root;
523-
try {
524-
root = d3Hierarchy.stratify()
525-
.id(function(d) { return d.id; })
526-
.parentId(function(d) { return d.pid; })(ancestors);
527-
} catch(e) {
528-
return Lib.warn('Failed to build hierarchy for pathbar. Error: ' + e.message);
529-
}
530-
531-
// create new hierarchy
532-
barEntry = d3Hierarchy.hierarchy(root);
533-
534-
drawAncestors(gd, cd, barEntry, selAncestors, {
502+
if(trace.pathbar.visible && trace.pathbar.position !== 'inside') {
503+
drawAncestors(gd, cd, entry, selAncestors, {
535504
barDifY: barDifY,
536505
width: barW,
537506
height: barH,
146 Bytes
Loading
-197 Bytes
Loading
-510 Bytes
Loading
175 Bytes
Loading

0 commit comments

Comments
 (0)