diff --git a/frontend/components.d.ts b/frontend/components.d.ts index fc4a4af74..55b378c0f 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -46,7 +46,6 @@ declare module 'vue' { ListFilter: typeof import('./src/components/ListFilter/ListFilter.vue')['default'] ListPicker: typeof import('./src/components/Controls/ListPicker.vue')['default'] LoginBox: typeof import('./src/components/LoginBox.vue')['default'] - LucideChevronRight: typeof import('~icons/lucide/chevron-right')['default'] NestedPopover: typeof import('./src/components/ListFilter/NestedPopover.vue')['default'] NewDialogWithTypes: typeof import('./src/components/NewDialogWithTypes.vue')['default'] PageBreadcrumbs: typeof import('./src/components/PageBreadcrumbs.vue')['default'] diff --git a/frontend/src2/charts/chart.ts b/frontend/src2/charts/chart.ts index b3684240d..a6e036ef3 100644 --- a/frontend/src2/charts/chart.ts +++ b/frontend/src2/charts/chart.ts @@ -19,9 +19,9 @@ import { DonutChartConfig, MapChartConfig, NumberChartConfig, + BubbleChartConfig, TableChartConfig, } from '../types/chart.types' -import { AdhocFilters, Dimension, Measure } from '../types/query.types' import { InsightsChartv3 } from '../types/workbook.types' import useWorkbook, { getLinkedQueries } from '../workbook/workbook' import { handleOldXAxisConfig, handleOldYAxisConfig, setDimensionNames } from './helpers' @@ -176,6 +176,22 @@ function makeChart(name: string) { } } + if (chart.doc.chart_type === 'Bubble') { + const config = chart.doc.config as BubbleChartConfig + if (!config.xAxis?.measure_name) { + messages.push({ + variant: 'error', + message: 'X-axis is required', + }) + } + if (!config.yAxis?.measure_name) { + messages.push({ + variant: 'error', + message: 'Y-axis is required', + }) + } + } + return !messages.length } @@ -212,6 +228,10 @@ function makeChart(name: string) { if (chart.doc.chart_type === 'Map') { addMapChartOperation(query) } + + if (chart.doc.chart_type === 'Bubble') { + addBubbleChartOperation(query) + } } function addAxisChartOperation(query: Query) { @@ -291,6 +311,38 @@ function makeChart(name: string) { }) } + function addBubbleChartOperation(query: Query) { + const config = chart.doc.config as BubbleChartConfig + + const dimensions: any[] = [] + const measures: any[] = [] + + if (config.xAxis?.measure_name) { + measures.push(config.xAxis) + } + + if (config.yAxis?.measure_name) { + measures.push(config.yAxis) + } + + if (config.size_column?.measure_name) { + measures.push(config.size_column) + } + + if (config.dimension?.column_name) { + dimensions.push(config.dimension) + } + + if (config.quadrant_column?.column_name) { + dimensions.push(config.quadrant_column) + } + + query.addSummarize({ + measures: measures, + dimensions: dimensions, + }) + } + function addOrderByOperation(query: Query) { chart.doc.config.order_by.forEach((sort) => { if (sort.column.column_name && sort.direction) { diff --git a/frontend/src2/charts/components/BubbleChartConfigForm.vue b/frontend/src2/charts/components/BubbleChartConfigForm.vue new file mode 100644 index 000000000..c61402f5b --- /dev/null +++ b/frontend/src2/charts/components/BubbleChartConfigForm.vue @@ -0,0 +1,92 @@ + + + diff --git a/frontend/src2/charts/components/ChartConfigForm.vue b/frontend/src2/charts/components/ChartConfigForm.vue index 423277f2c..18eb5f319 100644 --- a/frontend/src2/charts/components/ChartConfigForm.vue +++ b/frontend/src2/charts/components/ChartConfigForm.vue @@ -3,6 +3,7 @@ import { computed, inject } from 'vue' import useQuery, { Query } from '../../query/query' import { BarChartConfig, + BubbleChartConfig, DonutChartConfig, FunnelChartConfig, LineChartConfig, @@ -18,6 +19,7 @@ import FunnelChartConfigForm from './FunnelChartConfigForm.vue' import LineChartConfigForm from './LineChartConfigForm.vue' import MapChartConfigForm from './MapChartConfigForm.vue' import NumberChartConfigForm from './NumberChartConfigForm.vue' +import BubbleChartConfigForm from './BubbleChartConfigForm.vue' import TableChartConfigForm from './TableChartConfigForm.vue' const props = defineProps<{ chart: Chart }>() @@ -82,4 +84,10 @@ const columnOptions = computed(() => chartQuery.value.result?.columnOptions || [ :dimensions="dimensions" :column-options="columnOptions" /> + diff --git a/frontend/src2/charts/components/ChartIcon.vue b/frontend/src2/charts/components/ChartIcon.vue index 6461c5e75..02cce655e 100644 --- a/frontend/src2/charts/components/ChartIcon.vue +++ b/frontend/src2/charts/components/ChartIcon.vue @@ -24,7 +24,7 @@ const icon = computed(() => { return LineChart case 'Row': return BarChartHorizontal - case 'Scatter': + case 'Bubble': return ScatterChart case 'Area': return AreaChart diff --git a/frontend/src2/charts/components/ChartRenderer.vue b/frontend/src2/charts/components/ChartRenderer.vue index cfb21f7a4..7816fc010 100644 --- a/frontend/src2/charts/components/ChartRenderer.vue +++ b/frontend/src2/charts/components/ChartRenderer.vue @@ -9,6 +9,7 @@ import { LineChartConfig, MapChartConfig, NumberChartConfig, + BubbleChartConfig, } from '../../types/chart.types' import { Chart } from '../chart' import { @@ -17,6 +18,7 @@ import { getFunnelChartOptions, getLineChartOptions, getMapChartOptions, + getBubbleChartOptions, } from '../helpers' import { FIELDTYPES } from '../../helpers/constants.ts' import { titleCase } from '../../helpers' @@ -56,6 +58,9 @@ const eChartOptions = computed(() => { if (chart_type.value === 'Map') { return getMapChartOptions(config.value as MapChartConfig, result.value) } + if (chart_type.value === 'Bubble') { + return getBubbleChartOptions(config.value as BubbleChartConfig, result.value) + } }) const showDrillDown = ref(false) diff --git a/frontend/src2/charts/components/XAxisConfig.vue b/frontend/src2/charts/components/XAxisConfig.vue index 08a292ffd..19af9f503 100644 --- a/frontend/src2/charts/components/XAxisConfig.vue +++ b/frontend/src2/charts/components/XAxisConfig.vue @@ -1,12 +1,11 @@