完成页面统计图渲染

This commit is contained in:
2025-02-28 20:16:43 +08:00
parent ce59d63412
commit bfffbc9868
3 changed files with 107 additions and 18 deletions

View File

@@ -1,9 +1,27 @@
<script setup>
import {onMounted, ref} from 'vue'
import {onMounted, ref, toRaw} from 'vue'
import MarkdownIt from 'markdown-it'
import MarkDownMermaidPlugin from 'mermaid-it-markdown'
import {createEventSource} from 'eventsource-client'
import * as echarts from 'echarts'
import {CategoryScale, Chart, LinearScale, LineController, LineElement, PointElement, Title,} from 'chart.js'
import 'chartjs-adapter-moment'
import mermaid from 'mermaid'
import {each, isEqual, isJson, nextTick} from 'licia'
Chart.register(
LineController,
LineElement,
PointElement,
LinearScale,
Title,
CategoryScale
)
const chartsMap = ref({
echarts: {},
chartjs: {},
mermaid: {},
})
// 初始化 markdown-it 实例
const md = new MarkdownIt({
html: true, // 启用 HTML 标签
@@ -11,7 +29,33 @@ const md = new MarkdownIt({
linkify: true, // 自动转换 URL 为链接
typographer: true, // 启用一些语言中性的替换 + 引号美化
})
md.use(MarkDownMermaidPlugin)
md.use(function (md) {
md.renderer.rules.fence = function (tokens, idx, options, env, slf) {
// console.log('tokens', tokens, tokens[idx].info)
const content = tokens[idx].content
// 此处判断是否为 echarts 代码块
if (tokens[idx].info === 'echarts') {
if (isJson(content)) {
chartsMap.value.echarts[idx] = JSON.parse(content) //此处表示将内容存起来,存到当前页面的变量去
}
return `<div id="echarts-${idx}" style="width: 600px;height:400px;"></div>`
} else if (tokens[idx].info === 'chartjs') {
// 此处判断是否为 chartjs 代码块
if (isJson(content)) {
chartsMap.value.chartjs[idx] = JSON.parse(content)
}
return `<canvas id="chartjs-${idx}"></canvas>`
} else if (tokens[idx].info === 'mermaid') {
// 此处判断是否为 mermaidChart 代码块
const code = content.trim()
chartsMap.value.mermaid[idx] = code
return `<div id="mermaid-${idx}">${code}</div>`
} else {
// 其他代码块
return `<pre><code class='languge-${tokens[idx].info}'>${content}</code></pre>`
}
}
})
const question = ref('')
const answer = ref('')
@@ -33,12 +77,25 @@ const showToast = ref(false)
const toastMessage = ref('')
const toastMessageType = ref('success')
const onEventSourceClose = (eventSource) => {
console.log(answer.value)
console.log(renderedAnswer.value)
console.log(chartsMap.value)
eventSource.close()
renderCharts()
}
const handleSubmit = async () => {
if (!question.value.trim() || loading.value) return
loading.value = true
answer.value = ''
renderedAnswer.value = ''
chartsMap.value = {
echarts: {},
chartjs: {},
mermaid: {},
}
try {
const url = 'http://localhost:7891/chat/stream'
@@ -59,18 +116,18 @@ const handleSubmit = async () => {
url: url,
method: 'POST',
body: formData,
onDisconnect: () => {
console.log(answer.value)
console.log(renderedAnswer.value)
eventSource.close()
},
})
for await (const { data } of eventSource) {
if (isEqual(data, '#CLOSE#')) {
onEventSourceClose(eventSource)
break
}
answer.value += data.replaceAll(/#\/#/g, '')
renderedAnswer.value = md.render(answer.value)
}
} catch (error) {
console.error('请求出错:', error)
console.log(answer.value)
answer.value = '抱歉,请求出现错误'
renderedAnswer.value = answer.value
showToastMessage('请求失败,请检查服务器连接', 'error')
@@ -141,8 +198,25 @@ const handleCloseSettings = () => {
showToastMessage('设置已保存', 'success')
}
const renderCharts = () => {
const map = toRaw(chartsMap.value)
each(map.echarts, (value, key) => {
echarts.init(document.getElementById(`echarts-${key}`)).setOption(value)
})
each(map.chartjs, (value, key) => {
new Chart(document.getElementById(`chartjs-${key}`), value)
})
each(map.mermaid, (value, key) => {
mermaid.initialize({ startOnLoad: true })
mermaid.init(undefined, document.getElementById(`mermaid-${key}`))
})
}
// 在组件挂载时加载设置
onMounted(() => {
nextTick(() => {
renderCharts()
})
loadSettingsFromStorage()
})
</script>
@@ -350,6 +424,10 @@ onMounted(() => {
</template>
<style scoped>
.mermaid {
font-family: 'Arial', sans-serif;
}
.chat-container {
margin: 0;
height: 100vh;