Skip to content

Commit

Permalink
Merge pull request #3876 from plotly/funnelarea-traces
Browse files Browse the repository at this point in the history
Funnelarea traces
  • Loading branch information
archmoj authored May 22, 2019
2 parents 1ce7848 + b8b3d94 commit 5ce2a83
Show file tree
Hide file tree
Showing 80 changed files with 4,303 additions and 281 deletions.
11 changes: 11 additions & 0 deletions lib/funnelarea.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Copyright 2012-2019, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

module.exports = require('../src/traces/funnelarea');
1 change: 1 addition & 0 deletions lib/index-finance.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Plotly.register([
require('./bar'),
require('./histogram'),
require('./pie'),
require('./funnelarea'),
require('./ohlc'),
require('./candlestick'),
require('./funnel'),
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Plotly.register([

require('./pie'),
require('./sunburst'),
require('./funnelarea'),

require('./scatter3d'),
require('./surface'),
Expand Down
2 changes: 1 addition & 1 deletion src/components/fx/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = function calc(gd) {
// don't include hover calc fields for pie traces
// as calcdata items might be sorted by value and
// won't match the data array order.
if(Registry.traceIs(trace, 'pie')) continue;
if(Registry.traceIs(trace, 'pie-like')) continue;

var fillFn = Registry.traceIs(trace, '2dMap') ? paste : Lib.fillArray;

Expand Down
3 changes: 1 addition & 2 deletions src/components/legend/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var Registry = require('../../registry');
Expand Down Expand Up @@ -42,7 +41,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
legendReallyHasATrace = true;
// Always show the legend by default if there's a pie,
// or if there's only one trace but it's explicitly shown
if(Registry.traceIs(trace, 'pie') ||
if(Registry.traceIs(trace, 'pie-like') ||
trace._input.showlegend === true
) {
legendTraceCount++;
Expand Down
14 changes: 7 additions & 7 deletions src/components/legend/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ module.exports = function draw(gd) {
for(var j = 0; j < legendData[i].length; j++) {
var item = legendData[i][j][0];
var trace = item.trace;
var isPie = Registry.traceIs(trace, 'pie');
var name = isPie ? item.label : trace.name;
var isPieLike = Registry.traceIs(trace, 'pie-like');
var name = isPieLike ? item.label : trace.name;
maxLength = Math.max(maxLength, name && name.length || 0);
}
}
Expand Down Expand Up @@ -110,7 +110,7 @@ module.exports = function draw(gd) {

traces.style('opacity', function(d) {
var trace = d[0].trace;
if(Registry.traceIs(trace, 'pie')) {
if(Registry.traceIs(trace, 'pie-like')) {
return hiddenSlices.indexOf(d[0].label) !== -1 ? 0.5 : 1;
} else {
return trace.visible === 'legendonly' ? 0.5 : 1;
Expand Down Expand Up @@ -375,7 +375,7 @@ function clickOrDoubleClick(gd, legend, legendItem, numClicks, evt) {
if(trace._group) {
evtData.group = trace._group;
}
if(trace.type === 'pie') {
if(Registry.traceIs(trace, 'pie-like')) {
evtData.label = legendItem.datum()[0].label;
}

Expand All @@ -399,11 +399,11 @@ function drawTexts(g, gd, maxLength) {
var legendItem = g.data()[0][0];
var fullLayout = gd._fullLayout;
var trace = legendItem.trace;
var isPie = Registry.traceIs(trace, 'pie');
var isPieLike = Registry.traceIs(trace, 'pie-like');
var traceIndex = trace.index;
var isEditable = gd._context.edits.legendText && !isPie;
var isEditable = gd._context.edits.legendText && !isPieLike;

var name = isPie ? legendItem.label : trace.name;
var name = isPieLike ? legendItem.label : trace.name;
if(trace._meta) {
name = Lib.templateString(name, trace._meta);
}
Expand Down
4 changes: 1 addition & 3 deletions src/components/legend/get_legend_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var Registry = require('../../registry');
var helpers = require('./helpers');


module.exports = function getLegendData(calcdata, opts) {
var lgroupToTraces = {};
var lgroups = [];
Expand Down Expand Up @@ -45,7 +43,7 @@ module.exports = function getLegendData(calcdata, opts) {

if(!trace.visible || !trace.showlegend) continue;

if(Registry.traceIs(trace, 'pie')) {
if(Registry.traceIs(trace, 'pie-like')) {
if(!slicesShown[lgroup]) slicesShown[lgroup] = {};

for(j = 0; j < cd.length; j++) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/legend/handle_click.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ module.exports = function handleClick(g, gd, numClicks) {
}
}

if(Registry.traceIs(fullTrace, 'pie')) {
if(Registry.traceIs(fullTrace, 'pie-like')) {
var thisLabel = legendItem.label;
var thisLabelIndex = hiddenSlices.indexOf(thisLabel);

Expand Down
26 changes: 19 additions & 7 deletions src/components/legend/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ module.exports = function style(s, gd) {
.each(styleFunnels)
.each(styleBars)
.each(styleBoxes)
.each(styleFunnelareas)
.each(stylePies)
.each(styleLines)
.each(stylePoints)
Expand Down Expand Up @@ -307,14 +308,14 @@ module.exports = function style(s, gd) {
}

function styleBars(d) {
styleBarFamily(d, this);
styleBarLike(d, this);
}

function styleFunnels(d) {
styleBarFamily(d, this, 'funnel');
styleBarLike(d, this, 'funnel');
}

function styleBarFamily(d, lThis, desiredType) {
function styleBarLike(d, lThis, desiredType) {
var trace = d[0].trace;
var marker = trace.marker || {};
var markerLine = marker.line || {};
Expand Down Expand Up @@ -435,13 +436,24 @@ module.exports = function style(s, gd) {
}

function stylePies(d) {
stylePieLike(d, this, 'pie');
}

function styleFunnelareas(d) {
stylePieLike(d, this, 'funnelarea');
}

function stylePieLike(d, lThis, desiredType) {
var d0 = d[0];
var trace = d0.trace;

var pts = d3.select(this).select('g.legendpoints')
.selectAll('path.legendpie')
.data(Registry.traceIs(trace, 'pie') && trace.visible ? [d] : []);
pts.enter().append('path').classed('legendpie', true)
var isVisible = (!desiredType) ? Registry.traceIs(trace, desiredType) :
(trace.type === desiredType && trace.visible);

var pts = d3.select(lThis).select('g.legendpoints')
.selectAll('path.legend' + desiredType)
.data(isVisible ? [d] : []);
pts.enter().append('path').classed('legend' + desiredType, true)
.attr('d', 'M6,6H-6V-6H6Z')
.attr('transform', 'translate(20,0)');
pts.exit().remove();
Expand Down
3 changes: 2 additions & 1 deletion src/components/modebar/manage.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ function getButtonGroups(gd, buttonsToRemove, buttonsToAdd, showSendToCloud) {
var hasGL3D = fullLayout._has('gl3d');
var hasGeo = fullLayout._has('geo');
var hasPie = fullLayout._has('pie');
var hasFunnelarea = fullLayout._has('funnelarea');
var hasGL2D = fullLayout._has('gl2d');
var hasTernary = fullLayout._has('ternary');
var hasMapbox = fullLayout._has('mapbox');
Expand Down Expand Up @@ -113,7 +114,7 @@ function getButtonGroups(gd, buttonsToRemove, buttonsToAdd, showSendToCloud) {
var resetGroup = [];
var dragModeGroup = [];

if((hasCartesian || hasGL2D || hasPie || hasTernary) + hasGeo + hasGL3D + hasMapbox + hasPolar > 1) {
if((hasCartesian || hasGL2D || hasPie || hasFunnelarea || hasTernary) + hasGeo + hasGL3D + hasMapbox + hasPolar > 1) {
// graphs with more than one plot types get 'union buttons'
// which reset the view or toggle hover labels across all subplots.
hoverGroup = ['toggleHover'];
Expand Down
12 changes: 12 additions & 0 deletions src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1159,3 +1159,15 @@ lib.fillText = function(calcPt, trace, contOut) {
lib.isValidTextValue = function(v) {
return v || v === 0;
};

lib.formatPercent = function(ratio, n) {
n = n || 0;
var str = (Math.round(100 * ratio * Math.pow(10, n)) * Math.pow(0.1, n)).toFixed(n) + '%';
for(var i = 0; i < n; i++) {
if(str.indexOf('.') !== -1) {
str = str.replace('0%', '%');
str = str.replace('.%', '%');
}
}
return str;
};
3 changes: 1 addition & 2 deletions src/plot_api/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var isNumeric = require('fast-isnumeric');
Expand Down Expand Up @@ -328,7 +327,7 @@ exports.cleanData = function(data) {
trace.scene = Plots.subplotsRegistry.gl3d.cleanId(trace.scene);
}

if(!traceIs(trace, 'pie') && !traceIs(trace, 'bar-like')) {
if(!traceIs(trace, 'pie-like') && !traceIs(trace, 'bar-like')) {
if(Array.isArray(trace.textposition)) {
for(i = 0; i < trace.textposition.length; i++) {
trace.textposition[i] = cleanTextPosition(trace.textposition[i]);
Expand Down
14 changes: 9 additions & 5 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';


var d3 = require('d3');
var isNumeric = require('fast-isnumeric');
var hasHover = require('has-hover');
Expand Down Expand Up @@ -1634,7 +1632,10 @@ function _restyle(gd, aobj, traces) {
doextra(prefixDot + 'len', innerContFull.len *
(newVal === 'fraction' ? 1 / lennorm : lennorm), i);
}
} else if(ai === 'type' && (newVal === 'pie') !== (oldVal === 'pie')) {
} else if(ai === 'type' && (
(newVal === 'pie') !== (oldVal === 'pie') ||
(newVal === 'funnelarea') !== (oldVal === 'funnelarea')
)) {
var labelsTo = 'x';
var valuesTo = 'y';
if((newVal === 'bar' || oldVal === 'bar') && cont.orientation === 'h') {
Expand All @@ -1645,7 +1646,7 @@ function _restyle(gd, aobj, traces) {
Lib.swapAttrs(cont, ['d?', '?0'], 'label', labelsTo);
Lib.swapAttrs(cont, ['?', '?src'], 'values', valuesTo);

if(oldVal === 'pie') {
if(oldVal === 'pie' || oldVal === 'funnelarea') {
nestedProperty(cont, 'marker.color')
.set(nestedProperty(cont, 'marker.colors').get());

Expand Down Expand Up @@ -3769,10 +3770,13 @@ function makePlotFramework(gd) {
// single geo layer for the whole plot
fullLayout._geolayer = fullLayout._paper.append('g').classed('geolayer', true);

// single funnelarea layer for the whole plot
fullLayout._funnelarealayer = fullLayout._paper.append('g').classed('funnelarealayer', true);

// single pie layer for the whole plot
fullLayout._pielayer = fullLayout._paper.append('g').classed('pielayer', true);

// single sunbursrt layer for the whole plot
// single sunburst layer for the whole plot
fullLayout._sunburstlayer = fullLayout._paper.append('g').classed('sunburstlayer', true);

// fill in image server scrape-svg
Expand Down
3 changes: 2 additions & 1 deletion src/plots/plots.js
Original file line number Diff line number Diff line change
Expand Up @@ -2758,9 +2758,10 @@ plots.doCalcdata = function(gd, traces) {
gd._hmpixcount = 0;
gd._hmlumcount = 0;

// for sharing colors across pies / sunbursts (and for legend)
// for sharing colors across pies / sunbursts / funnelarea (and for legend)
fullLayout._piecolormap = {};
fullLayout._sunburstcolormap = {};
fullLayout._funnelareacolormap = {};

// If traces were specified and this trace was not included,
// then transfer it over from the old calcdata:
Expand Down
4 changes: 2 additions & 2 deletions src/snapshot/cloneplot.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var Registry = require('../registry');
var Lib = require('../lib');

var extendFlat = Lib.extendFlat;
Expand Down Expand Up @@ -89,7 +89,7 @@ module.exports = function clonePlot(graphObj, options) {
var trace = newData[i];
trace.showscale = false;
if(trace.marker) trace.marker.showscale = false;
if(trace.type === 'pie') trace.textposition = 'none';
if(Registry.traceIs(trace, 'pie-like')) trace.textposition = 'none';
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/traces/bar/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ module.exports = {
valType: 'enumerated',
values: ['end', 'middle', 'start'],
dflt: 'end',
role: 'info', // TODO: or style ?
role: 'info',
editType: 'plot',
description: [
'Determines if texts are kept at center or start/end points in `textposition` *inside* mode.'
Expand All @@ -98,7 +98,7 @@ module.exports = {
textangle: {
valType: 'angle',
dflt: 'auto',
role: 'info', // TODO: or style ?
role: 'info',
editType: 'plot',
description: [
'Sets the angle of the tick labels with respect to the bar.',
Expand Down
Loading

0 comments on commit 5ce2a83

Please sign in to comment.