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 @@