Skip to content

Commit 14a8ce8

Browse files
authored
Merge pull request #496 from plotly/histogram-features
Add histogram features
2 parents 0c18f2c + f6d2d24 commit 14a8ce8

File tree

9 files changed

+301
-69
lines changed

9 files changed

+301
-69
lines changed

dev/percy/histogram.json

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"data": [
3+
{
4+
"type": "histogram",
5+
"mode": "markers",
6+
"uid": "dcb598",
7+
"x": [
8+
1,
9+
2,
10+
3,
11+
4,
12+
5,
13+
6
14+
],
15+
"xsrc": "ints",
16+
"autobinx": true,
17+
"xbins": {
18+
"start": -0.5,
19+
"end": 7.5,
20+
"size": 2
21+
},
22+
"y": [
23+
2,
24+
1,
25+
3,
26+
5,
27+
4,
28+
6
29+
],
30+
"ysrc": "jagged ints",
31+
"error_x": {
32+
"visible": true,
33+
"symmetric": true
34+
},
35+
"error_y": {
36+
"visible": true,
37+
"symmetric": false
38+
},
39+
"orientation": "v",
40+
"autobiny": true,
41+
"ybins": {
42+
"start": -0.5,
43+
"end": 7.5,
44+
"size": 2
45+
}
46+
}
47+
],
48+
"layout": {
49+
"plot_bgcolor": "rgb(255, 0, 0)",
50+
"xaxis": {
51+
"range": [
52+
0,
53+
2.3157894736842106
54+
],
55+
"autorange": true,
56+
"type": "linear"
57+
},
58+
"yaxis": {
59+
"range": [
60+
-0.5,
61+
7.552631578947369
62+
],
63+
"autorange": true,
64+
"type": "linear"
65+
},
66+
"autosize": true
67+
},
68+
"frames": []
69+
}

dev/percy/histogram2d.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"data": [
3+
{
4+
"type": "histogram2d",
5+
"mode": "markers",
6+
"uid": "7cb332",
7+
"x": [
8+
1,
9+
2,
10+
3
11+
],
12+
"xsrc": "ints",
13+
"y": [
14+
1,
15+
2,
16+
3
17+
],
18+
"ysrc": "ints",
19+
"autobinx": false,
20+
"xbins": {
21+
"start": 0.5,
22+
"end": 9.5,
23+
"size": 5,
24+
"_dataSpan": 5
25+
},
26+
"autobiny": true,
27+
"ybins": {
28+
"start": -0.5,
29+
"end": 9.5,
30+
"size": 10,
31+
"_dataSpan": 5
32+
},
33+
"zmin": 2,
34+
"zmax": 4,
35+
"zauto": true,
36+
"cumulative": {
37+
"enabled": true
38+
}
39+
}
40+
],
41+
"layout": {
42+
"xaxis": {
43+
"type": "linear",
44+
"range": [
45+
-0.5,
46+
9.5
47+
],
48+
"autorange": true
49+
},
50+
"yaxis": {
51+
"type": "linear",
52+
"range": [
53+
-0.5,
54+
9.5
55+
],
56+
"autorange": true
57+
},
58+
"autosize": true
59+
},
60+
"frames": []
61+
}

dev/percy/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
import panelTest from './panelTest.json';
2+
import histogram from './histogram.json';
3+
import histogram2d from './histogram2d.json';
24

3-
export {panelTest};
5+
export {panelTest, histogram, histogram2d};

