Skip to content

Commit a83e8e4

Browse files
authored
feat(explore): Smart default visualization (#90073)
Previously, we hard code in bar chart as the chart type for the default visualization. This has the consequence of the bar chart being persisted until the user explicitly changes the chart type. This introduces the ability to pick a default chart type based on the currently selected visualization. We default to bar charts for `count/count_unique/sum` and default to line charts otherwise. Closes EXP-103
1 parent 24a9f3d commit a83e8e4

File tree

13 files changed

+311
-373
lines changed

13 files changed

+311
-373
lines changed

static/app/utils/dedupeArray.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export function dedupeArray(values: string[]): string[] {
1+
export function dedupeArray(values: readonly string[]): string[] {
22
const deduped: string[] = [];
33
const seen = new Set();
44
values.forEach(s => {

static/app/views/explore/charts/index.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ import {TimeSeriesWidgetVisualization} from 'sentry/views/dashboards/widgets/tim
2424
import {Widget} from 'sentry/views/dashboards/widgets/widget/widget';
2525
import {WidgetExtrapolationFooter} from 'sentry/views/explore/charts/widgetExtrapolationFooter';
2626
import ChartContextMenu from 'sentry/views/explore/components/chartContextMenu';
27-
import type {Visualize} from 'sentry/views/explore/contexts/pageParamsContext/visualizes';
27+
import type {
28+
BaseVisualize,
29+
Visualize,
30+
} from 'sentry/views/explore/contexts/pageParamsContext/visualizes';
2831
import {useChartInterval} from 'sentry/views/explore/hooks/useChartInterval';
2932
import type {SamplingMode} from 'sentry/views/explore/hooks/useProgressiveQuery';
3033
import {useTopEvents} from 'sentry/views/explore/hooks/useTopEvents';
@@ -40,7 +43,7 @@ interface ExploreChartsProps {
4043
confidences: Confidence[];
4144
dataset: DiscoverDatasets;
4245
query: string;
43-
setVisualizes: (visualizes: Visualize[]) => void;
46+
setVisualizes: (visualizes: BaseVisualize[]) => void;
4447
timeseriesResult: ReturnType<typeof useSortedTimeSeries>;
4548
visualizes: Visualize[];
4649
hideContextMenu?: boolean;
@@ -164,8 +167,12 @@ export function ExploreCharts({
164167

165168
const handleChartTypeChange = useCallback(
166169
(chartType: ChartType, index: number) => {
167-
const newVisualizes = visualizes.slice();
168-
newVisualizes[index] = {...newVisualizes[index]!, chartType};
170+
const newVisualizes = visualizes.map((visualize, i) => {
171+
if (i === index) {
172+
visualize = visualize.replace({chartType});
173+
}
174+
return visualize.toJSON();
175+
});
169176
setVisualizes(newVisualizes);
170177
},
171178
[visualizes, setVisualizes]

static/app/views/explore/components/chartContextMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function ChartContextMenu({
2121
interval: string;
2222
query: string;
2323
visualizeIndex: number;
24-
visualizeYAxes: string[];
24+
visualizeYAxes: readonly string[];
2525
}) {
2626
const {addToDashboard} = useAddToDashboard();
2727
const organization = useOrganization();

static/app/views/explore/contexts/pageParamsContext/index.spec.tsx

Lines changed: 18 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
DEFAULT_VISUALIZATION,
2020
DEFAULT_VISUALIZATION_AGGREGATE,
2121
DEFAULT_VISUALIZATION_FIELD,
22+
Visualize,
2223
} from 'sentry/views/explore/contexts/pageParamsContext/visualizes';
2324
import {ChartType} from 'sentry/views/insights/common/components/chart';
2425

@@ -112,13 +113,7 @@ describe('PageParamsProvider', function () {
112113
mode: Mode.SAMPLES,
113114
query: '',
114115
sortBys: [{field: 'timestamp', kind: 'desc'}],
115-
visualizes: [
116-
{
117-
chartType: ChartType.BAR,
118-
label: 'A',
119-
yAxes: ['count(span.duration)'],
120-
},
121-
],
116+
visualizes: [new Visualize(['count(span.duration)'], 'A')],
122117
});
123118
});
124119

@@ -134,13 +129,7 @@ describe('PageParamsProvider', function () {
134129
mode: Mode.AGGREGATE,
135130
query: '',
136131
sortBys: [{field: 'count(span.self_time)', kind: 'asc'}],
137-
visualizes: [
138-
{
139-
chartType: ChartType.AREA,
140-
label: 'A',
141-
yAxes: ['count(span.self_time)'],
142-
},
143-
],
132+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
144133
});
145134
});
146135

@@ -156,13 +145,7 @@ describe('PageParamsProvider', function () {
156145
mode: Mode.AGGREGATE,
157146
query: '',
158147
sortBys: [{field: 'count(span.self_time)', kind: 'asc'}],
159-
visualizes: [
160-
{
161-
chartType: ChartType.AREA,
162-
label: 'A',
163-
yAxes: ['count(span.self_time)'],
164-
},
165-
],
148+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
166149
});
167150
});
168151

@@ -178,13 +161,7 @@ describe('PageParamsProvider', function () {
178161
mode: Mode.AGGREGATE,
179162
query: '',
180163
sortBys: [{field: 'count(span.self_time)', kind: 'asc'}],
181-
visualizes: [
182-
{
183-
chartType: ChartType.AREA,
184-
label: 'A',
185-
yAxes: ['count(span.self_time)'],
186-
},
187-
],
164+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
188165
});
189166
});
190167

@@ -200,13 +177,7 @@ describe('PageParamsProvider', function () {
200177
mode: Mode.AGGREGATE,
201178
query: '',
202179
sortBys: [{field: 'count(span.self_time)', kind: 'asc'}],
203-
visualizes: [
204-
{
205-
chartType: ChartType.AREA,
206-
label: 'A',
207-
yAxes: ['count(span.self_time)'],
208-
},
209-
],
180+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
210181
});
211182
});
212183

