Skip to content

Commit a8abd2a

Browse files
committed
feat: add thousands separator settings
1 parent dc2b078 commit a8abd2a

16 files changed

Lines changed: 206 additions & 62 deletions

File tree

Lines changed: 6 additions & 0 deletions
Loading

frontend/src/i18n/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,8 @@
788788
"no_data": "No Data",
789789
"loading_data": "Loading ...",
790790
"show_error_detail": "Show error info",
791+
"thousands_separator_setting": "Thousands Separator Setting",
792+
"thousands_separator_display": "Apply Thousands Separator Display",
791793
"log": {
792794
"GENERATE_SQL": "Generate SQL",
793795
"GENERATE_CHART": "Generate Chart Structure",

frontend/src/i18n/ko-KR.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,8 @@
788788
"no_data": "데이터가 없습니다",
789789
"loading_data": "로딩 중 ...",
790790
"show_error_detail": "구체적인 정보 보기",
791+
"thousands_separator_setting": "천 단위 구분 기호 설정",
792+
"thousands_separator_display": "천 단위 구분 기호 표시 적용",
791793
"log": {
792794
"GENERATE_SQL": "SQL 생성",
793795
"GENERATE_CHART": "차트 구조 생성",

frontend/src/i18n/zh-CN.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,8 @@
788788
"no_data": "暂无数据",
789789
"loading_data": "加载中...",
790790
"show_error_detail": "查看具体信息",
791+
"thousands_separator_setting": "千分位符设置",
792+
"thousands_separator_display": "应用千分位符展示",
791793
"log": {
792794
"GENERATE_SQL": "生成 SQL",
793795
"GENERATE_CHART": "生成图表结构",

frontend/src/i18n/zh-TW.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,8 @@
788788
"no_data": "暫無資料",
789789
"loading_data": "載入中...",
790790
"show_error_detail": "檢視具體資訊",
791+
"thousands_separator_setting": "千分位符設定",
792+
"thousands_separator_display": "套用千分位符顯示",
791793
"log": {
792794
"GENERATE_SQL": "產生 SQL",
793795
"GENERATE_CHART": "產生圖表結構",

frontend/src/views/chat/answer/ChartAnswer.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ function stop() {
258258
emits('stop')
259259
}
260260
261+
const enableThousandsSeparatorList = ref<Array<string>>([])
262+
261263
onBeforeUnmount(() => {
262264
stop()
263265
})
@@ -274,6 +276,7 @@ defineExpose({ sendMessage, index: () => index.value, stop })
274276
<template>
275277
<BaseAnswer v-if="message" :message="message" :reasoning-name="reasoningName" :loading="_loading">
276278
<ChartBlock
279+
v-model:thousands-separator-list="enableThousandsSeparatorList"
277280
style="margin-top: 6px"
278281
:message="message"
279282
:record-id="recordId"

frontend/src/views/chat/answer/PredictAnswer.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ function stop() {
257257
emits('stop')
258258
}
259259
260+
const enableThousandsSeparatorList = ref<Array<string>>([])
261+
260262
onBeforeUnmount(() => {
261263
stop()
262264
})
@@ -276,6 +278,7 @@ defineExpose({ sendMessage, index: () => index.value, chatList: () => _chatList,
276278
<ChartBlock
277279
v-if="message.record?.predict_data?.length > 0 && message.record?.data"
278280
ref="chartBlockRef"
281+
v-model:thousands-separator-list="enableThousandsSeparatorList"
279282
style="margin-top: 12px"
280283
:record-id="recordId"
281284
:message="message"

frontend/src/views/chat/chat-block/ChartBlock.vue

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import icon_window_max_outlined from '@/assets/svg/icon_window-max_outlined.svg'
2020
import icon_window_mini_outlined from '@/assets/svg/icon_window-mini_outlined.svg'
2121
import icon_copy_outlined from '@/assets/svg/icon_copy_outlined.svg'
2222
import ICON_STYLE from '@/assets/svg/icon_style-set_outlined.svg'
23+
import THOUSAND_SEPARATOR from '@/assets/svg/chart/icon-thousand-separator.svg'
2324
import { useI18n } from 'vue-i18n'
2425
import SQLComponent from '@/views/chat/component/SQLComponent.vue'
2526
import { useAssistantStore } from '@/stores/assistant'
@@ -38,21 +39,23 @@ const props = withDefaults(
3839
chatType?: ChartTypes
3940
enlarge?: boolean
4041
loadingData?: boolean
42+
thousandsSeparatorList?: Array<string>
4143
}>(),
4244
{
4345
recordId: undefined,
4446
isPredict: false,
4547
chatType: undefined,
4648
enlarge: false,
4749
loadingData: false,
50+
thousandsSeparatorList: () => [],
4851
}
4952
)
5053
5154
const { copy } = useClipboard({ legacy: true })
5255
const loading = ref<boolean>(false)
5356
const { t } = useI18n()
5457
const addViewRef = ref(null)
55-
const emits = defineEmits(['exitFullScreen'])
58+
const emits = defineEmits(['exitFullScreen', 'update:thousandsSeparatorList'])
5659
5760
const dataObject = computed<{
5861
fields: Array<string>
@@ -364,6 +367,20 @@ watch(
364367
}
365368
}
366369
)
370+
371+
const enableThousandsSeparatorList = computed({
372+
get() {
373+
return props.thousandsSeparatorList
374+
},
375+
set(v) {
376+
emits('update:thousandsSeparatorList', v)
377+
},
378+
})
379+
380+
const optionList = ref<Array<{ name: string; value: string }>>([])
381+
function getBaseAxis() {
382+
optionList.value = chartRef.value?.getBaseAxis()
383+
}
367384
</script>
368385

369386
<template>
@@ -390,7 +407,7 @@ watch(
390407
:chart-type="chartType"
391408
:title="t('chat.type')"
392409
@type-change="onTypeChange"
393-
></ChartPopover>
410+
/>
394411
</el-tooltip>
395412

396413
<el-tooltip
@@ -412,23 +429,58 @@ watch(
412429
</el-tooltip>
413430
</div>
414431

415-
<div v-if="currentChartType !== 'table'" class="chart-select-container">
432+
<div class="chart-select-container">
433+
<template v-if="currentChartType !== 'table'">
434+
<el-tooltip
435+
effect="dark"
436+
:offset="8"
437+
:content="showLabel ? t('chat.hide_label') : t('chat.show_label')"
438+
placement="top"
439+
>
440+
<el-button
441+
class="tool-btn"
442+
:class="{ 'chart-active': showLabel }"
443+
text
444+
@click="showLabel = !showLabel"
445+
>
446+
<el-icon size="16">
447+
<ICON_STYLE />
448+
</el-icon>
449+
</el-button>
450+
</el-tooltip>
451+
</template>
416452
<el-tooltip
417453
effect="dark"
418454
:offset="8"
419-
:content="showLabel ? t('chat.hide_label') : t('chat.show_label')"
455+
:content="t('chat.thousands_separator_setting')"
420456
placement="top"
421457
>
422-
<el-button
423-
class="tool-btn"
424-
:class="{ 'chart-active': showLabel }"
425-
text
426-
@click="showLabel = !showLabel"
427-
>
428-
<el-icon size="16">
429-
<ICON_STYLE />
430-
</el-icon>
431-
</el-button>
458+
<div>
459+
<el-popover placement="bottom" trigger="click">
460+
<template #reference>
461+
<el-button class="tool-btn" text @click="getBaseAxis">
462+
<el-icon size="16">
463+
<THOUSAND_SEPARATOR />
464+
</el-icon>
465+
</el-button>
466+
</template>
467+
<label style="font-weight: 500; line-height: 28px">
468+
{{ t('chat.thousands_separator_display') }}
469+
</label>
470+
<el-checkbox-group
471+
v-model="enableThousandsSeparatorList"
472+
style="display: flex; flex-direction: column"
473+
>
474+
<el-checkbox
475+
v-for="option in optionList"
476+
:key="option.value"
477+
size="large"
478+
:label="option.name"
479+
:value="option.value"
480+
/>
481+
</el-checkbox-group>
482+
</el-popover>
483+
</div>
432484
</el-tooltip>
433485
</div>
434486

@@ -538,6 +590,7 @@ watch(
538590
:data="data"
539591
:loading-data="loadingData"
540592
:show-label="showLabel"
593+
:thousands-separator-list="enableThousandsSeparatorList"
541594
/>
542595
</div>
543596
<div v-if="dataObject.limit" class="over-limit-hint">
@@ -556,7 +609,8 @@ watch(
556609
body-class="chart-fullscreen-dialog-body"
557610
>
558611
<ChartBlock
559-
v-if="dialogVisible"
612+
v-if="dialogVisible && !enlarge"
613+
v-model:thousands-separator-list="enableThousandsSeparatorList"
560614
:message="message"
561615
:record-id="recordId"
562616
:is-predict="isPredict"

frontend/src/views/chat/component/BaseChart.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export interface ChartAxis {
44
type?: 'x' | 'y' | 'series' | 'other-info'
55
'multi-quota'?: boolean
66
hidden?: boolean
7+
formatNumber?: boolean
78
}
89

910
export interface ChartData {
@@ -18,15 +19,17 @@ export abstract class BaseChart {
1819
axis: Array<ChartAxis> = []
1920
data: Array<ChartData> = []
2021
showLabel: boolean = false
22+
formatNumberFields: Array<string> = []
2123

2224
constructor(id: string, name: string) {
2325
this.id = id
2426
this._name = name
2527
}
2628

27-
init(axis: Array<ChartAxis>, data: Array<ChartData>): void {
29+
init(axis: Array<ChartAxis>, data: Array<ChartData>, formatNumberFields: Array<string>): void {
2830
this.axis = axis
2931
this.data = data
32+
this.formatNumberFields = formatNumberFields
3033
}
3134

3235
abstract render(): void

frontend/src/views/chat/component/ChartComponent.vue

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { computed, nextTick, onMounted, onUnmounted, watch } from 'vue'
33
import { getChartInstance } from '@/views/chat/component/index.ts'
44
import type { BaseChart, ChartAxis, ChartData } from '@/views/chat/component/BaseChart.ts'
55
import { useEmitt } from '@/utils/useEmitt.ts'
6+
import { filter, includes } from 'lodash-es'
67
78
const params = withDefaults(
89
defineProps<{
@@ -15,6 +16,7 @@ const params = withDefaults(
1516
series?: Array<ChartAxis>
1617
multiQuotaName?: string | undefined
1718
showLabel?: boolean
19+
thousandsSeparatorList?: Array<string>
1820
}>(),
1921
{
2022
data: () => [],
@@ -24,6 +26,7 @@ const params = withDefaults(
2426
series: () => [],
2527
multiQuotaName: undefined,
2628
showLabel: false,
29+
thousandsSeparatorList: () => [],
2730
}
2831
)
2932
@@ -34,21 +37,36 @@ const chartId = computed(() => {
3437
const axis = computed(() => {
3538
const _list: Array<ChartAxis> = []
3639
params.columns.forEach((column) => {
37-
_list.push({ name: column.name, value: column.value })
40+
_list.push({
41+
name: column.name,
42+
value: column.value,
43+
formatNumber: includes(params.thousandsSeparatorList, column.value),
44+
})
3845
})
3946
params.x.forEach((column) => {
40-
_list.push({ name: column.name, value: column.value, type: 'x' })
47+
_list.push({
48+
name: column.name,
49+
value: column.value,
50+
type: 'x',
51+
formatNumber: includes(params.thousandsSeparatorList, column.value),
52+
})
4153
})
4254
params.y.forEach((column) => {
4355
_list.push({
4456
name: column.name,
4557
value: column.value,
4658
type: 'y',
4759
'multi-quota': column['multi-quota'],
60+
formatNumber: includes(params.thousandsSeparatorList, column.value),
4861
})
4962
})
5063
params.series.forEach((column) => {
51-
_list.push({ name: column.name, value: column.value, type: 'series' })
64+
_list.push({
65+
name: column.name,
66+
value: column.value,
67+
type: 'series',
68+
formatNumber: includes(params.thousandsSeparatorList, column.value),
69+
})
5270
})
5371
if (params.multiQuotaName) {
5472
_list.push({
@@ -67,16 +85,17 @@ function renderChart() {
6785
chartInstance = getChartInstance(params.type, chartId.value)
6886
if (chartInstance) {
6987
chartInstance.showLabel = params.showLabel
70-
chartInstance.init(axis.value, params.data)
88+
chartInstance.init(axis.value, params.data, params.thousandsSeparatorList)
7189
chartInstance.render()
7290
}
7391
}
7492
7593
watch(
76-
() => params.showLabel,
94+
() => [params.showLabel, params.thousandsSeparatorList],
7795
() => {
7896
renderChart()
79-
}
97+
},
98+
{ deep: true }
8099
)
81100
82101
function destroyChart() {
@@ -93,6 +112,10 @@ function getExcelData() {
93112
}
94113
}
95114
115+
function getBaseAxis() {
116+
return filter(axis.value, (a) => !a.hidden)
117+
}
118+
96119
useEmitt({
97120
name: 'view-render-all',
98121
callback: renderChart,
@@ -107,6 +130,7 @@ defineExpose({
107130
renderChart,
108131
destroyChart,
109132
getExcelData,
133+
getBaseAxis,
110134
})
111135
112136
onMounted(() => {

0 commit comments

Comments
 (0)