1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-10 23:50:12 +00:00

Display chart in the chart widget

This commit is contained in:
Petr Stribny 2025-02-14 09:56:59 +01:00
parent c1afd69ac9
commit c72879d6f3
5 changed files with 152 additions and 2 deletions
enterprise/web-frontend/modules/baserow_enterprise
assets/scss/components
dashboard/components/widget

View file

@ -20,3 +20,4 @@
@import 'oidc_auth_link';
@import 'dashboard_chart_widget';
@import 'aggregation_series_form';
@import 'chart';

View file

@ -0,0 +1,3 @@
.chart {
max-height: 320px;
}

View file

@ -1,4 +1,3 @@
.dashboard-chart-widget {
padding: 0 24px 24px;
}

View file

@ -0,0 +1,144 @@
<template>
<Bar id="chart-id" :options="chartOptions" :data="chartData" class="chart" />
</template>
<script>
import { Bar } from 'vue-chartjs'
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
BarElement,
LineElement,
CategoryScale,
LinearScale,
PointElement,
} from 'chart.js'
ChartJS.register(
Title,
Tooltip,
Legend,
BarElement,
CategoryScale,
LinearScale,
PointElement,
LineElement
)
export default {
name: 'Chart',
components: { Bar },
props: {
dataSource: {
type: Object,
required: true,
},
dataSourceData: {
type: Object,
required: true,
},
},
computed: {
chartOptions() {
return {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
align: 'start',
position: 'bottom',
},
},
}
},
result() {
return this.dataSourceData.result
},
chartData() {
if (!this.result) {
return {
datasets: [],
}
}
if (this.dataSource.aggregation_group_bys?.length === 0) {
return this.chartDataNoGrouping
}
return this.chartDataGrouping
},
chartDataGrouping() {
const groupByFieldId = this.dataSource.aggregation_group_bys[0].field_id
const primaryField = Object.values(
this.dataSource.schema.properties
).find((item) => item.metadata?.primary === true)
const labels = this.result.map((item) => {
if (item[`field_${groupByFieldId}`]) {
return item[`field_${groupByFieldId}`]
}
return item[`field_${primaryField.metadata.id}`]
})
const datasets = []
for (const [index, series] of this.seriesConfig.entries()) {
const seriesData = this.result.map((item) => {
return item[series.fieldName]
})
const label = this.getLabel(series.fieldName, series.aggregationType)
datasets.push({
data: seriesData,
label,
backgroundColor: this.chartColors[index],
})
}
return {
labels,
datasets,
}
},
chartDataNoGrouping() {
const labels = ['']
const datasets = []
for (const [index, series] of this.seriesConfig.entries()) {
const seriesData = [this.result[series.fieldName]]
const label = this.getLabel(series.fieldName, series.aggregationType)
datasets.push({
data: seriesData,
label,
backgroundColor: this.chartColors[index],
})
}
return {
labels,
datasets,
}
},
seriesConfig() {
return this.dataSource.aggregation_series.map((item) => {
return {
fieldName: `field_${item.field_id}`,
aggregationType: item.aggregation_type,
}
})
},
chartColors() {
return ['#4E5CFE', '#2BC3F1', '#FFC744', '#E26AB0', '#3E4ACB']
},
},
methods: {
getFieldTitle(fieldName) {
return this.dataSource.schema.properties[fieldName].title
},
getAggregationTitle(aggregationType) {
return this.$registry.get('viewAggregation', aggregationType).getName()
},
getLabel(fieldName, aggregationType) {
let label = this.getAggregationTitle(aggregationType)
if (fieldName) {
label = `${this.getFieldTitle(fieldName)} (${label})`
}
return label
},
},
}
</script>

View file

@ -31,15 +31,18 @@
@delete-widget="$emit('delete-widget', $event)"
></WidgetContextMenu>
</div>
<Chart :data-source="dataSource" :data-source-data="dataForDataSource">
</Chart>
</div>
</template>
<script>
import WidgetContextMenu from '@baserow/modules/dashboard/components/widget/WidgetContextMenu'
import Chart from '@baserow_enterprise/dashboard/components/widget/Chart'
export default {
name: 'ChartWidget',
components: { WidgetContextMenu },
components: { WidgetContextMenu, Chart },
props: {
dashboard: {
type: Object,