@@ -222,13 +193,7 @@ describe('PageParamsProvider', function () {
222193
mode: Mode.AGGREGATE,
223194
query: '',
224195
sortBys: [{field: 'count(span.self_time)', kind: 'asc'}],
225-
visualizes: [
226-
{
227-
chartType: ChartType.AREA,
228-
label: 'A',
229-
yAxes: ['count(span.self_time)'],
230-
},
231-
],
196+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
232197
});
233198
});
234199

@@ -244,13 +209,7 @@ describe('PageParamsProvider', function () {
244209
mode: Mode.SAMPLES,
245210
query: '',
246211
sortBys: [{field: 'timestamp', kind: 'desc'}],
247-
visualizes: [
248-
{
249-
chartType: ChartType.AREA,
250-
label: 'A',
251-
yAxes: ['count(span.self_time)'],
252-
},
253-
],
212+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
254213
});
255214
});
256215

@@ -271,13 +230,7 @@ describe('PageParamsProvider', function () {
271230
mode: Mode.SAMPLES,
272231
query: '',
273232
sortBys: [{field: 'timestamp', kind: 'desc'}],
274-
visualizes: [
275-
{
276-
chartType: ChartType.AREA,
277-
label: 'A',
278-
yAxes: ['count(span.self_time)'],
279-
},
280-
],
233+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
281234
});
282235
});
283236

@@ -293,13 +246,7 @@ describe('PageParamsProvider', function () {
293246
mode: Mode.AGGREGATE,
294247
query: 'foo:bar',
295248
sortBys: [{field: 'count(span.self_time)', kind: 'asc'}],
296-
visualizes: [
297-
{
298-
chartType: ChartType.AREA,
299-
label: 'A',
300-
yAxes: ['count(span.self_time)'],
301-
},
302-
],
249+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
303250
});
304251
});
305252

