feat: 图表对接

main
许宏杰 2 months ago
parent 66b0a45740
commit 34f23c6d5a

@ -3,4 +3,4 @@ import { BarCrossrangeConfig } from './BarCrossrange/index'
import { CapsuleChartConfig } from './CapsuleChart/index'
import { BarLineConfig } from './BarLine/index'
export default [BarCommonConfig, BarCrossrangeConfig, BarLineConfig, CapsuleChartConfig]
export default [BarCommonConfig, BarCrossrangeConfig, ]//BarLineConfigCapsuleChartConfig

@ -3,4 +3,4 @@ import { LineLinearSingleConfig } from './LineLinearSingle/index'
import { LineGradientSingleConfig } from './LineGradientSingle/index'
import { LineGradientsConfig } from './LineGradients/index'
export default [LineCommonConfig, LineLinearSingleConfig, LineGradientSingleConfig, LineGradientsConfig]
export default [LineCommonConfig, LineLinearSingleConfig]//LineGradientSingleConfig,LineGradientsConfig

@ -102,7 +102,7 @@ const styleColor: string[] = ['简约风', '商务风', '科技风']
const handleSend = async () => {
if (!keyWord.value.trim()) {
messageDialog.warning('请先输入您想知道的问题')
messageDialog.warning('请先输入需要统计的数据')
return
}

@ -7,6 +7,21 @@
height: chatRoom + 'px'
}"
>
<div
:class="['chat-item', 'ai-message']"
>
<!-- 头像 -->
<img :src="aiIcon" class="user-icon" alt="" />
<!-- 内容 -->
<div class="message-content">
<div class="message-time">当前数据</div>
<div class="message-text">
<span>{{ toString(source)}}</span>
</div>
</div>
</div>
<div
v-for="(item, index) in messagesList"
:key="index"
@ -44,9 +59,13 @@
</div>
</template>
<script setup>
<script setup lang="ts">
import { toString, isArray } from '@/utils'
import { ChartFrameEnum } from '@/packages/index.d'
import { useMessage } from 'naive-ui'
import { ref, reactive, watch, nextTick, onMounted } from 'vue'
import { ref, reactive, watch, nextTick, onMounted ,computed} from 'vue'
import { DataResultEnum, TimelineTitleEnum } from '../../index.d'
import { useTargetData } from '../../../hooks/useTargetData.hook'
import moment from 'moment'
// @ts-ignore
@ -57,14 +76,42 @@ import aiIcon from '@/assets/images/ai/ai-icon.png'
//
const { targetData, chartEditStore } = useTargetData()
const source = ref()
let keyWord = ref('')
let loading = ref(false)
const messageDialog = useMessage()
let messagesList = reactive([])
const scrollContainer = ref(null)
const chatBxo = ref(null)
const chatInput = ref(null)
let messagesList :any[] = reactive([])
const scrollContainer = ref<HTMLDivElement | null>(null)
const chatBxo =ref<HTMLDivElement | null>(null)
const chatInput = ref<HTMLDivElement | null>(null)
let chatRoom = ref(0)
const noData = ref(false)
const dimensions = ref()
const dimensionsAndSource = ref()
// , mapping
const fieldList = ref<
Array<{
field: string
mapping: string[]
result: DataResultEnum
}>
>([])
//
const matchingHandle = (mapping: string) => {
let res = DataResultEnum.SUCCESS
for (let i = 0; i < source.value.length; i++) {
if (source.value[i][mapping] === undefined) {
res = DataResultEnum.FAILURE
return res
}
}
return DataResultEnum.SUCCESS
}
//
const handleSend = async () => {
if (!keyWord.value.trim()) {
@ -74,38 +121,38 @@ const handleSend = async () => {
/**
*保存用户提问信息
*/
messagesList.push({
const messagesItem = {
from: 'user',
text: keyWord.value,
time: moment().format('YYYY/MM/DD HH:mm:ss')
})
}
messagesList.push(messagesItem)
loading.value = true
try {
const res = await getAiMsg({ prompt: keyWord.value })
let result = {}
if(res.chartType){
result.dimensions = [
'product','data1'
]
let result:any = {}
if (res.chartType) {
result.dimensions = ['product', 'data1']
result.source = []
res.xData.map((item,index)=>{
res.xData.map((item:any, index:any) => {
result.source.push({
product:item,
data1:parseInt(res.yData[index])
product: item,
data1: parseInt(res.yData[index])
})
})
}else{
targetData.value.option.dataset = result
// targetData.value.option.messages = messagesItem
} else {
result = res
}
//AI
messagesList.push({
from: 'ai',
text: result,
time: moment().format('YYYY/MM/DD HH:mm:ss')
})
targetData.value.option.dataset = result
// //AI
// messagesList.push({
// from: 'ai',
// text: result,
// time: moment().format('YYYY/MM/DD HH:mm:ss')
// })
keyWord.value = '' //
loading.value = false
} catch (error) {
@ -119,7 +166,56 @@ const handleSend = async () => {
loading.value = false
}
}
//
const dimensionsAndSourceHandle = () => {
try {
//
return dimensions.value.map((dimensionsItem: string, index: number) => {
return index === 0
? {
//
field: '通用标识',
//
mapping: dimensionsItem,
//
result: DataResultEnum.NULL
}
: {
field: `数据项-${index}`,
mapping: dimensionsItem,
result: matchingHandle(dimensionsItem)
}
})
} catch (error) {
return []
}
}
// dataset
const isCharts = computed(() => {
return targetData.value.chartConfig.chartFrame === ChartFrameEnum.ECHARTS
})
// vchart
const initFieldListHandle = () => {
if (targetData.value?.option) {
fieldList.value = []
// Field key
for (const key in targetData.value.option) {
if (key.endsWith('Field')) {
const value = targetData.value.option[key]
targetData.value.option[key] = value
const item = {
field: key,
mapping: value,
result: DataResultEnum.SUCCESS
}
if (item.mapping === undefined) {
item.result = DataResultEnum.FAILURE
}
fieldList.value.push(item)
}
}
}
}
//watch
// messages
watch(
@ -134,11 +230,59 @@ watch(
{ deep: true }
)
//
// watch(
// () => targetData.value.id,
// (
// ) => {
// messagesList = []
// },
// )
//
watch(
() => targetData.value?.option?.dataset,
(
newData?: {
source: any
dimensions: any
} | null
) => {
// console.log(targetData.value.option.messages,'sss')
noData.value = false
if (newData && targetData?.value?.chartConfig?.chartFrame === ChartFrameEnum.ECHARTS) {
// DataSet
source.value = newData
if (isCharts.value) {
dimensions.value = newData.dimensions
dimensionsAndSource.value = dimensionsAndSourceHandle()
}
} else if (newData && targetData?.value?.chartConfig?.chartFrame === ChartFrameEnum.VCHART) {
source.value = newData
initFieldListHandle()
} else if (newData !== undefined && newData !== null) {
dimensionsAndSource.value = null
source.value = newData
fieldList.value = []
} else {
noData.value = true
source.value = '此组件无数据源'
}
if (isArray(newData)) {
dimensionsAndSource.value = null
}
},
{
immediate: true
}
)
onMounted(() => {
if (chatBxo.value) {
if (chatBxo.value && chatInput.value) {
// 使 offsetHeight
chatRoom.value = chatBxo.value.offsetHeight - (chatInput.value.offsetHeight+100 )
console.log(chatBxo.value.offsetHeight, '高度')
chatRoom.value = chatBxo.value.offsetHeight - (chatInput.value.offsetHeight + 100)
}
})
</script>
@ -161,6 +305,7 @@ onMounted(() => {
gap: 25px;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
.chat-item {
display: flex;
gap: 6px;

@ -7,7 +7,7 @@
<!-- 位置 -->
<position-setting :chartAttr="targetData.attr" :canvasConfig="chartEditStore.getEditCanvasConfig" />
<!-- 滤镜 -->
<styles-setting :isGroup="targetData.isGroup" :chartStyles="targetData.styles"></styles-setting>
<!-- <styles-setting :isGroup="targetData.isGroup" :chartStyles="targetData.styles"></styles-setting> -->
<!-- 自定义配置项 -->
<component :is="targetData.chartConfig.conKey" :optionData="targetData.option"></component>
</div>

@ -8,6 +8,7 @@ export const useTargetData = () => {
const targetData: Ref<CreateComponentType | CreateComponentGroupType> = computed(() => {
const list = chartEditStore.getComponentList
const targetIndex = chartEditStore.fetchTargetIndex()
return list[targetIndex]
})
return { targetData, chartEditStore }

@ -134,16 +134,16 @@ const chartsDefaultTabList = [
icon: ConstructIcon,
render: ChartSetting
},
{
key: TabsEnum.CHART_ANIMATION,
title: '动画',
icon: LeafIcon,
render: ChartAnimation
}
// {
// key: TabsEnum.CHART_ANIMATION,
// title: '',
// icon: LeafIcon,
// render: ChartAnimation
// }
]
const chartsTabList = [
// ...chartsDefaultTabList,
...chartsDefaultTabList,
{
key: TabsEnum.CHART_DATA,
title: '统计数据',
@ -171,7 +171,7 @@ const chartsTabList = [
}
::v-deep .n-scrollbar-content{
height: 100%;
overflow: hidden;
}
.n-tabs{
height: 100%;

Loading…
Cancel
Save