mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-09 17:57:06 +08:00
feat: add pie chart
This commit is contained in:
@@ -55,10 +55,10 @@ template:
|
||||
{{"type":"bar", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称", "value": "SQL 查询 x 轴的列(有别名用别名)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名)"}}}}
|
||||
必须从 SQL 查询列中提取“x”和“y”。
|
||||
- 如果需要折线图,则生成的 JSON 格式应为:
|
||||
{{"type":"line", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称","value": "x轴的SQL查询列(有别名用别名)"}}, "y": {{"name":"y轴的中文名称","value": "y轴的SQL查询列(有别名用别名)"}}}}
|
||||
{{"type":"line", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称","value": "SQL 查询 x 轴的列(有别名用别名)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名)"}}}}
|
||||
其中“x”和“y”必须从SQL查询列中提取。
|
||||
- 如果需要饼图,则生成的 JSON 格式应为:
|
||||
{{"type":"pie", "title": "标题", "columns": [{{"name":"中文字段名1","value":"SQL查询列1(有别名用别名)"}},{{"name":"中文字段名2","value":"SQL查询列2(有别名用别名)"}}]}}
|
||||
{{"type":"pie", "title": "标题", "axis": {{"y": {{"值轴的中文名称","value":"SQL 查询数值的列(有别名用别名)"}}, "series": {{"name":"分类的中文名称","value":"SQL 查询分类的列(有别名用别名)"}}}}
|
||||
其中“column”必须从SQL查询列中提取。
|
||||
- 如果答案未知或者与生成JSON无关,则生成的 JSON 格式应为:
|
||||
{{"type":"error", "reason": "抱歉,我无法回答您的问题。"}}
|
||||
|
||||
@@ -5,6 +5,7 @@ import {computed, nextTick, ref} from "vue";
|
||||
import type {TabsPaneContext} from 'element-plus-secondary'
|
||||
import {Loading} from "@element-plus/icons-vue";
|
||||
import Component from "./component/Component.vue"
|
||||
import type {ChartTypes} from "@/views/chat/component/BaseChart.ts";
|
||||
|
||||
const props = defineProps<{
|
||||
message?: ChatMessage
|
||||
@@ -43,9 +44,13 @@ const dataObject = computed<{
|
||||
})
|
||||
|
||||
const chartObject = computed<{
|
||||
type: "table" | "bar" | "line" | "pie"
|
||||
type: ChartTypes
|
||||
title: string
|
||||
axis: { x: { name: string, value: string }, y: { name: string, value: string } }
|
||||
axis: {
|
||||
x: { name: string, value: string },
|
||||
y: { name: string, value: string },
|
||||
series: { name: string, value: string }
|
||||
}
|
||||
columns: Array<{ name: string, value: string }>
|
||||
}>(() => {
|
||||
if (props.message?.record?.chart) {
|
||||
@@ -66,10 +71,16 @@ const yAxis = computed(() => {
|
||||
}
|
||||
return []
|
||||
})
|
||||
const series = computed(() => {
|
||||
if (chartObject.value?.axis?.series) {
|
||||
return [chartObject.value.axis.series]
|
||||
}
|
||||
return []
|
||||
})
|
||||
|
||||
const currentChartType = ref<"table" | "bar" | 'column' | "line" | "pie" | undefined>(undefined)
|
||||
const currentChartType = ref<ChartTypes | undefined>(undefined)
|
||||
|
||||
const chartType = computed<"table" | "bar" | 'column' | "line" | "pie">({
|
||||
const chartType = computed<ChartTypes>({
|
||||
get() {
|
||||
if (currentChartType.value) {
|
||||
return currentChartType.value
|
||||
@@ -158,6 +169,7 @@ function onTypeChange(type: string) {
|
||||
:columns="chartObject?.columns"
|
||||
:x="xAxis"
|
||||
:y="yAxis"
|
||||
:series="series"
|
||||
:data="dataObject.data"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -189,6 +201,6 @@ function onTypeChange(type: string) {
|
||||
|
||||
.chart-base-container {
|
||||
padding: 20px;
|
||||
background: rgba(224,224,226,0.29);
|
||||
background: rgba(224, 224, 226, 0.29);
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +1,27 @@
|
||||
export interface ChartAxis {
|
||||
name: string,
|
||||
value: string,
|
||||
type?: 'x' | 'y' | 'series'
|
||||
}
|
||||
|
||||
export interface ChartData {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export type ChartTypes = "table" | "bar" | 'column' | "line" | "pie"
|
||||
|
||||
export abstract class BaseChart {
|
||||
id: string;
|
||||
_name: string = 'base-chart';
|
||||
axis: Array<{ name: string, value: string, type?: 'x' | 'y' }> = [];
|
||||
data: Array<{ [key: string]: any }> = [];
|
||||
axis: Array<ChartAxis> = [];
|
||||
data: Array<ChartData> = [];
|
||||
|
||||
constructor(id: string, name: string) {
|
||||
this.id = id;
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
init(axis: Array<{ name: string, value: string, type?: 'x' | 'y' }>, data: Array<{ [key: string]: any }>): void {
|
||||
init(axis: Array<ChartAxis>, data: Array<ChartData>): void {
|
||||
this.axis = axis;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import {computed, onMounted, onUnmounted} from "vue";
|
||||
import {getChartInstance} from "@/views/chat/component/index.ts";
|
||||
import type {BaseChart} from "@/views/chat/component/BaseChart.ts";
|
||||
import type {BaseChart, ChartAxis, ChartData} from "@/views/chat/component/BaseChart.ts";
|
||||
|
||||
const params = withDefaults(defineProps<{
|
||||
id: string | number
|
||||
type: string
|
||||
data?: Array<{ [key: string]: any }>
|
||||
columns?: Array<{ name: string, value: string }>
|
||||
x?: Array<{ name: string, value: string }>
|
||||
y?: Array<{ name: string, value: string }>
|
||||
data?: Array<ChartData>
|
||||
columns?: Array<ChartAxis>
|
||||
x?: Array<ChartAxis>
|
||||
y?: Array<ChartAxis>
|
||||
series?: Array<ChartAxis>
|
||||
}>(), {
|
||||
data: () => [],
|
||||
columns: () => [],
|
||||
x: () => [],
|
||||
y: () => [],
|
||||
series: () => [],
|
||||
})
|
||||
|
||||
const chartId = computed(() => {
|
||||
@@ -22,7 +24,7 @@ const chartId = computed(() => {
|
||||
})
|
||||
|
||||
const axis = computed(() => {
|
||||
const _list: Array<{ name: string, value: string, type?: 'x' | 'y' }> = []
|
||||
const _list: Array<ChartAxis> = []
|
||||
params.columns.forEach(column => {
|
||||
_list.push({name: column.name, value: column.value})
|
||||
})
|
||||
@@ -32,6 +34,9 @@ const axis = computed(() => {
|
||||
params.y.forEach(column => {
|
||||
_list.push({name: column.name, value: column.value, type: 'y'})
|
||||
})
|
||||
params.series.forEach(column => {
|
||||
_list.push({name: column.name, value: column.value, type: 'series'})
|
||||
})
|
||||
return _list
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {BaseG2Chart} from "@/views/chat/component/BaseG2Chart.ts";
|
||||
import type {ChartAxis, ChartData} from "@/views/chat/component/BaseChart.ts";
|
||||
|
||||
export class Bar extends BaseG2Chart {
|
||||
|
||||
@@ -6,7 +7,7 @@ export class Bar extends BaseG2Chart {
|
||||
super(id, "bar");
|
||||
}
|
||||
|
||||
init(axis: Array<{ name: string; value: string; type: "x" | "y" }>, data: Array<{ [key: string]: any }>) {
|
||||
init(axis: Array<ChartAxis>, data: Array<ChartData>) {
|
||||
super.init(axis, data);
|
||||
const x = this.axis.filter(item => item.type === "x");
|
||||
const y = this.axis.filter(item => item.type === "y");
|
||||
@@ -26,7 +27,7 @@ export class Bar extends BaseG2Chart {
|
||||
.scale('y', {
|
||||
nice: true,
|
||||
})
|
||||
.interaction('elementHighlight', { background: true });
|
||||
.interaction('elementHighlight', {background: true});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {BaseG2Chart} from "@/views/chat/component/BaseG2Chart.ts";
|
||||
import type {ChartAxis, ChartData} from "@/views/chat/component/BaseChart.ts";
|
||||
|
||||
export class Column extends BaseG2Chart {
|
||||
|
||||
@@ -6,7 +7,7 @@ export class Column extends BaseG2Chart {
|
||||
super(id, "column");
|
||||
}
|
||||
|
||||
init(axis: Array<{ name: string; value: string; type: "x" | "y" }>, data: Array<{ [key: string]: any }>) {
|
||||
init(axis: Array<ChartAxis>, data: Array<ChartData>) {
|
||||
super.init(axis, data);
|
||||
|
||||
const x = this.axis.filter(item => item.type === "x");
|
||||
@@ -26,7 +27,7 @@ export class Column extends BaseG2Chart {
|
||||
.scale('y', {
|
||||
nice: true,
|
||||
})
|
||||
.interaction('elementHighlight', { background: true });
|
||||
.interaction('elementHighlight', {background: true});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {BaseG2Chart} from "@/views/chat/component/BaseG2Chart.ts";
|
||||
import type {ChartAxis, ChartData} from "@/views/chat/component/BaseChart.ts";
|
||||
|
||||
export class Line extends BaseG2Chart {
|
||||
|
||||
@@ -6,7 +7,7 @@ export class Line extends BaseG2Chart {
|
||||
super(id, "line");
|
||||
}
|
||||
|
||||
init(axis: Array<{ name: string; value: string; type: "x" | "y" }>, data: Array<{ [key: string]: any }>) {
|
||||
init(axis: Array<ChartAxis>, data: Array<ChartData>) {
|
||||
super.init(axis, data);
|
||||
|
||||
const x = this.axis.filter(item => item.type === "x");
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import {BaseG2Chart} from "@/views/chat/component/BaseG2Chart.ts";
|
||||
import type {ChartAxis, ChartData} from "@/views/chat/component/BaseChart.ts";
|
||||
|
||||
export class Pie extends BaseG2Chart {
|
||||
|
||||
constructor(id: string) {
|
||||
super(id, "pie");
|
||||
}
|
||||
|
||||
init(axis: Array<ChartAxis>, data: Array<ChartData>) {
|
||||
super.init(axis, data);
|
||||
const y = this.axis.filter(item => item.type === "y");
|
||||
const series = this.axis.filter(item => item.type === "series");
|
||||
|
||||
if (series.length == 0 || y.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.chart.coordinate({type: 'theta', outerRadius: 0.8});
|
||||
|
||||
this.chart?.interval()
|
||||
.transform({type: 'stackY'})
|
||||
.data(data)
|
||||
.encode('y', y[0].value)
|
||||
.encode('color', series[0].value)
|
||||
.legend('color', {position: 'bottom', layout: {justifyContent: 'center'}})
|
||||
;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import {BaseChart} from "@/views/chat/component/BaseChart.ts";
|
||||
import {BaseChart, type ChartAxis, type ChartData} from "@/views/chat/component/BaseChart.ts";
|
||||
import {TableSheet, type S2Options, type S2DataConfig, type S2MountContainer} from "@antv/s2";
|
||||
import {debounce} from "lodash-es";
|
||||
|
||||
@@ -33,7 +33,7 @@ export class Table extends BaseChart {
|
||||
}
|
||||
}
|
||||
|
||||
init(axis: Array<{ name: string; value: string; type: "x" | "y" }>, data: Array<{ [key: string]: any }>) {
|
||||
init(axis: Array<ChartAxis>, data: Array<ChartData>) {
|
||||
super.init(axis, data);
|
||||
|
||||
const s2DataConfig: S2DataConfig = {
|
||||
|
||||
@@ -3,13 +3,14 @@ import {Bar} from "@/views/chat/component/charts/Bar.ts";
|
||||
import {Column} from "@/views/chat/component/charts/Column.ts";
|
||||
import {Line} from "@/views/chat/component/charts/Line.ts";
|
||||
import {Table} from "@/views/chat/component/charts/Table.ts";
|
||||
import {Pie} from "@/views/chat/component/charts/Pie.ts";
|
||||
|
||||
const CHART_TYPE_MAP: { [key: string]: any } = {
|
||||
"table": Table,
|
||||
"column": Column,
|
||||
"bar": Bar,
|
||||
"line": Line,
|
||||
"pie": undefined
|
||||
"pie": Pie
|
||||
}
|
||||
|
||||
const isParent = (type: any, parentType: any) => {
|
||||
|
||||
Reference in New Issue
Block a user