@@ -315,13 +262,7 @@ describe('PageParamsProvider', function () {
315262
mode: Mode.SAMPLES,
316263
query: '',
317264
sortBys: [{field: 'id', kind: 'desc'}],
318-
visualizes: [
319-
{
320-
chartType: ChartType.AREA,
321-
label: 'A',
322-
yAxes: ['count(span.self_time)'],
323-
},
324-
],
265+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
325266
});
326267
});
327268

@@ -337,13 +278,7 @@ describe('PageParamsProvider', function () {
337278
mode: Mode.SAMPLES,
338279
query: '',
339280
sortBys: [{field: 'timestamp', kind: 'desc'}],
340-
visualizes: [
341-
{
342-
chartType: ChartType.AREA,
343-
label: 'A',
344-
yAxes: ['count(span.self_time)'],
345-
},
346-
],
281+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
347282
});
348283
});
349284

@@ -369,11 +304,7 @@ describe('PageParamsProvider', function () {
369304
query: '',
370305
sortBys: [{field: 'max(span.duration)', kind: 'desc'}],
371306
visualizes: [
372-
{
373-
chartType: ChartType.AREA,
374-
label: 'A',
375-
yAxes: ['min(span.self_time)', 'max(span.duration)'],
376-
},
307+
new Visualize(['min(span.self_time)', 'max(span.duration)'], 'A', ChartType.AREA),
377308
],
378309
});
379310
});
@@ -400,11 +331,7 @@ describe('PageParamsProvider', function () {
400331
query: '',
401332
sortBys: [{field: 'min(span.self_time)', kind: 'desc'}],
402333
visualizes: [
403-
{
404-
chartType: ChartType.AREA,
405-
label: 'A',
406-
yAxes: ['min(span.self_time)', 'max(span.duration)'],
407-
},
334+
new Visualize(['min(span.self_time)', 'max(span.duration)'], 'A', ChartType.AREA),
408335
],
409336
});
410337
});
@@ -421,13 +348,7 @@ describe('PageParamsProvider', function () {
421348
mode: Mode.AGGREGATE,
422349
query: '',
423350
sortBys: [{field: 'sdk.name', kind: 'desc'}],
424-
visualizes: [
425-
{
426-
chartType: ChartType.AREA,
427-
label: 'A',
428-
yAxes: ['count(span.self_time)'],
429-
},
430-
],
351+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
431352
});
432353
});
433354

@@ -443,13 +364,7 @@ describe('PageParamsProvider', function () {
443364
mode: Mode.AGGREGATE,
444365
query: '',
445366
sortBys: [{field: 'count(span.self_time)', kind: 'desc'}],
446-
visualizes: [
447-
{
448-
chartType: ChartType.AREA,
449-
label: 'A',
450-
yAxes: ['count(span.self_time)'],
451-
},
452-
],
367+
visualizes: [new Visualize(['count(span.self_time)'], 'A', ChartType.AREA)],
453368
});
454369
});
455370

@@ -477,16 +392,8 @@ describe('PageParamsProvider', function () {
477392
query: '',
478393
sortBys: [{field: 'count(span.self_time)', kind: 'asc'}],
479394
visualizes: [
480-
{
481-
chartType: ChartType.AREA,
482-
label: 'A',
483-
yAxes: ['count(span.self_time)'],
484-
},
485-
{
486-
chartType: ChartType.LINE,
487-
label: 'B',
488-
yAxes: ['avg(span.duration)', 'avg(span.self_time)'],
489-
},
395+
new Visualize(['count(span.self_time)'], 'A', ChartType.AREA),
396+
new Visualize(['avg(span.duration)', 'avg(span.self_time)'], 'B', ChartType.LINE),
490397
],
491398
});
492399
});

0 commit comments

Comments
 (0)