Skip to content

Funnel support #934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dev/mocks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"/percy/panelTest.json",
"/percy/bar.json",
"/percy/box.json",
"/percy/funnel.json",
"/percy/funnelarea.json",
"/percy/histogram.json",
"/percy/histogram2d.json",
"/percy/pie.json",
Expand Down
9 changes: 9 additions & 0 deletions dev/percy/funnel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"data": [
{
"type": "funnel",
"y": ["Lead", "Pipeline", "Proposal", "Negotiation", "Closed (Won)"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a general, more plot.js type question. Why are the axes for funnel (x/y) and funnelarea (labels/values), why couldn't they both have been named (labels/values) ? I feel like that would have been easier understand for a business type chart.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah this is because funnel is based on bar and is on cartesian axes, but funnelarea is based on pie and has no axes or orientation.

"x": [ 610, 432, 231, 103, 54 ]
}
]
}
9 changes: 9 additions & 0 deletions dev/percy/funnelarea.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"data": [
{
"type": "funnelarea",
"labels": ["Lead", "Pipeline", "Proposal", "Negotiation", "Closed (Won)"],
"values": [ 610, 432, 231, 103, 54 ]
}
]
}
2 changes: 2 additions & 0 deletions dev/percy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ export {default as box} from './box.json';
export {default as waterfall} from './waterfall.json';
export {default as sunburst} from './sunburst.json';
export {default as sankey} from './sankey.json';
export {default as funnel} from './funnel.json';
export {default as funnelarea} from './funnelarea.json';
export {default as geoTest} from './geoTest.json';
3 changes: 2 additions & 1 deletion src/EditorControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
shamefullyAdjustSplitStyleTargetContainers,
shamefullyDeleteRelatedAnalysisTransforms,
shamefullyAdjustSizeref,
shamefullyAdjustAxisDirection,
} from './shame';
import {EDITOR_ACTIONS} from './lib/constants';
import isNumeric from 'fast-isnumeric';
Expand Down Expand Up @@ -71,7 +72,7 @@ class EditorControls extends Component {
}

shamefullyAdjustSizeref(graphDiv, payload);

