Skip to content
1 change: 0 additions & 1 deletion frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down
54 changes: 53 additions & 1 deletion frontend/src2/charts/chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
92 changes: 92 additions & 0 deletions frontend/src2/charts/components/BubbleChartConfigForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<script setup lang="ts">
import { BubbleChartConfig } from '../../types/chart.types'
import { ColumnOption, Dimension, DimensionOption, Measure } from '../../types/query.types'
import CollapsibleSection from './CollapsibleSection.vue'
import MeasurePicker from './MeasurePicker.vue'
import DimensionPicker from './DimensionPicker.vue'

const props = defineProps<{
dimensions: DimensionOption[]
columnOptions: ColumnOption[]
}>()

const config = defineModel<BubbleChartConfig>({
required: true,
default: () => ({
xAxis: {} as Measure,
yAxis: {} as Measure,
size_column: {} as Measure,
dimension: {} as Dimension,
quadrant_column: {} as Dimension,
show_data_labels: false,
show_quadrants: false,
}),
})

if (!config.value.xAxis) {
config.value.xAxis = {} as Measure
}
if (!config.value.yAxis) {
config.value.yAxis = {} as Measure
}
if (!config.value.size_column) {
config.value.size_column = {} as Measure
}

</script>

<template>
<CollapsibleSection title="Setup">
<div class="flex flex-col gap-3 pt-1">
<MeasurePicker
label="X Axis"
v-model="config.xAxis"
:column-options="props.columnOptions"
/>

<MeasurePicker
label="Y Axis"
v-model="config.yAxis"
:column-options="props.columnOptions"
/>
<DimensionPicker
label="Color by"
v-model="config.quadrant_column!"
:options="props.dimensions"
@remove="config.quadrant_column = {} as Dimension"
/>
<MeasurePicker
label="Size Column"
v-model="config.size_column!"
:column-options="props.columnOptions"
@remove="config.size_column = {} as Measure"
/>
</div>
</CollapsibleSection>

<CollapsibleSection title="Options">
<div class="flex flex-col gap-2 pt-1">
<div class="flex flex-col gap-2">
<div class="flex flex-col gap-3">
<DimensionPicker
label="Name Column"
v-model="config.dimension!"
:options="props.dimensions"
@remove="config.dimension = {} as Dimension"
/>
</div>
<div
class="group flex flex-col items-between justify-between rounded py-2"
>
<div class=" gap-3">
<Toggle
v-model="config.show_data_labels"
label="Show Data Labels"
/>
</div>
</div>
</div>
</div>
</CollapsibleSection>

</template>
8 changes: 8 additions & 0 deletions frontend/src2/charts/components/ChartConfigForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { computed, inject } from 'vue'
import useQuery, { Query } from '../../query/query'
import {
BarChartConfig,
BubbleChartConfig,
DonutChartConfig,
FunnelChartConfig,
LineChartConfig,
Expand All @@ -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 }>()
Expand Down Expand Up @@ -82,4 +84,10 @@ const columnOptions = computed(() => chartQuery.value.result?.columnOptions || [
:dimensions="dimensions"
:column-options="columnOptions"
/>
<BubbleChartConfigForm
v-if="props.chart.doc.chart_type == 'Bubble'"
v-model="(props.chart.doc.config as BubbleChartConfig)"
:dimensions="dimensions"
:column-options="columnOptions"
/>
</template>
2 changes: 1 addition & 1 deletion frontend/src2/charts/components/ChartIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const icon = computed(() => {
return LineChart
case 'Row':
return BarChartHorizontal
case 'Scatter':
case 'Bubble':
return ScatterChart
case 'Area':
return AreaChart
Expand Down
5 changes: 5 additions & 0 deletions frontend/src2/charts/components/ChartRenderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
LineChartConfig,
MapChartConfig,
NumberChartConfig,
BubbleChartConfig,
} from '../../types/chart.types'
import { Chart } from '../chart'
import {
Expand All @@ -17,6 +18,7 @@ import {
getFunnelChartOptions,
getLineChartOptions,
getMapChartOptions,
getBubbleChartOptions,
} from '../helpers'
import { FIELDTYPES } from '../../helpers/constants.ts'
import { titleCase } from '../../helpers'
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions frontend/src2/charts/components/XAxisConfig.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<script setup lang="ts">
import { watchEffect } from 'vue'
import InlineFormControlLabel from '../../components/InlineFormControlLabel.vue'
import { AxisChartConfig } from '../../types/chart.types'
import { Dimension, DimensionOption } from '../../types/query.types'
import CollapsibleSection from './CollapsibleSection.vue'
import DimensionPicker from './DimensionPicker.vue'

const props = defineProps<{ dimensions: DimensionOption[] }>()
const props = defineProps<{ dimensions: DimensionOption[], showRotateLabels?: boolean}>()
const x_axis = defineModel<AxisChartConfig['x_axis']>({
required: true,
default: () => ({}),
Expand Down Expand Up @@ -35,6 +34,7 @@ watchEffect(() => {
@remove="x_axis.dimension = {} as Dimension"
/>
<FormControl
v-if="props.showRotateLabels"
label="Rotate Values"
type="select"
v-model="x_axis.label_rotation"
Expand Down
Loading