dev/percy/panelTest.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
}
127127
],
128128
"xaxis": {
129-
"type": "linear",
129+
"type": "date",
130130
"range": [
131131
0.6919103739269605,
132132
6.3080896260730395
@@ -147,6 +147,19 @@
147147
6.3080896260730395
148148
]
149149
},
150+
"rangeselector": {
151+
"visible": true,
152+
"buttons": [
153+
{
154+
"label": "b1",
155+
"step": "year"
156+
},
157+
{
158+
"label": "b2",
159+
"step": "month"
160+
}
161+
]
162+
},
150163
"showspikes": true
151164
},
152165
"yaxis": {

src/__percy__/panels.percy.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ import './percy.css';
1212

1313
/**
1414
* To add more Percy tests - add a mock file to /dev/percy, add it to /dev/percy/index.js
15+
* To specify which panels to test with the mock, add entry to panelsToTest, else all panels will be tested
1516
*/
17+
const panelsToTest = {
18+
histogram: ['GraphCreatePanel'],
19+
histogram2d: ['GraphCreatePanel', 'StyleTracesPanel'],
20+
};
1621

1722
const panelFixture = (Panel, group, name, data) => {
1823
return (
@@ -29,7 +34,11 @@ const panelFixture = (Panel, group, name, data) => {
2934
const snapshotWidth = 500;
3035

3136
Object.keys(mocks).forEach(m => {
32-
Object.keys(panels).forEach(p => {
37+
const selectedPanels = panelsToTest[m]
38+
? panelsToTest[m]
39+
: Object.keys(panels);
40+
41+
selectedPanels.forEach(p => {
3342
const words = p.split(/(?=[A-Z])/);
3443
const panelGroup = words[0];
3544
const panelName = words.slice(1, -1).join(' ');

src/components/fields/derived.js

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {UnconnectedFlaglist} from './Flaglist';
44
import {UnconnectedNumeric} from './Numeric';
55
import {UnconnectedAxisRangeValue} from './AxisRangeValue';
66
import {UnconnectedRadio} from './Radio';
7+
import Info from './Info';
78
import {
89
connectToContainer,
910
getAllAxes,
@@ -144,67 +145,55 @@ export const ContourNumeric = connectToContainer(UnconnectedNumeric, {
144145
},
145146
});
146147

147-
export const TraceOrientation = connectToContainer(UnconnectedRadio, {
148+
export const BinningNumeric = connectToContainer(UnconnectedNumeric, {
148149
modifyPlotProps: (props, context, plotProps) => {
150+
const {fullContainer} = plotProps;
149151
if (
150-
context.container.type === 'box' &&
151-
plotProps.fullValue === 'h' &&
152-
context.container.y &&
153-
context.container.y.length !== 0
154-
) {
155-
context.updateContainer({
156-
y: null,
157-
ysrc: null,
158-
x: context.container.y,
159-
xsrc: context.container.ysrc,
160-
});
161-
}
162-
163-
if (
164-
context.container.type === 'box' &&
165-
plotProps.fullValue === 'v' &&
166-
context.container.x &&
167-
context.container.x.length !== 0
152+
plotProps.isVisible &&
153+
fullContainer &&
154+
fullContainer[`autobin${props.axis}`]
168155
) {
169-
context.updateContainer({
170-
x: null,
171-
xsrc: null,
172-
y: context.container.x,
173-
ysrc: context.container.xsrc,
174-
});
156+
plotProps.isVisible = false;
175157
}
158+
},
159+
});
176160

177-
if (
178-
context.container.type === 'histogram' &&
179-
plotProps.fullValue === 'v' &&
180-
context.container.y &&
181-
context.container.y.length !== 0
182-
) {
183-
context.updateContainer({
184-
y: null,
185-
ysrc: null,
186-
ybins: null,
187-
x: context.container.y,
188-
xsrc: context.container.ysrc,
189-
xbins: context.container.ybins,
190-
});
191-
}
161+
export const BinningDropdown = connectToContainer(UnconnectedDropdown, {
162+
modifyPlotProps: (props, context, plotProps) => {
163+
const {localize: _} = context;
164+
plotProps.options =
165+
plotProps.fullContainer.orientation === 'v'
166+
? [
167+
{label: _('Count X'), value: 'count'},
168+
{label: _('Sum Y'), value: 'sum'},
169+
{label: _('Average Y'), value: 'avg'},
170+
{label: _('Minimum Y'), value: 'min'},
171+
{label: _('Maximum Y'), value: 'max'},
172+
]
173+
: [
174+
{label: _('Count Y'), value: 'count'},
175+
{label: _('Sum X'), value: 'sum'},
176+
{label: _('Average X'), value: 'avg'},
177+
{label: _('Minimum X'), value: 'min'},
178+
{label: _('Maximum X'), value: 'max'},
179+
];
180+
},
181+
});
192182

193-
if (
194-
context.container.type === 'histogram' &&
195-
plotProps.fullValue === 'h' &&
196-
context.container.x &&
197-
context.container.x.length !== 0
198-
) {
199-
context.updateContainer({
200-
x: null,
201-
xsrc: null,
202-
xbins: null,
203-
y: context.container.x,
204-
ysrc: context.container.xsrc,
205-
ybins: context.container.xbins,
206-
});
207-
}
183+
export const HistogramInfoVertical = connectToContainer(Info, {
184+
modifyPlotProps: (props, context, plotProps) => {
185+
plotProps.isVisible =
186+
context.fullContainer.type === 'histogram' &&
187+
context.fullContainer.orientation === 'v';
188+
return plotProps;
189+
},
190+
});
191+
export const HistogramInfoHorizontal = connectToContainer(Info, {
192+
modifyPlotProps: (props, context, plotProps) => {
193+
plotProps.isVisible =
194+
context.fullContainer.type === 'histogram' &&
195+
context.fullContainer.orientation === 'h';
196+
return plotProps;
208197
},
209198
});
210199

src/default_panels/GraphCreatePanel.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ import {
1414
Numeric,
1515
TraceTypeSection,
1616
} from '../components';
17+
import {
18+
HistogramInfoVertical,
19+
HistogramInfoHorizontal,
20+
} from '../components/fields/derived';
1721

1822
const GraphCreatePanel = (props, {localize: _}) => {
1923
return (
@@ -27,6 +31,15 @@ const GraphCreatePanel = (props, {localize: _}) => {
2731
<DataSelector label={_('Locations')} attr="locations" />
2832
<DataSelector label={_('Latitude')} attr="lat" />
2933
<DataSelector label={_('Longitude')} attr="lon" />
34+
<Radio
35+
label={_('Orientation')}
36+
attr="orientation"
37+
options={[
38+
{label: _('Vertical'), value: 'v'},
39+
{label: _('Horizontal'), value: 'h'},
40+
]}
41+
/>
42+
3043
<DataSelector
3144
label={{
3245
histogram2d: _('X Values'),
@@ -51,6 +64,16 @@ const GraphCreatePanel = (props, {localize: _}) => {
5164
}}
5265
attr="z"
5366
/>
67+
<HistogramInfoVertical>
68+
{_(
69+
'Note: in vertical orientation, X values are used for bins and Y values for weights.'
70+
)}
71+
</HistogramInfoVertical>
72+
<HistogramInfoHorizontal>
73+
{_(
74+
'Note: in horizontal orientation, Y Values are used for bins and X values for weights.'
75+
)}
76+
</HistogramInfoHorizontal>
5477
<DataSelector label={_('I (Optional)')} attr="i" />
5578
<DataSelector label={_('J (Optional)')} attr="j" />
5679
<DataSelector label={_('K (Optional)')} attr="k" />

0 commit comments

Comments
 (0)