shamefullyAdjustAxisDirection(graphDiv, payload);
shamefullyClearAxisTypes(graphDiv, payload);
shamefullyAdjustAxisRef(graphDiv, payload);
shamefullyAddTableColumns(graphDiv, payload);
Expand Down
6 changes: 4 additions & 2 deletions src/components/containers/SubplotAccordion.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class SubplotAccordion extends Component {
// of right type that have attr 'subplot': 'ternary' in their data.

/**
Example:
Example:
{
"data": [
{
Expand Down Expand Up @@ -126,7 +126,9 @@ class SubplotAccordion extends Component {
data.forEach((d, i) => {
if (
(d.type === 'pie' && d.values) ||
['pie', 'table', 'sunburst', 'sankey', 'parcoords', 'parcats'].includes(d.type)
['pie', 'table', 'sunburst', 'sankey', 'parcoords', 'parcats', 'funnelarea'].includes(
d.type
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's nice that we can make subplots with funnelarea, but the legends will overlap, unless there's a control i've missed for that?
Screen Shot 2019-06-13 at 10 51 20 AM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the legend is merged, not overlapping, just like with a multi-pie scenario.

) {
counter[d.type]++;
const currentCount = counter[d.type];
Expand Down
8 changes: 3 additions & 5 deletions src/components/containers/TraceMarkerSection.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ class TraceMarkerSection extends Component {
setLocals(context) {
const _ = this.context.localize;
const traceType = context.fullContainer.type;
if (['bar', 'histogram'].includes(traceType)) {
if (['bar', 'histogram', 'funnel', 'waterfall'].includes(traceType)) {
this.name = _('Bars');
} else if (traceType === 'pie') {
this.name = _('Pie Segments');
} else if (traceType === 'sunburst') {
this.name = _('Sunburst Segments');
} else if (['funnelarea', 'pie', 'sunburst'].includes(traceType)) {
this.name = _('Segments');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

} else {
this.name = _('Points');
}
Expand Down
1 change: 1 addition & 0 deletions src/components/fields/DataSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class UnconnectedDataSelector extends Component {
'scatter',
'scattergl',
'bar',
'funnel',
'heatmap',
'heatmapgl',
'violin',
Expand Down
5 changes: 4 additions & 1 deletion src/components/fields/TextPosition.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,17 @@ export default connectToContainer(UnconnectedTextPosition, {
{label: _('Bottom Center'), value: 'bottom center'},
{label: _('Bottom Right'), value: 'bottom right'},
];
if (['pie', 'bar', 'waterfall'].includes(context.container.type)) {
if (['pie', 'bar', 'funnel', 'waterfall'].includes(context.container.type)) {
options = [
{label: _('Inside'), value: 'inside'},
{label: _('Outside'), value: 'outside'},
{label: _('Auto'), value: 'auto'},
{label: _('None'), value: 'none'},
];
}
if (['funnelarea'].includes(context.container.type)) {
options = [{label: _('Inside'), value: 'inside'}, {label: _('None'), value: 'none'}];
}
plotProps.options = options;
plotProps.clearable = false;
},
Expand Down
17 changes: 14 additions & 3 deletions src/components/fields/derived.js
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,23 @@ function computeAxesRefOptions(axes, propsAttr) {
export const TextInfo = connectToContainer(UnconnectedFlaglist, {
modifyPlotProps: (props, context, plotProps) => {
const {localize: _, container} = context;
const options = [

let options = [
{label: _('Label'), value: 'label'},
{label: _('Value'), value: 'value'},
{label: _('%'), value: 'percent'},
];

if (container.type === 'funnel') {
options = [
{label: _('Label'), value: 'label'},
{label: _('Value'), value: 'value'},
{label: _('% initial'), value: 'percent initial'},
{label: _('% previous'), value: 'percent previous'},
{label: _('% total'), value: 'percent total'},
];
}

if (container.text) {
options.push({label: _('Text'), value: 'text'});
}
Expand Down Expand Up @@ -591,11 +602,11 @@ export const HoverInfo = connectToContainer(UnconnectedFlaglist, {
options = [];
}

if (container.labels && ['pie', 'sunburst'].includes(container.type)) {
if (container.labels && ['pie', 'sunburst', 'funnelarea'].includes(container.type)) {
options.push({label: _('Label'), value: 'label'});
}

if (container.values && ['pie', 'sunburst'].includes(container.type)) {
if (container.values && ['pie', 'sunburst', 'funnelarea'].includes(container.type)) {
options.push({label: _('Value'), value: 'value'});
}

Expand Down
181 changes: 106 additions & 75 deletions src/default_panels/StyleTracesPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,38 +91,44 @@ const StyleTracesPanel = (props, {localize: _}) => (
<Numeric label={_('Max Tube segments')} attr="maxdisplayed" />
</PlotlySection>
<MultiColorPicker label={_('Color')} attr="color" />
<TraceTypeSection name={_('Waterfall')} traceTypes={['waterfall']} mode="trace">
<LayoutSection attr="name">
<Radio
label={_('Mode')}
attr="waterfallmode"
options={[{label: _('Group'), value: 'group'}, {label: _('Overlay'), value: 'overlay'}]}
/>
<NumericFraction label={_('Gap')} attr="waterfallgap" />
<NumericFraction label={_('Group gap')} attr="waterfallgroupgap" />
</LayoutSection>
</TraceTypeSection>
<TraceTypeSection name={_('Pie Colors')} traceTypes={['pie']} mode="trace">
<TraceTypeSection
name={_('Segment Colors')}
traceTypes={['pie', 'sunburst', 'funnelarea']}
mode="trace"
>
<LayoutSection attr="name">
<ColorwayPicker label={_('Colors')} attr="piecolorway" />
<Radio
label={_('Extended Colors')}
attr="extendpiecolors"
options={[{label: _('On'), value: true}, {label: _('Off'), value: false}]}
/>
</LayoutSection>
</TraceTypeSection>
<TraceTypeSection name={_('Sunburst Colors')} traceTypes={['sunburst']} mode="trace">
<LayoutSection attr="name">
<ColorwayPicker label={_('Colors')} attr="sunburstcolorway" />
<Radio
label={_('Extended Colors')}
attr="extendsunburstcolors"
options={[{label: _('On'), value: true}, {label: _('Off'), value: false}]}
/>
<ColorwayPicker label={_('Colors')} attr="funnelareacolorway" />
<Radio
label={_('Extended Colors')}
attr="extendfunnelareacolors"
options={[{label: _('On'), value: true}, {label: _('Off'), value: false}]}
/>
</LayoutSection>
</TraceTypeSection>
<PlotlySection name={_('Pie Title')} attr="title.text">
<PlotlySection name={_('Funnel Dimensions')} traceTypes={['funnelarea']} attr="aspectratio">
<Numeric
label={_('Aspect Ratio')}
attr="aspectratio"
step={0.01}
min={0}
max={2}
showSlider
/>
<NumericFraction label={_('Base Ratio')} attr="baseratio" />
</PlotlySection>
<PlotlySection name={_('Subplot Title')} attr="title.text">
<TextEditor label={_('Name')} attr="title.text" />
<Dropdown
label={'Title Position'}
Expand Down Expand Up @@ -231,7 +237,7 @@ const StyleTracesPanel = (props, {localize: _}) => (
</PlotlySection>
<TraceTypeSection
name={_('Bar Grouping, Sizing and Spacing')}
traceTypes={['bar', 'histogram']}
traceTypes={['bar', 'histogram', 'funnel', 'waterfall']}
mode="trace"
>
<LayoutSection attr="name">
Expand All @@ -258,6 +264,32 @@ const StyleTracesPanel = (props, {localize: _}) => (
/>
<NumericFractionInverse label={_('Bar Width')} attr="bargap" />
<NumericFraction label={_('Bar Padding')} attr="bargroupgap" />

<Dropdown
label={_('Bar Mode')}
attr="funnelmode"
options={[
{label: _('Grouped'), value: 'group'},
{label: _('Stacked'), value: 'stack'},
{label: _('Overlaid'), value: 'overlay'},
]}
clearable={false}
/>
<NumericFractionInverse label={_('Bar Width')} attr="funnelgap" />
<NumericFraction label={_('Bar Padding')} attr="funnelgroupgap" />

<Dropdown
label={_('Bar Mode')}
attr="waterfallmode"
options={[
{label: _('Grouped'), value: 'group'},
{label: _('Stacked'), value: 'stack'},
{label: _('Overlaid'), value: 'overlay'},
]}
clearable={false}
/>
<NumericFractionInverse label={_('Bar Width')} attr="waterfallgap" />
<NumericFraction label={_('Bar Padding')} attr="waterfallgroupgap" />
</LayoutSection>
</TraceTypeSection>
<PlotlySection name={_('Binning')}>
Expand Down Expand Up @@ -363,6 +395,60 @@ const StyleTracesPanel = (props, {localize: _}) => (
<MultiColorPicker label={_('Border Color')} attr="marker.line.color" />
<Numeric label={_('Max Number of Points')} attr="marker.maxdisplayed" />
</TraceMarkerSection>
<PlotlySection name={_('Connector Styles')}>
<Radio
attr="connector.visible"
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
/>
<MultiColorPicker label={_('Fill Color')} attr="connector.fillcolor" />
<Numeric label={_('Line Width')} attr="connector.line.width" />
<MultiColorPicker label={_('Line Color')} attr="connector.line.color" />
<LineDashSelector label={_('Line Type')} attr="connector.line.dash" />
<Dropdown
label={_('Line Shape')}
options={[
{label: _('Spanning'), value: 'spanning'},
{label: _('Between'), value: 'between'},
]}
attr="connector.mode"
clearable={false}
/>
</PlotlySection>
<PlotlySection name={_('Increasing Marker Styles')}>
<TextEditor label={_('Name')} attr="increasing.name" richTextOnly />
<Numeric label={_('Width')} attr="increasing.line.width" />
<MultiColorPicker label={_('Line Color')} attr="increasing.line.color" />
<MultiColorPicker label={_('Marker Color')} attr="increasing.marker.color" />
<MultiColorPicker label={_('Line Color')} attr="increasing.marker.line.color" />
<Numeric label={_('Line Width')} attr="increasing.marker.line.width" />
<MultiColorPicker label={_('Fill Color')} attr="increasing.fillcolor" />
<LineDashSelector label={_('Type')} attr="increasing.line.dash" />
<Radio
label={_('Show in Legend')}
attr="increasing.showlegend"
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
/>
</PlotlySection>
<PlotlySection name={_('Decreasing Marker Styles')}>
<TextEditor label={_('Name')} attr="decreasing.name" richTextOnly />
<Numeric label={_('Width')} attr="decreasing.line.width" />
<MultiColorPicker label={_('Line Color')} attr="decreasing.line.color" />
<MultiColorPicker label={_('Marker Color')} attr="decreasing.marker.color" />
<MultiColorPicker label={_('Line Color')} attr="decreasing.marker.line.color" />
<Numeric label={_('Line Width')} attr="decreasing.marker.line.width" />
<MultiColorPicker label={_('Fill Color')} attr="decreasing.fillcolor" />
<LineDashSelector label={_('Type')} attr="decreasing.line.dash" />
<Radio
label={_('Show in Legend')}
attr="decreasing.showlegend"
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
/>
</PlotlySection>
<PlotlySection name={_('Total Marker Styles')}>
<MultiColorPicker label={_('Marker Color')} attr="totals.marker.color" />
<MultiColorPicker label={_('Line Color')} attr="totals.marker.line.color" />
<Numeric label={_('Line Width')} attr="totals.marker.line.width" />
</PlotlySection>
<PlotlySection name={_('Ticks')}>
<Numeric label={_('Width')} attr="tickwidth" />
</PlotlySection>
Expand Down Expand Up @@ -597,59 +683,6 @@ const StyleTracesPanel = (props, {localize: _}) => (
<NumericFraction label={_('Y')} attr="lightposition.y" />
<NumericFraction label={_('Z')} attr="lightposition.z" />
</PlotlySection>
<PlotlySection name={_('Increasing Marker Styles')}>
<TextEditor label={_('Name')} attr="increasing.name" richTextOnly />
<Numeric label={_('Width')} attr="increasing.line.width" />
<MultiColorPicker label={_('Line Color')} attr="increasing.line.color" />
<MultiColorPicker label={_('Marker Color')} attr="increasing.marker.color" />
<MultiColorPicker label={_('Line Color')} attr="increasing.marker.line.color" />
<Numeric label={_('Line Width')} attr="increasing.marker.line.width" />
<MultiColorPicker label={_('Fill Color')} attr="increasing.fillcolor" />
<LineDashSelector label={_('Type')} attr="increasing.line.dash" />
<Radio
label={_('Show in Legend')}
attr="increasing.showlegend"
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
/>
</PlotlySection>
<PlotlySection name={_('Decreasing Marker Styles')}>
<TextEditor label={_('Name')} attr="decreasing.name" richTextOnly />
<Numeric label={_('Width')} attr="decreasing.line.width" />
<MultiColorPicker label={_('Line Color')} attr="decreasing.line.color" />
<MultiColorPicker label={_('Marker Color')} attr="decreasing.marker.color" />
<MultiColorPicker label={_('Line Color')} attr="decreasing.marker.line.color" />
<Numeric label={_('Line Width')} attr="decreasing.marker.line.width" />
<MultiColorPicker label={_('Fill Color')} attr="decreasing.fillcolor" />
<LineDashSelector label={_('Type')} attr="decreasing.line.dash" />
<Radio
label={_('Show in Legend')}
attr="decreasing.showlegend"
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
/>
</PlotlySection>
<PlotlySection name={_('Total Marker Styles')}>
<MultiColorPicker label={_('Marker Color')} attr="totals.marker.color" />
<MultiColorPicker label={_('Line Color')} attr="totals.marker.line.color" />
<Numeric label={_('Line Width')} attr="totals.marker.line.width" />
</PlotlySection>
<PlotlySection name={_('Connector Styles')}>
<Radio
attr="connector.visible"
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
/>
<Numeric label={_('Line Width')} attr="connector.line.width" />
<MultiColorPicker label={_('Line Color')} attr="connector.line.color" />
<LineDashSelector label={_('Line Type')} attr="connector.line.dash" />
<Dropdown
label={_('Line Shape')}
options={[
{label: _('Spanning'), value: 'spanning'},
{label: _('Between'), value: 'between'},
]}
attr="connector.mode"
clearable={false}
/>
</PlotlySection>
<PlotlySection name={_('Scaling')}>
<GroupCreator label={_('Scale Group')} prefix={_('Group')} attr="scalegroup" />
<Radio
Expand Down Expand Up @@ -729,7 +762,8 @@ const StyleTracesPanel = (props, {localize: _}) => (
<MultiColorPicker label={_('Line Color')} attr="link.line.color" />
<Numeric label={_('Line Width')} attr="link.line.width" min={0} />
</PlotlySection>
<PlotlySection name={_('Hover/Tooltip Text')}>
<PlotlySection name={_('Hover/Tooltip')}>
<HoveronDropdown attr="hoveron" label={_('Hover on')} />
<HoverTemplateSwitch attr="hovertemplate" label={_('Mode')} />
<HoverInfo attr="hoverinfo" label={_('Show')} />
<HoverTemplateText attr="hovertemplate" label={_('Template')} />
Expand Down Expand Up @@ -762,9 +796,6 @@ const StyleTracesPanel = (props, {localize: _}) => (
<Text label={_('Value Format')} attr="valueformat" />
<Text label={_('Value Suffix')} attr="valuesuffix" />
</PlotlySection>
<PlotlySection name={_('Hover Action')}>
<HoveronDropdown attr="hoveron" label={_('Hover on')} />
</PlotlySection>
<TraceTypeSection
name={_('Error Bars X')}
traceTypes={['scatter', 'scattergl', 'scatter3d', 'bar']}
Expand Down
Loading