diff --git a/dev/percy/histogram.json b/dev/percy/histogram.json new file mode 100644 index 000000000..d8f399464 --- /dev/null +++ b/dev/percy/histogram.json @@ -0,0 +1,69 @@ +{ + "data": [ + { + "type": "histogram", + "mode": "markers", + "uid": "dcb598", + "x": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "xsrc": "ints", + "autobinx": true, + "xbins": { + "start": -0.5, + "end": 7.5, + "size": 2 + }, + "y": [ + 2, + 1, + 3, + 5, + 4, + 6 + ], + "ysrc": "jagged ints", + "error_x": { + "visible": true, + "symmetric": true + }, + "error_y": { + "visible": true, + "symmetric": false + }, + "orientation": "v", + "autobiny": true, + "ybins": { + "start": -0.5, + "end": 7.5, + "size": 2 + } + } + ], + "layout": { + "plot_bgcolor": "rgb(255, 0, 0)", + "xaxis": { + "range": [ + 0, + 2.3157894736842106 + ], + "autorange": true, + "type": "linear" + }, + "yaxis": { + "range": [ + -0.5, + 7.552631578947369 + ], + "autorange": true, + "type": "linear" + }, + "autosize": true + }, + "frames": [] +} diff --git a/dev/percy/histogram2d.json b/dev/percy/histogram2d.json new file mode 100644 index 000000000..48056d0b6 --- /dev/null +++ b/dev/percy/histogram2d.json @@ -0,0 +1,61 @@ +{ + "data": [ + { + "type": "histogram2d", + "mode": "markers", + "uid": "7cb332", + "x": [ + 1, + 2, + 3 + ], + "xsrc": "ints", + "y": [ + 1, + 2, + 3 + ], + "ysrc": "ints", + "autobinx": false, + "xbins": { + "start": 0.5, + "end": 9.5, + "size": 5, + "_dataSpan": 5 + }, + "autobiny": true, + "ybins": { + "start": -0.5, + "end": 9.5, + "size": 10, + "_dataSpan": 5 + }, + "zmin": 2, + "zmax": 4, + "zauto": true, + "cumulative": { + "enabled": true + } + } + ], + "layout": { + "xaxis": { + "type": "linear", + "range": [ + -0.5, + 9.5 + ], + "autorange": true + }, + "yaxis": { + "type": "linear", + "range": [ + -0.5, + 9.5 + ], + "autorange": true + }, + "autosize": true + }, + "frames": [] +} diff --git a/dev/percy/index.js b/dev/percy/index.js index 0290431f9..32a680630 100644 --- a/dev/percy/index.js +++ b/dev/percy/index.js @@ -1,3 +1,5 @@ import panelTest from './panelTest.json'; +import histogram from './histogram.json'; +import histogram2d from './histogram2d.json'; -export {panelTest}; +export {panelTest, histogram, histogram2d}; diff --git a/dev/percy/panelTest.json b/dev/percy/panelTest.json index 93bc6e705..ae6532910 100644 --- a/dev/percy/panelTest.json +++ b/dev/percy/panelTest.json @@ -126,7 +126,7 @@ } ], "xaxis": { - "type": "linear", + "type": "date", "range": [ 0.6919103739269605, 6.3080896260730395 @@ -147,6 +147,19 @@ 6.3080896260730395 ] }, + "rangeselector": { + "visible": true, + "buttons": [ + { + "label": "b1", + "step": "year" + }, + { + "label": "b2", + "step": "month" + } + ] + }, "showspikes": true }, "yaxis": { diff --git a/src/__percy__/panels.percy.js b/src/__percy__/panels.percy.js index c9b152986..e19a8b657 100644 --- a/src/__percy__/panels.percy.js +++ b/src/__percy__/panels.percy.js @@ -12,7 +12,12 @@ import './percy.css'; /** * To add more Percy tests - add a mock file to /dev/percy, add it to /dev/percy/index.js + * To specify which panels to test with the mock, add entry to panelsToTest, else all panels will be tested */ +const panelsToTest = { + histogram: ['GraphCreatePanel'], + histogram2d: ['GraphCreatePanel', 'StyleTracesPanel'], +}; const panelFixture = (Panel, group, name, data) => { return ( @@ -29,7 +34,11 @@ const panelFixture = (Panel, group, name, data) => { const snapshotWidth = 500; Object.keys(mocks).forEach(m => { - Object.keys(panels).forEach(p => { + const selectedPanels = panelsToTest[m] + ? panelsToTest[m] + : Object.keys(panels); + + selectedPanels.forEach(p => { const words = p.split(/(?=[A-Z])/); const panelGroup = words[0]; const panelName = words.slice(1, -1).join(' '); diff --git a/src/components/fields/derived.js b/src/components/fields/derived.js index c33bb3f6a..9f2af8c6c 100644 --- a/src/components/fields/derived.js +++ b/src/components/fields/derived.js @@ -4,6 +4,7 @@ import {UnconnectedFlaglist} from './Flaglist'; import {UnconnectedNumeric} from './Numeric'; import {UnconnectedAxisRangeValue} from './AxisRangeValue'; import {UnconnectedRadio} from './Radio'; +import Info from './Info'; import { connectToContainer, getAllAxes, @@ -144,67 +145,55 @@ export const ContourNumeric = connectToContainer(UnconnectedNumeric, { }, }); -export const TraceOrientation = connectToContainer(UnconnectedRadio, { +export const BinningNumeric = connectToContainer(UnconnectedNumeric, { modifyPlotProps: (props, context, plotProps) => { + const {fullContainer} = plotProps; if ( - context.container.type === 'box' && - plotProps.fullValue === 'h' && - context.container.y && - context.container.y.length !== 0 - ) { - context.updateContainer({ - y: null, - ysrc: null, - x: context.container.y, - xsrc: context.container.ysrc, - }); - } - - if ( - context.container.type === 'box' && - plotProps.fullValue === 'v' && - context.container.x && - context.container.x.length !== 0 + plotProps.isVisible && + fullContainer && + fullContainer[`autobin${props.axis}`] ) { - context.updateContainer({ - x: null, - xsrc: null, - y: context.container.x, - ysrc: context.container.xsrc, - }); + plotProps.isVisible = false; } + }, +}); - if ( - context.container.type === 'histogram' && - plotProps.fullValue === 'v' && - context.container.y && - context.container.y.length !== 0 - ) { - context.updateContainer({ - y: null, - ysrc: null, - ybins: null, - x: context.container.y, - xsrc: context.container.ysrc, - xbins: context.container.ybins, - }); - } +export const BinningDropdown = connectToContainer(UnconnectedDropdown, { + modifyPlotProps: (props, context, plotProps) => { + const {localize: _} = context; + plotProps.options = + plotProps.fullContainer.orientation === 'v' + ? [ + {label: _('Count X'), value: 'count'}, + {label: _('Sum Y'), value: 'sum'}, + {label: _('Average Y'), value: 'avg'}, + {label: _('Minimum Y'), value: 'min'}, + {label: _('Maximum Y'), value: 'max'}, + ] + : [ + {label: _('Count Y'), value: 'count'}, + {label: _('Sum X'), value: 'sum'}, + {label: _('Average X'), value: 'avg'}, + {label: _('Minimum X'), value: 'min'}, + {label: _('Maximum X'), value: 'max'}, + ]; + }, +}); - if ( - context.container.type === 'histogram' && - plotProps.fullValue === 'h' && - context.container.x && - context.container.x.length !== 0 - ) { - context.updateContainer({ - x: null, - xsrc: null, - xbins: null, - y: context.container.x, - ysrc: context.container.xsrc, - ybins: context.container.xbins, - }); - } +export const HistogramInfoVertical = connectToContainer(Info, { + modifyPlotProps: (props, context, plotProps) => { + plotProps.isVisible = + context.fullContainer.type === 'histogram' && + context.fullContainer.orientation === 'v'; + return plotProps; + }, +}); +export const HistogramInfoHorizontal = connectToContainer(Info, { + modifyPlotProps: (props, context, plotProps) => { + plotProps.isVisible = + context.fullContainer.type === 'histogram' && + context.fullContainer.orientation === 'h'; + return plotProps; }, }); diff --git a/src/default_panels/GraphCreatePanel.js b/src/default_panels/GraphCreatePanel.js index 390c67c61..330cd3403 100644 --- a/src/default_panels/GraphCreatePanel.js +++ b/src/default_panels/GraphCreatePanel.js @@ -14,6 +14,10 @@ import { Numeric, TraceTypeSection, } from '../components'; +import { + HistogramInfoVertical, + HistogramInfoHorizontal, +} from '../components/fields/derived'; const GraphCreatePanel = (props, {localize: _}) => { return ( @@ -27,6 +31,15 @@ const GraphCreatePanel = (props, {localize: _}) => { + + { }} attr="z" /> + + {_( + 'Note: in vertical orientation, X values are used for bins and Y values for weights.' + )} + + + {_( + 'Note: in horizontal orientation, Y Values are used for bins and X values for weights.' + )} + diff --git a/src/default_panels/StyleTracesPanel.js b/src/default_panels/StyleTracesPanel.js index ba48ac8cf..a306eb9a7 100644 --- a/src/default_panels/StyleTracesPanel.js +++ b/src/default_panels/StyleTracesPanel.js @@ -18,7 +18,6 @@ import { TraceAccordion, TraceTypeSection, TraceMarkerSection, - TraceOrientation, ColorscalePicker, HoverInfo, Dropdown, @@ -26,6 +25,7 @@ import { FontSelector, TextPosition, } from '../components'; +import {BinningNumeric, BinningDropdown} from '../components/fields/derived'; const StyleTracesPanel = (props, {localize: _}) => ( @@ -38,17 +38,48 @@ const StyleTracesPanel = (props, {localize: _}) => ( {label: _('Hide'), value: false}, ]} /> - + + + - - - + + + + + + ( + + + + + + + + + + + + + + + + +