Skip to content

Commit 28b2f14

Browse files
committed
improve funnelarea scalegroup
1 parent 77f1c59 commit 28b2f14

File tree

6 files changed

+69
-51
lines changed

6 files changed

+69
-51
lines changed

src/traces/funnelarea/plot.js

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,22 @@ var piePlot = require('../pie/plot');
2323
var attachFxHandlers = piePlot.attachFxHandlers;
2424
var determineInsideTextFont = piePlot.determineInsideTextFont;
2525

26-
var scalePies = piePlot.scalePies;
26+
var layoutAreas = piePlot.layoutAreas;
2727
var prerenderTitles = piePlot.prerenderTitles;
2828
var positionTitleOutside = piePlot.positionTitleOutside;
2929

3030
module.exports = function plot(gd, cdModule) {
3131
var fullLayout = gd._fullLayout;
3232

3333
prerenderTitles(cdModule, gd);
34-
scalePies(cdModule, fullLayout._size);
34+
layoutAreas(cdModule, fullLayout._size);
3535

3636
Lib.makeTraceGroups(fullLayout._funnelarealayer, cdModule, 'trace').each(function(cd) {
3737
var plotGroup = d3.select(this);
3838
var cd0 = cd[0];
3939
var trace = cd0.trace;
4040

41-
setCoords(cd, fullLayout);
41+
setCoords(cd);
4242

4343
plotGroup.each(function() {
4444
var slices = d3.select(this).selectAll('g.slice').data(cd);
@@ -179,19 +179,15 @@ function getBetween(a, b) {
179179
];
180180
}
181181

182-
function setCoords(cd, fullLayout) {
182+
function setCoords(cd) {
183183
if(!cd.length) return;
184184

185185
var cd0 = cd[0];
186+
var trace = cd0.trace;
186187

187-
var size = fullLayout._size;
188-
var domain = cd0.trace.domain;
189-
var width = size.w * Math.abs(domain.x[1] - domain.x[0]);
190-
var height = size.h * Math.abs(domain.y[1] - domain.y[0]);
188+
var aspectratio = trace.aspectratio;
191189

192-
var aspectratio = cd0.trace.aspectratio;
193-
194-
var h = cd0.trace.baseratio;
190+
var h = trace.baseratio;
195191
if(h > 0.999) h = 0.999; // TODO: may handle this case separately
196192
var h2 = Math.pow(h, 2);
197193

@@ -246,18 +242,16 @@ function setCoords(cd, fullLayout) {
246242

247243
// get pie r
248244
var r = cd0.r;
249-
if(cd0.trace.scalegroup) {
250-
r *= Math.sqrt(Math.PI / 4);
251-
r /= Math.sqrt(1 + h);
252-
r *= Math.sqrt((aspectratio < height / width) ? 1 / aspectratio : aspectratio);
253-
}
254245

255246
var rY = (maxY - minY) / 2;
256247
var scaleX = r / lastX;
257-
var scaleY = r / (aspectratio * rY);
258-
if(aspectratio < height / width) {
259-
scaleX *= aspectratio;
260-
scaleY *= aspectratio;
248+
var scaleY = r / rY / aspectratio;
249+
250+
if(!trace.scalegroup) {
251+
if(aspectratio < cd0.figMaxH / cd0.figMaxW) {
252+
scaleX *= aspectratio;
253+
scaleY *= aspectratio;
254+
}
261255
}
262256

263257
// set funnelarea r

src/traces/pie/plot.js

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function plot(gd, cdModule) {
2323
var fullLayout = gd._fullLayout;
2424

2525
prerenderTitles(cdModule, gd);
26-
scalePies(cdModule, fullLayout._size);
26+
layoutAreas(cdModule, fullLayout._size);
2727

2828
var plotGroups = Lib.makeTraceGroups(fullLayout._pielayer, cdModule, 'trace').each(function(cd) {
2929
var plotGroup = d3.select(this);
@@ -800,30 +800,28 @@ function scootLabels(quadrants, trace) {
800800
}
801801
}
802802

803-
function scalePies(cdModule, plotSize) {
803+
function layoutAreas(cdModule, plotSize) {
804804
var scaleGroups = [];
805805

806-
var pieBoxWidth, pieBoxHeight, i, j, cd0, trace,
807-
maxPull, scaleGroup, minPxPerValUnit;
808-
809-
// first figure out the center and maximum radius for each pie
810-
for(i = 0; i < cdModule.length; i++) {
811-
cd0 = cdModule[i][0];
812-
trace = cd0.trace;
806+
// figure out the center and maximum radius
807+
for(var i = 0; i < cdModule.length; i++) {
808+
var cd0 = cdModule[i][0];
809+
var trace = cd0.trace;
813810

814-
pieBoxWidth = plotSize.w * (trace.domain.x[1] - trace.domain.x[0]);
815-
pieBoxHeight = plotSize.h * (trace.domain.y[1] - trace.domain.y[0]);
811+
var domain = trace.domain;
812+
var width = plotSize.w * (domain.x[1] - domain.x[0]);
813+
var height = plotSize.h * (domain.y[1] - domain.y[0]);
816814
// leave some space for the title, if it will be displayed outside
817815
if(trace.title.text && trace.title.position !== 'middle center') {
818-
pieBoxHeight -= getTitleSpace(cd0, plotSize);
816+
height -= getTitleSpace(cd0, plotSize);
819817
}
820818

821-
maxPull = getMaxPull(trace);
822-
823-
cd0.r = Math.min(pieBoxWidth, pieBoxHeight) / (2 + 2 * maxPull);
819+
cd0.figMaxH = height;
820+
cd0.figMaxW = width;
821+
cd0.r = Math.min(width / 2, height / 2) / (1 + getMaxPull(trace));
824822

825823
cd0.cx = plotSize.l + plotSize.w * (trace.domain.x[1] + trace.domain.x[0]) / 2;
826-
cd0.cy = plotSize.t + plotSize.h * (1 - trace.domain.y[0]) - pieBoxHeight / 2;
824+
cd0.cy = plotSize.t + plotSize.h * (1 - trace.domain.y[0]) - height / 2;
827825
if(trace.title.text && trace.title.position.indexOf('bottom') !== -1) {
828826
cd0.cy -= getTitleSpace(cd0, plotSize);
829827
}
@@ -833,23 +831,54 @@ function scalePies(cdModule, plotSize) {
833831
}
834832
}
835833

836-
// Then scale any pies that are grouped
837-
for(j = 0; j < scaleGroups.length; j++) {
838-
minPxPerValUnit = Infinity;
839-
scaleGroup = scaleGroups[j];
834+
groupScale(cdModule, scaleGroups);
835+
}
836+
837+
function groupScale(cdModule, scaleGroups) {
838+
var cd0, i, trace;
839+
840+
// scale those that are grouped
841+
for(var k = 0; k < scaleGroups.length; k++) {
842+
var min = Infinity;
843+
var g = scaleGroups[k];
840844

841845
for(i = 0; i < cdModule.length; i++) {
842846
cd0 = cdModule[i][0];
843-
if(cd0.trace.scalegroup === scaleGroup) {
844-
minPxPerValUnit = Math.min(minPxPerValUnit,
845-
cd0.r * cd0.r / cd0.vTotal);
847+
trace = cd0.trace;
848+
849+
if(trace.scalegroup === g) {
850+
var area;
851+
if(trace.type === 'pie') {
852+
area = cd0.r * cd0.r;
853+
} else if(trace.type === 'funnelarea') {
854+
var rx, ry;
855+
if(trace.aspectratio < 1) {
856+
rx = cd0.r;
857+
ry = rx * trace.aspectratio;
858+
} else {
859+
ry = cd0.r;
860+
rx = ry / trace.aspectratio;
861+
}
862+
rx *= (1 + trace.baseratio) / 2;
863+
864+
area = rx * ry;
865+
}
866+
867+
min = Math.min(min, area / cd0.vTotal);
846868
}
847869
}
848870

849871
for(i = 0; i < cdModule.length; i++) {
850872
cd0 = cdModule[i][0];
851-
if(cd0.trace.scalegroup === scaleGroup) {
852-
cd0.r = Math.sqrt(minPxPerValUnit * cd0.vTotal);
873+
trace = cd0.trace;
874+
if(trace.scalegroup === g) {
875+
var v = min * cd0.vTotal;
876+
if(trace.type === 'funnelarea') {
877+
v /= (1 + trace.baseratio) / 2;
878+
v *= trace.aspectratio;
879+
}
880+
881+
cd0.r = Math.sqrt(v);
853882
}
854883
}
855884
}
@@ -912,6 +941,6 @@ module.exports = {
912941
determineInsideTextFont: determineInsideTextFont,
913942
positionTitleOutside: positionTitleOutside,
914943
prerenderTitles: prerenderTitles,
915-
scalePies: scalePies,
944+
layoutAreas: layoutAreas,
916945
attachFxHandlers: attachFxHandlers,
917946
};
2.9 KB
Loading
-2.76 KB
Loading
-3.78 KB
Loading

test/jasmine/tests/funnelarea_test.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,11 +1455,6 @@ describe('Test funnelarea calculated areas with scalegroup', function() {
14551455
{aspectratio: 0.5, baseratio: 0.5},
14561456
{aspectratio: 0.5, baseratio: 0.75},
14571457
{aspectratio: 0.5, baseratio: 1},
1458-
{aspectratio: 1, baseratio: 0},
1459-
{aspectratio: 1, baseratio: 0.25},
1460-
{aspectratio: 1, baseratio: 0.5},
1461-
{aspectratio: 1, baseratio: 0.75},
1462-
{aspectratio: 1, baseratio: 1},
14631458
{aspectratio: 2, baseratio: 0},
14641459
{aspectratio: 2, baseratio: 0.25},
14651460
{aspectratio: 2, baseratio: 0.5},

0 commit comments

Comments
 (0)