mirror of
https://gitee.com/arthas/arthas.git
synced 2024-11-29 18:58:37 +08:00
refactor(web ui):refactor echarts component
This commit is contained in:
parent
be27d0e51d
commit
f74167bfdb
@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import Chart from "./Base.vue"
|
||||
import * as echarts from 'echarts/core';
|
||||
import { DatasetComponentOption, DataZoomComponent, DataZoomComponentOption, GridComponent, GridComponentOption, LegendComponent, LegendComponentOption, TitleComponentOption, ToolboxComponentOption, TooltipComponentOption } from 'echarts/components';
|
||||
import { BarChart, BarSeriesOption, } from 'echarts/charts';
|
||||
import { LabelLayout } from 'echarts/features';
|
||||
import { BarChartOption } from "@/echart";
|
||||
let useList = ([
|
||||
// LegendComponent,
|
||||
BarChart,
|
||||
LabelLayout,
|
||||
GridComponent,
|
||||
DataZoomComponent
|
||||
]);
|
||||
const props = defineProps<{ option: BarChartOption }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Chart :use-list="useList" :option="props.option"></Chart>
|
||||
</template>
|
@ -0,0 +1,73 @@
|
||||
<script setup lang="ts">
|
||||
import * as echarts from 'echarts/core';
|
||||
import { SVGRenderer } from 'echarts/renderers';
|
||||
import { TitleComponent, TitleComponentOption, TooltipComponent, TooltipComponentOption, ToolboxComponent, LegendComponent} from 'echarts/components'
|
||||
import { onBeforeUnmount, onMounted, Ref, ref, watch } from 'vue';
|
||||
// option && myChart.setOption(option);
|
||||
|
||||
type GetTuple<T extends unknown> = T extends T
|
||||
? T extends [...infer E]
|
||||
? T
|
||||
: never
|
||||
: never
|
||||
type UseType = GetTuple<Parameters<typeof echarts.use>[0]>
|
||||
// echarts.ECharts
|
||||
type OptionType = Parameters<echarts.ECharts["setOption"]>[0]
|
||||
const props = defineProps<{
|
||||
useList: UseType,
|
||||
option: OptionType,
|
||||
}>()
|
||||
|
||||
// type EChartsOption = echarts.ComposeOption<TooltipComponentOption | TitleComponentOption | DatasetComponentOption | PieSeriesOption>;
|
||||
const container = ref(null)
|
||||
let myChart: echarts.ECharts
|
||||
echarts.use([
|
||||
...props.useList,
|
||||
SVGRenderer,
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
ToolboxComponent,
|
||||
LegendComponent
|
||||
])
|
||||
|
||||
|
||||
// 抽离出来使得resize事件可以在全局挂载和卸载
|
||||
const resizeDom = () => {
|
||||
myChart && myChart.resize()
|
||||
}
|
||||
onMounted(() => {
|
||||
// container.value.el.id = chartId.toString()
|
||||
let dom = container.value
|
||||
myChart = echarts.init(dom as unknown as HTMLElement)
|
||||
myChart && myChart.setOption<OptionType>({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
}
|
||||
},
|
||||
...props.option
|
||||
})
|
||||
window.addEventListener("resize", resizeDom)
|
||||
})
|
||||
watch(props.option, (newData: any) => {
|
||||
myChart && newData && myChart.setOption(newData, true)
|
||||
console.log(newData)
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
myChart && myChart.dispose()
|
||||
window.removeEventListener("resize", resizeDom)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="container" class="w-full h-full"></div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
// import Chart from "./Chart.vue"
|
||||
import * as echarts from 'echarts/core';
|
||||
import { DatasetComponent, DatasetComponentOption, LegendComponent, TitleComponentOption, TooltipComponentOption } from 'echarts/components';
|
||||
import { PieChart } from 'echarts/charts';
|
||||
import { LabelLayout } from 'echarts/features';
|
||||
import { CircleChartOption } from "@/echart";
|
||||
import Base from './Base.vue';
|
||||
let useList = ([
|
||||
PieChart,
|
||||
LabelLayout,
|
||||
DatasetComponent
|
||||
]);
|
||||
// type CircleChartsOption = echarts.ComposeOption<TooltipComponentOption | TitleComponentOption | DatasetComponentOption | PieSeriesOption>;
|
||||
const props = defineProps<{ option: CircleChartOption }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Base :use-list="useList" :option="props.option" />
|
||||
</template>
|
@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import Chart from "./Base.vue"
|
||||
import * as echarts from 'echarts/core';
|
||||
import { DataZoomComponent, GridComponent } from 'echarts/components';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import { LabelLayout } from 'echarts/features';
|
||||
import { LineChartOption } from "@/echart";
|
||||
let useList = ([
|
||||
LineChart,
|
||||
LabelLayout,
|
||||
GridComponent,
|
||||
DataZoomComponent
|
||||
]);
|
||||
const props = defineProps<{ option: LineChartOption }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Chart :use-list="useList" :option="props.option"></Chart>
|
||||
</template>
|
47
web-ui/arthasWebConsole/all/ui/ui/src/echart.d.ts
vendored
Normal file
47
web-ui/arthasWebConsole/all/ui/ui/src/echart.d.ts
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
import * as echarts from "echarts";
|
||||
import {
|
||||
DatasetComponentOption,
|
||||
DataZoomComponentOption,
|
||||
GridComponentOption,
|
||||
LegendComponentOption,
|
||||
TitleComponentOption,
|
||||
ToolboxComponentOption,
|
||||
TooltipComponentOption,
|
||||
} from "echarts/components";
|
||||
import {
|
||||
BarSeriesOption,
|
||||
LineSeriesOption,
|
||||
PieSeriesOption,
|
||||
} from "echarts/charts";
|
||||
type LineChartOption = echarts.ComposeOption<
|
||||
| TooltipComponentOption
|
||||
| TitleComponentOption
|
||||
| DatasetComponentOption
|
||||
| LineSeriesOption
|
||||
| TitleComponentOption
|
||||
| ToolboxComponentOption
|
||||
| TooltipComponentOption
|
||||
| GridComponentOption
|
||||
| LegendComponentOption
|
||||
| DataZoomComponentOption
|
||||
| LineSeriesOption
|
||||
>;
|
||||
|
||||
type BarChartOption = echarts.ComposeOption<
|
||||
| TooltipComponentOption
|
||||
| TitleComponentOption
|
||||
| DatasetComponentOption
|
||||
| BarSeriesOption
|
||||
| DataZoomComponentOption
|
||||
| LegendComponentOption
|
||||
| GridComponentOption
|
||||
| ToolboxComponentOption
|
||||
>;
|
||||
|
||||
type CircleChartOption = echarts.ComposeOption<
|
||||
| TooltipComponentOption
|
||||
| TitleComponentOption
|
||||
| DatasetComponentOption
|
||||
| PieSeriesOption
|
||||
| LegendComponentOption
|
||||
>;
|
@ -3,51 +3,17 @@ import machine from '@/machines/consoleMachine';
|
||||
import { fetchStore } from '@/stores/fetch';
|
||||
import { publicStore } from '@/stores/public';
|
||||
import { useInterpret, useMachine } from '@xstate/vue';
|
||||
import { onBeforeMount, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
|
||||
import * as echarts from 'echarts/core';
|
||||
import {
|
||||
TooltipComponent,
|
||||
TooltipComponentOption,
|
||||
LegendComponent,
|
||||
LegendComponentOption,
|
||||
DatasetComponentOption,
|
||||
GridComponentOption,
|
||||
ToolboxComponentOption,
|
||||
GridComponent,
|
||||
ToolboxComponent
|
||||
} from 'echarts/components';
|
||||
import {
|
||||
BarChart,
|
||||
BarSeriesOption,
|
||||
LineChart,
|
||||
LineSeriesOption,
|
||||
PieChart,
|
||||
PieSeriesOption
|
||||
} from 'echarts/charts';
|
||||
import {
|
||||
LabelLayout, UniversalTransition
|
||||
} from 'echarts/features';
|
||||
import {
|
||||
SVGRenderer
|
||||
} from 'echarts/renderers';
|
||||
import { dispose, ECharts } from 'echarts/core';
|
||||
import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue';
|
||||
import permachine from '@/machines/perRequestMachine';
|
||||
|
||||
type EChartsOption = echarts.ComposeOption<
|
||||
DatasetComponentOption | PieSeriesOption
|
||||
>
|
||||
type GcEChartsOption = echarts.ComposeOption<
|
||||
ToolboxComponentOption | TooltipComponentOption | GridComponentOption | LegendComponentOption | BarSeriesOption | LineSeriesOption
|
||||
>
|
||||
import Bar from '@/components/charts/Bar.vue';
|
||||
import { BarChartOption, CircleChartOption } from '@/echart';
|
||||
import Circle from '@/components/charts/Circle.vue';
|
||||
const fetchS = fetchStore()
|
||||
const { getCommonResEffect } = publicStore()
|
||||
const dashboadM = useInterpret(permachine)
|
||||
const dashboadResM = useMachine(machine)
|
||||
const loop = fetchS.pullResultsLoop(dashboadResM)
|
||||
const toMb = (b: number) => Math.floor(b / 1024 / 1024)
|
||||
const gcInfos = reactive(new Map<string, string[]>())
|
||||
const memoryInfo = reactive(new Map<string, string[]>())
|
||||
const threads = reactive(new Map<string, string[]>())
|
||||
const runtimeInfo = reactive(new Map<keyof RuntimeInfo, string>())
|
||||
const pri = ref(3)
|
||||
const publiC = publicStore()
|
||||
@ -66,286 +32,17 @@ const keyList: (keyof ThreadStats)[] = [
|
||||
]
|
||||
|
||||
let dashboardId = -1
|
||||
let heapChart: ECharts
|
||||
let nonheapChart: ECharts
|
||||
let bufferPoolChart: ECharts
|
||||
let gcChart: ECharts
|
||||
const clearChart = (...charts: ECharts[]) => {
|
||||
charts.forEach(chart => {
|
||||
if (chart !== null && chart !== undefined) chart.dispose()
|
||||
})
|
||||
}
|
||||
const transformMemory = (result: ArthasResResult) => {
|
||||
if (result.type === "dashboard") {
|
||||
|
||||
const heaparr: { value: number, name: string }[] = [
|
||||
]
|
||||
result.memoryInfo.heap.filter(v => v.name !== "heap").forEach(v => {
|
||||
const arr: string[] = []
|
||||
|
||||
arr.push('max : ' + toMb(v.max))
|
||||
arr.push('total : ' + toMb(v.total))
|
||||
arr.push('used : ' + toMb(v.used))
|
||||
|
||||
const usage: number = (v.max > 0 ? (v.used / v.max) : (v.used / v.total)) * 100
|
||||
heaparr.push({ value: toMb(v.used), name: `${v.name}(${usage.toFixed(2)}%)` })
|
||||
|
||||
arr.push(usage + '%')
|
||||
|
||||
memoryInfo.set(v.name, arr)
|
||||
})
|
||||
heaparr.push({
|
||||
value: Math.floor((result.memoryInfo.heap[0].max > 0 ? (result.memoryInfo.heap[0].max - result.memoryInfo.heap[0].used) : (result.memoryInfo.heap[0].total - result.memoryInfo.heap[0].used)) / 1024 / 1024),
|
||||
name: "free",
|
||||
})
|
||||
heapChart && heapChart.setOption({
|
||||
series: {
|
||||
data: heaparr
|
||||
}
|
||||
} as EChartsOption)
|
||||
|
||||
const nonheaparr: {
|
||||
value: number, name: string,
|
||||
}[] = []
|
||||
result.memoryInfo.nonheap.filter(v => v.name !== "nonheap").forEach(v => {
|
||||
const arr: string[] = []
|
||||
|
||||
arr.push('max : ' + toMb(v.max))
|
||||
arr.push('total : ' + toMb(v.total))
|
||||
arr.push('used : ' + toMb(v.used))
|
||||
const usage: number = (v.used / v.total) * 100
|
||||
nonheaparr.push({ value: toMb(v.used), name: `${v.name}(${usage.toFixed(2)}%)` })
|
||||
|
||||
arr.push(usage * 100 + '%')
|
||||
|
||||
memoryInfo.set(v.name, arr)
|
||||
})
|
||||
nonheapChart && nonheapChart.setOption({ series: { data: nonheaparr } } as EChartsOption)
|
||||
|
||||
const bufferPoolarr: {
|
||||
value: number, name: string,
|
||||
}[] = []
|
||||
result.memoryInfo.buffer_pool.filter(v => v.name !== "buffer_pool;").forEach(v => {
|
||||
bufferPoolarr.push({ value: toMb(v.used), name: `${v.name}` })
|
||||
|
||||
})
|
||||
bufferPoolChart && bufferPoolChart.setOption({ series: { data: bufferPoolarr } } as EChartsOption)
|
||||
}
|
||||
}
|
||||
const transformThread = (result: ArthasResResult, end: number) => {
|
||||
if (result.type !== "dashboard") return;
|
||||
|
||||
for (let i = 0; i < end && i < result.threads.length; i++) {
|
||||
const thread = result.threads[i]
|
||||
const map = new Map()
|
||||
Object.entries(thread).forEach(([k, v]) => map.set(k, v.toString().trim() || "-"))
|
||||
tableResults.unshift(map)
|
||||
}
|
||||
}
|
||||
const transformGc = (result: ArthasResResult) => {
|
||||
if (result.type !== "dashboard") return;
|
||||
const gcCountData: number[] = []
|
||||
|
||||
const gcTimeData: number[] = []
|
||||
const gcxdata: string[] = []
|
||||
result.gcInfos.forEach(v => {
|
||||
// gcInfos.set(v.name, [v.collectionCount.toString(), v.collectionTime.toString()])
|
||||
gcxdata.push(v.name)
|
||||
gcCountData.push(v.collectionCount)
|
||||
gcTimeData.push(v.collectionTime)
|
||||
})
|
||||
gcChart.setOption({
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
},
|
||||
// prettier-ignore
|
||||
data: gcxdata
|
||||
}, series: [{
|
||||
name: "collectionCount",
|
||||
type: 'bar',
|
||||
data: gcCountData
|
||||
}, {
|
||||
name: "collectionTime",
|
||||
type: 'bar',
|
||||
data: gcTimeData
|
||||
}]
|
||||
} as GcEChartsOption)
|
||||
}
|
||||
const setPri = publiC.inputDialogFactory(
|
||||
pri,
|
||||
(raw) => {
|
||||
let valRaw = parseInt(raw)
|
||||
return Number.isNaN(valRaw) ? 3 : valRaw
|
||||
},
|
||||
(input) => input.value.toString(),
|
||||
)
|
||||
const { increase, decrease } = publiC.numberCondition(pri, { min: 1 })
|
||||
const transformRuntimeInfo = (result: ArthasResResult) => {
|
||||
if (result.type !== "dashboard") return;
|
||||
for (const key in result.runtimeInfo as RuntimeInfo) {
|
||||
runtimeInfo.set(key as keyof RuntimeInfo, result.runtimeInfo[key as keyof RuntimeInfo].toString())
|
||||
}
|
||||
}
|
||||
getCommonResEffect(dashboadResM, body => {
|
||||
if (body.results.length > 0 && dashboardId >= 0) {
|
||||
const result = body.results.find(v => v.type === "dashboard" && v.jobId === dashboardId)
|
||||
if (result && result.type === "dashboard") {
|
||||
|
||||
memoryInfo.clear()
|
||||
transformMemory(result)
|
||||
|
||||
runtimeInfo.clear()
|
||||
transformRuntimeInfo(result)
|
||||
|
||||
threads.clear()
|
||||
tableResults.length = 0
|
||||
transformThread(result, pri.value)
|
||||
|
||||
gcInfos.clear()
|
||||
transformGc(result)
|
||||
}
|
||||
}
|
||||
|
||||
const colors = ['#5470C6', '#91CC75'];
|
||||
const gcChartContext = reactive<{ xData: string[], collectionCount: number[], collectionTime: number[] }>({
|
||||
xData: [],
|
||||
collectionCount: [],
|
||||
collectionTime: []
|
||||
})
|
||||
// 处理初始化请求
|
||||
onBeforeMount(async () => {
|
||||
dashboadResM.send("INIT")
|
||||
|
||||
fetchS
|
||||
.asyncInit()
|
||||
.finally(
|
||||
() => {
|
||||
fetchS.baseSubmit(dashboadM, {
|
||||
action: "async_exec",
|
||||
command: "dashboard",
|
||||
sessionId: undefined
|
||||
}).then(
|
||||
res => {
|
||||
dashboardId = (res as AsyncRes).body.jobId
|
||||
loop.open()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
})
|
||||
// 处理dom
|
||||
onMounted(() => {
|
||||
// init
|
||||
|
||||
const clearDom = (...doms: HTMLElement[]) => {
|
||||
doms.forEach(dom => {
|
||||
dispose(dom)
|
||||
})
|
||||
}
|
||||
clearChart(nonheapChart, heapChart, bufferPoolChart, gcChart)
|
||||
const heapDom = document.getElementById('heapMemory')!
|
||||
const nonheapDom = document.getElementById('nonheapMemory')!
|
||||
const bufferPoolDom = document.getElementById('bufferPoolMemory')!
|
||||
const gcDom = document.getElementById('gc-info')!
|
||||
clearDom(heapDom, nonheapDom, bufferPoolDom, gcDom)
|
||||
echarts.use(
|
||||
[TooltipComponent, LegendComponent, PieChart, SVGRenderer, LabelLayout, ToolboxComponent, GridComponent, BarChart, LineChart, UniversalTransition]
|
||||
);
|
||||
|
||||
|
||||
|
||||
const heapoption: EChartsOption = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b}:{c}M {d}'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'heap memory',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: true,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center',
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
const nonheapoption: EChartsOption = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b}:{c}M'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'nonheap memory',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center',
|
||||
formatter: '{b}:{c}M'
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
const bufferPooloption: EChartsOption = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{c}M'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'buffer_pool memory',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: true,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'outside',
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 0,
|
||||
name: '',
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
const colors = ['#5470C6', '#91CC75'];
|
||||
const gcoption: GcEChartsOption = {
|
||||
const gcoption = reactive<BarChartOption>({
|
||||
color: colors,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
}
|
||||
title:{
|
||||
text: "GC",
|
||||
},
|
||||
grid: {
|
||||
right: '20%'
|
||||
@ -353,21 +50,13 @@ onMounted(() => {
|
||||
legend: {
|
||||
data: ['collectionCount', 'collectionTime']
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
},
|
||||
// prettier-ignore
|
||||
data: []
|
||||
}
|
||||
],
|
||||
toolbox: {
|
||||
feature: {
|
||||
dataView: { show: true, readOnly: true },
|
||||
}
|
||||
},
|
||||
data: gcChartContext.xData
|
||||
}],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
@ -404,39 +93,255 @@ onMounted(() => {
|
||||
{
|
||||
name: 'collectionCount',
|
||||
type: 'bar',
|
||||
data: [
|
||||
]
|
||||
data: gcChartContext.collectionCount
|
||||
},
|
||||
{
|
||||
name: 'collectionTime',
|
||||
type: 'bar',
|
||||
yAxisIndex: 1,
|
||||
data: [
|
||||
]
|
||||
data: gcChartContext.collectionTime
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
heapChart = echarts.init(heapDom);
|
||||
heapoption && heapChart.setOption(heapoption);
|
||||
|
||||
nonheapChart = echarts.init(nonheapDom);
|
||||
nonheapoption && nonheapChart.setOption(nonheapoption);
|
||||
|
||||
bufferPoolChart = echarts.init(bufferPoolDom);
|
||||
bufferPooloption && bufferPoolChart.setOption(bufferPooloption);
|
||||
|
||||
// gcInfosChart
|
||||
|
||||
gcChart = echarts.init(gcDom);
|
||||
|
||||
|
||||
gcoption && gcChart.setOption(gcoption);
|
||||
});
|
||||
const bufferPoolContext = reactive<{
|
||||
data: {
|
||||
value: number, name: string,
|
||||
}[]
|
||||
}>({
|
||||
data: []
|
||||
})
|
||||
const heapoptionContext = reactive<{
|
||||
data: {
|
||||
value: number, name: string,
|
||||
}[]
|
||||
}>({
|
||||
data: []
|
||||
})
|
||||
const nonheapContext = reactive<{
|
||||
data: {
|
||||
value: number, name: string,
|
||||
}[]
|
||||
}>({
|
||||
data: []
|
||||
})
|
||||
const heapoption = reactive<CircleChartOption>({
|
||||
title:{
|
||||
text:"heap"
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b}:{c}M {d}'
|
||||
},
|
||||
legend: {
|
||||
top: 'center',
|
||||
left: 'right',
|
||||
orient: "vertical"
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
center:['35%','50%'],
|
||||
avoidLabelOverlap: true,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center',
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: heapoptionContext.data
|
||||
}
|
||||
]
|
||||
});
|
||||
const nonheapoption = reactive<CircleChartOption>({
|
||||
title:{
|
||||
text:"nonheap"
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b}:{c}M'
|
||||
},
|
||||
legend: {
|
||||
top: 'center',
|
||||
left: 'right',
|
||||
orient: "vertical"
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
center:['35%','50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center',
|
||||
formatter: '{b}:{c}M'
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: nonheapContext.data
|
||||
}
|
||||
]
|
||||
});
|
||||
const bufferPooloption = reactive<CircleChartOption>({
|
||||
title: {
|
||||
text: "buffer_pool"
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{c}M'
|
||||
},
|
||||
legend: {
|
||||
top: 'center',
|
||||
left: 'right',
|
||||
orient: 'vertical'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
center:['35%','50%'],
|
||||
avoidLabelOverlap: true,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'outside',
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: bufferPoolContext.data
|
||||
}
|
||||
]
|
||||
});
|
||||
const transformMemory = (result: ArthasResResult) => {
|
||||
if (result.type === "dashboard") {
|
||||
|
||||
// const heaparr: { value: number, name: string }[] = [
|
||||
// ]
|
||||
heapoptionContext.data.length = 0
|
||||
result.memoryInfo.heap.filter(v => v.name !== "heap").forEach(v => {
|
||||
const arr: string[] = []
|
||||
|
||||
// arr.push('max : ' + toMb(v.max))
|
||||
// arr.push('total : ' + toMb(v.total))
|
||||
// arr.push('used : ' + toMb(v.used))
|
||||
|
||||
const usage: number = (v.max > 0 ? (v.used / v.max) : (v.used / v.total)) * 100
|
||||
heapoptionContext.data.push({ value: toMb(v.used), name: `${v.name}(${usage.toFixed(2)}%)` })
|
||||
|
||||
// arr.push(usage + '%')
|
||||
|
||||
// memoryInfo.set(v.name, arr)
|
||||
})
|
||||
heapoptionContext.data.push({
|
||||
value: Math.floor((result.memoryInfo.heap[0].max > 0 ? (result.memoryInfo.heap[0].max - result.memoryInfo.heap[0].used) : (result.memoryInfo.heap[0].total - result.memoryInfo.heap[0].used)) / 1024 / 1024),
|
||||
name: "free",
|
||||
})
|
||||
// heapoptionContext.data = heaparr
|
||||
|
||||
nonheapContext.data.length = 0
|
||||
result.memoryInfo.nonheap.filter(v => v.name !== "nonheap").forEach(v => {
|
||||
const arr: string[] = []
|
||||
|
||||
// arr.push('max : ' + toMb(v.max))
|
||||
// arr.push('total : ' + toMb(v.total))
|
||||
// arr.push('used : ' + toMb(v.used))
|
||||
const usage: number = (v.used / v.total) * 100
|
||||
nonheapContext.data.push({ value: toMb(v.used), name: `${v.name}(${usage.toFixed(2)}%)` })
|
||||
|
||||
// arr.push(usage * 100 + '%')
|
||||
|
||||
// memoryInfo.set(v.name, arr)
|
||||
})
|
||||
// nonheapChart && nonheapChart.setOption({ series: { data: nonheaparr } } as EChartsOption)
|
||||
|
||||
bufferPoolContext.data.length = 0
|
||||
result.memoryInfo.buffer_pool.filter(v => v.name !== "buffer_pool;").forEach(v => {
|
||||
bufferPoolContext.data.push({ value: toMb(v.used), name: `${v.name}` })
|
||||
})
|
||||
}
|
||||
}
|
||||
const transformThread = (result: ArthasResResult, end: number) => {
|
||||
if (result.type !== "dashboard") return;
|
||||
|
||||
for (let i = 0; i < end && i < result.threads.length; i++) {
|
||||
const thread = result.threads[i]
|
||||
const map = new Map()
|
||||
Object.entries(thread).forEach(([k, v]) => map.set(k, v.toString().trim() || "-"))
|
||||
tableResults.unshift(map)
|
||||
}
|
||||
}
|
||||
const transformGc = (result: ArthasResResult) => {
|
||||
if (result.type !== "dashboard") return;
|
||||
gcChartContext.xData.length = 0
|
||||
gcChartContext.collectionCount.length = 0
|
||||
gcChartContext.collectionTime.length = 0
|
||||
result.gcInfos.forEach(v => {
|
||||
gcChartContext.xData.push(v.name)
|
||||
gcChartContext.collectionCount.push(v.collectionCount)
|
||||
gcChartContext.collectionTime.push(v.collectionTime)
|
||||
})
|
||||
}
|
||||
const setPri = publiC.inputDialogFactory(
|
||||
pri,
|
||||
(raw) => {
|
||||
let valRaw = parseInt(raw)
|
||||
return Number.isNaN(valRaw) ? 3 : valRaw
|
||||
},
|
||||
(input) => input.value.toString(),
|
||||
)
|
||||
const { increase, decrease } = publiC.numberCondition(pri, { min: 1 })
|
||||
const transformRuntimeInfo = (result: ArthasResResult) => {
|
||||
if (result.type !== "dashboard") return;
|
||||
for (const key in result.runtimeInfo as RuntimeInfo) {
|
||||
runtimeInfo.set(key as keyof RuntimeInfo, result.runtimeInfo[key as keyof RuntimeInfo].toString())
|
||||
}
|
||||
}
|
||||
getCommonResEffect(dashboadResM, body => {
|
||||
if (body.results.length > 0 && dashboardId >= 0) {
|
||||
const result = body.results.find(v => v.type === "dashboard" && v.jobId === dashboardId)
|
||||
if (result && result.type === "dashboard") {
|
||||
|
||||
transformMemory(result)
|
||||
|
||||
runtimeInfo.clear()
|
||||
transformRuntimeInfo(result)
|
||||
|
||||
tableResults.length = 0
|
||||
transformThread(result, pri.value)
|
||||
|
||||
transformGc(result)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
// 处理初始化请求
|
||||
onBeforeMount(async () => {
|
||||
dashboadResM.send("INIT")
|
||||
|
||||
fetchS
|
||||
.asyncInit()
|
||||
.finally(
|
||||
() => {
|
||||
fetchS.baseSubmit(dashboadM, {
|
||||
action: "async_exec",
|
||||
command: "dashboard",
|
||||
sessionId: undefined
|
||||
}).then(
|
||||
res => {
|
||||
dashboardId = (res as AsyncRes).body.jobId
|
||||
loop.open()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
})
|
||||
|
||||
onBeforeUnmount(async () => {
|
||||
loop.close()
|
||||
clearChart(nonheapChart, heapChart, bufferPoolChart, gcChart)
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -453,22 +358,21 @@ onBeforeUnmount(async () => {
|
||||
</div>
|
||||
<div class="flex justify-evenly mb-4 flex-1 h-80">
|
||||
<div class="card border mr-4 flex-1 bg-base-100">
|
||||
<div id="heapMemory" class="w-80 h-80 card-body "></div>
|
||||
|
||||
<Circle class="card-body" :option="heapoption"></Circle>
|
||||
</div>
|
||||
<div class="card border mr-4 flex-1 bg-base-100">
|
||||
<div id="nonheapMemory" class="w-80 h-80 card-body"></div>
|
||||
|
||||
<Circle class="card-body" :option="nonheapoption"></Circle>
|
||||
</div>
|
||||
<div class="card border flex-1 bg-base-100">
|
||||
<div id="bufferPoolMemory" class="w-80 h-80 card-body"></div>
|
||||
<Circle class="card-body" :option="bufferPooloption"></Circle>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="w-full flex justify-start items-start flex-1">
|
||||
<div class="card bg-base-100 border mr-4">
|
||||
<div id="gc-info" class="w-[40rem] h-80 card-body p-2 "></div>
|
||||
<div class="card bg-base-100 border mr-4 h-80 w-1/3">
|
||||
<Bar class="card-body" :option="gcoption" />
|
||||
</div>
|
||||
<div class="card flex-1 h-80 overflow-auto w-0 border bg-base-100">
|
||||
<div class="card-body">
|
||||
|
@ -10,45 +10,12 @@ import {
|
||||
import MethodInput from '@/components/input/MethodInput.vue';
|
||||
import machine from '@/machines/consoleMachine';
|
||||
import { fetchStore } from '@/stores/fetch';
|
||||
import { onBeforeMount, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
|
||||
import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue';
|
||||
import Enhancer from '@/components/show/Enhancer.vue';
|
||||
import { publicStore } from '@/stores/public';
|
||||
import * as echarts from 'echarts/core';
|
||||
import {
|
||||
TitleComponent,
|
||||
TitleComponentOption,
|
||||
ToolboxComponent,
|
||||
ToolboxComponentOption,
|
||||
TooltipComponent,
|
||||
TooltipComponentOption,
|
||||
GridComponent,
|
||||
GridComponentOption,
|
||||
LegendComponent,
|
||||
LegendComponentOption,
|
||||
DataZoomComponent,
|
||||
DataZoomComponentOption
|
||||
} from 'echarts/components';
|
||||
import {
|
||||
BarChart,
|
||||
BarSeriesOption,
|
||||
LineChart,
|
||||
LineSeriesOption
|
||||
} from 'echarts/charts';
|
||||
import {
|
||||
UniversalTransition
|
||||
} from 'echarts/features';
|
||||
import {
|
||||
SVGRenderer
|
||||
} from 'echarts/renderers';
|
||||
import { ECharts } from 'echarts/core';
|
||||
|
||||
echarts.use(
|
||||
[TitleComponent, ToolboxComponent, TooltipComponent, GridComponent, LegendComponent, DataZoomComponent, BarChart, LineChart, SVGRenderer, UniversalTransition]
|
||||
);
|
||||
|
||||
type EChartsOption = echarts.ComposeOption<
|
||||
TitleComponentOption | ToolboxComponentOption | TooltipComponentOption | GridComponentOption | LegendComponentOption | DataZoomComponentOption | BarSeriesOption | LineSeriesOption
|
||||
>
|
||||
import LineVue from "@/components/charts/Line.vue"
|
||||
import Bar from '@/components/charts/Bar.vue';
|
||||
import { BarChartOption, LineChartOption } from '@/echart';
|
||||
const pollingM = useMachine(machine)
|
||||
const fetchS = fetchStore()
|
||||
const { pullResultsLoop, getCommonResEffect } = fetchS
|
||||
@ -69,29 +36,28 @@ const averageRT = ref({
|
||||
})
|
||||
|
||||
const chartContext: {
|
||||
count: number,
|
||||
myChart?: ECharts,
|
||||
costChart?: ECharts,
|
||||
categories: string[],
|
||||
data: number[],
|
||||
cur: number,
|
||||
max: number,
|
||||
successData: number[],
|
||||
failureData: number[]
|
||||
} = {
|
||||
max: 0,
|
||||
cur: 0,
|
||||
count: 40,
|
||||
myChart: undefined,
|
||||
costChart: undefined,
|
||||
failureData: number[],
|
||||
dataZoom: Record<string, unknown>
|
||||
} = reactive({
|
||||
categories: [],
|
||||
data: [],
|
||||
successData: [],
|
||||
failureData: [],
|
||||
}
|
||||
// for (let i = 0; i < chartContext.count; i++) { chartContext.categories[i] = i + 1 }
|
||||
dataZoom: {
|
||||
type: "inside",
|
||||
minValueSpan: 10,
|
||||
maxValueSpan: 10,
|
||||
start: 50,
|
||||
end: 100,
|
||||
throttle: 0,
|
||||
zoomLock: true
|
||||
}
|
||||
})
|
||||
|
||||
const chartOption = {
|
||||
const chartOption = reactive<BarChartOption>({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
@ -102,12 +68,7 @@ const chartOption = {
|
||||
}
|
||||
},
|
||||
legend: {},
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
dataView: { readOnly: false },
|
||||
}
|
||||
},
|
||||
dataZoom: chartContext.dataZoom,
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
@ -129,20 +90,20 @@ const chartOption = {
|
||||
name: 'success',
|
||||
type: 'bar',
|
||||
stack: 'count',
|
||||
data: [],
|
||||
data: chartContext.successData,
|
||||
},
|
||||
{
|
||||
name: 'failure',
|
||||
type: 'bar',
|
||||
stack: "count",
|
||||
data: [],
|
||||
data: chartContext.failureData,
|
||||
itemStyle: {
|
||||
color: "#ff0000",
|
||||
}
|
||||
},
|
||||
]
|
||||
};
|
||||
const costOption = {
|
||||
});
|
||||
const costOption = reactive<LineChartOption>({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
@ -152,15 +113,16 @@ const costOption = {
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {},
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
dataView: { readOnly: false },
|
||||
}
|
||||
legend: {
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
dataZoom: chartContext.dataZoom,
|
||||
// toolbox: {
|
||||
// show: true,
|
||||
// feature: {
|
||||
// dataView: { readOnly: false },
|
||||
// }
|
||||
// },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: chartContext.categories,
|
||||
axisLabel: {
|
||||
@ -168,93 +130,33 @@ const costOption = {
|
||||
return value.split(" ")[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
scale: true,
|
||||
name: 'rt(ms)',
|
||||
min: 0,
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
},
|
||||
series: {
|
||||
name: 'rt',
|
||||
type: 'line',
|
||||
data: chartContext.data
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
const updateChart = (data: MonitorData) => {
|
||||
while (chartContext.cur > chartContext.count) {
|
||||
chartContext.data.shift()
|
||||
chartContext.successData.shift()
|
||||
chartContext.failureData.shift()
|
||||
chartContext.categories.shift()
|
||||
chartContext.cur--
|
||||
}
|
||||
chartContext.data.push(data.cost / data.total)
|
||||
chartContext.failureData.push(data.failed)
|
||||
chartContext.successData.push(data.success)
|
||||
chartContext.categories.push(data.timestamp)
|
||||
chartContext.cur++
|
||||
|
||||
chartContext.myChart!.setOption<EChartsOption>({
|
||||
xAxis: [
|
||||
{
|
||||
data: chartContext.categories
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
data: chartContext.successData
|
||||
}, {
|
||||
data: chartContext.failureData
|
||||
}
|
||||
]
|
||||
})
|
||||
chartContext.costChart!.setOption<EChartsOption>({
|
||||
xAxis: [
|
||||
{
|
||||
data: chartContext.categories
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: chartContext.data
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
const resetChart = () => {
|
||||
chartContext.data.length = 0
|
||||
chartContext.failureData.length = 0
|
||||
chartContext.successData.length = 0
|
||||
chartContext.myChart!.setOption<EChartsOption>({
|
||||
xAxis: [
|
||||
{
|
||||
data: chartContext.categories
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
data: chartContext.successData
|
||||
}, {
|
||||
data: chartContext.failureData
|
||||
}
|
||||
]
|
||||
})
|
||||
chartContext.costChart!.setOption<EChartsOption>({
|
||||
xAxis: [
|
||||
{
|
||||
data: chartContext.categories
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: chartContext.data
|
||||
}
|
||||
]
|
||||
})
|
||||
enhancer.value = undefined
|
||||
averageRT.value.totalCost = 0
|
||||
averageRT.value.totalCount = 0
|
||||
}
|
||||
const transform = (result: ArthasResResult) => {
|
||||
if (result.type === "monitor") {
|
||||
@ -286,21 +188,11 @@ onBeforeMount(() => {
|
||||
fetchS.asyncInit()
|
||||
pollingM.send("INIT")
|
||||
})
|
||||
onMounted(() => {
|
||||
const chartDom = document.getElementById('monitorchart')!;
|
||||
chartContext.myChart = echarts.init(chartDom);
|
||||
chartOption && chartContext.myChart.setOption(chartOption)
|
||||
chartContext.costChart = echarts.init(document.getElementById('monitorchartcost')!);
|
||||
chartOption && chartContext.costChart.setOption(costOption)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
loop.close()
|
||||
})
|
||||
const submit = async (data: { classItem: Item, methodItem: Item, conditon: string }) => {
|
||||
enhancer.value = undefined
|
||||
// tableResults.length = 0
|
||||
averageRT.value.totalCost =0
|
||||
averageRT.value.totalCount = 0
|
||||
resetChart()
|
||||
let condition = data.conditon.trim() == "" ? "" : `'${data.conditon.trim()}'`
|
||||
let cycle = `-c ${cycleV.value}`
|
||||
fetchS.baseSubmit(fetchM, {
|
||||
@ -321,7 +213,7 @@ const submit = async (data: { classItem: Item, methodItem: Item, conditon: strin
|
||||
<ListboxButton class="btn btn-sm btn-outline w-40">{{ mode.name }}</ListboxButton>
|
||||
<ListboxOptions
|
||||
class="absolute w-40 mt-2 border overflow-hidden rounded-md hover:shadow-xl transition bg-white z-10">
|
||||
<ListboxOption v-for="(am,i) in modelist" :key="i" :value="am" v-slot="{active, selected}">
|
||||
<ListboxOption v-for="(am, i) in modelist" :key="i" :value="am" v-slot="{ active, selected }">
|
||||
<div class=" p-2 transition" :class="{
|
||||
'bg-neutral text-neutral-content': active,
|
||||
'bg-neutral-focus text-neutral-content': selected,
|
||||
@ -332,13 +224,14 @@ const submit = async (data: { classItem: Item, methodItem: Item, conditon: strin
|
||||
</ListboxOptions>
|
||||
</div>
|
||||
</Listbox>
|
||||
<button class="btn btn-sm btn-outline" @click="changeCycle">cycle time:{{cycleV}}</button>
|
||||
<button class="btn btn-sm btn-outline" @click="changeCycle">cycle time:{{ cycleV }}</button>
|
||||
</template>
|
||||
</MethodInput>
|
||||
<Enhancer :result="enhancer" v-if="enhancer" class="mb-4">
|
||||
|
||||
</Enhancer>
|
||||
<div id="monitorchart" class="input-btn-style h-60 w-full pointer-events-auto transition mb-2"></div>
|
||||
<div id="monitorchartcost" class="input-btn-style h-60 w-full pointer-events-auto transition"></div>
|
||||
|
||||
<!-- <div id="monitorchart" class="input-btn-style h-60 w-full pointer-events-auto transition mb-2"></div> -->
|
||||
<Bar class="h-60 pointer-events-auto transition" :option="chartOption" />
|
||||
<!-- <div id="monitorchartcost" class="input-btn-style h-60 w-full pointer-events-auto transition"></div> -->
|
||||
<LineVue class="h-60 pointer-events-auto transition" :option="costOption" />
|
||||
</template>
|
||||
|
@ -8,42 +8,12 @@ import { onBeforeMount, onBeforeUnmount, onMounted, reactive, ref, } from 'vue';
|
||||
import CmdResMenu from '@/components/show/CmdResMenu.vue';
|
||||
import Enhancer from '@/components/show/Enhancer.vue';
|
||||
import { publicStore } from '@/stores/public';
|
||||
import * as echarts from 'echarts/core';
|
||||
import {
|
||||
TitleComponent,
|
||||
TitleComponentOption,
|
||||
ToolboxComponent,
|
||||
ToolboxComponentOption,
|
||||
TooltipComponent,
|
||||
TooltipComponentOption,
|
||||
GridComponent,
|
||||
GridComponentOption,
|
||||
LegendComponent,
|
||||
LegendComponentOption,
|
||||
DataZoomComponent,
|
||||
DataZoomComponentOption
|
||||
} from 'echarts/components';
|
||||
import {
|
||||
BarChart,
|
||||
BarSeriesOption,
|
||||
LineChart,
|
||||
LineSeriesOption
|
||||
} from 'echarts/charts';
|
||||
import {
|
||||
UniversalTransition
|
||||
} from 'echarts/features';
|
||||
import {
|
||||
SVGRenderer
|
||||
} from 'echarts/renderers';
|
||||
import { ECharts, number } from 'echarts/core';
|
||||
import LineVue from '@/components/charts/Line.vue';
|
||||
import { LineChartOption } from '@/echart';
|
||||
|
||||
echarts.use(
|
||||
[TitleComponent, ToolboxComponent, TooltipComponent, GridComponent, LegendComponent, DataZoomComponent, BarChart, LineChart, SVGRenderer, UniversalTransition]
|
||||
);
|
||||
|
||||
type EChartsOption = echarts.ComposeOption<
|
||||
TitleComponentOption | ToolboxComponentOption | TooltipComponentOption | GridComponentOption | LegendComponentOption | DataZoomComponentOption | BarSeriesOption | LineSeriesOption
|
||||
>
|
||||
// type EChartsOption = echarts.ComposeOption<
|
||||
// TitleComponentOption | ToolboxComponentOption | TooltipComponentOption | GridComponentOption | LegendComponentOption | DataZoomComponentOption | BarSeriesOption | LineSeriesOption
|
||||
// >
|
||||
const pollingM = useMachine(machine)
|
||||
const fetchS = fetchStore()
|
||||
const { pullResultsLoop, getPullResultsEffect } = fetchS
|
||||
@ -72,21 +42,13 @@ const tableResults = reactive([] as Map<string, string>[])
|
||||
type tfkey = keyof TimeFragment
|
||||
|
||||
const chartContext: {
|
||||
count: number,
|
||||
myChart?: ECharts,
|
||||
categories: number[],
|
||||
data: number[],
|
||||
cur: number,
|
||||
max: number,
|
||||
} = {
|
||||
max: 0,
|
||||
cur: 0,
|
||||
count: 20,
|
||||
myChart: undefined,
|
||||
} = reactive({
|
||||
categories: [],
|
||||
data: []
|
||||
}
|
||||
const chartOption = {
|
||||
})
|
||||
const chartOption = reactive<LineChartOption>({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
@ -96,67 +58,47 @@ const chartOption = {
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {},
|
||||
legend: {
|
||||
},
|
||||
dataZoom: {
|
||||
type: "inside",
|
||||
minValueSpan:30,
|
||||
maxValueSpan:30,
|
||||
start: 50,
|
||||
end: 100,
|
||||
throttle:0,
|
||||
zoomLock: true
|
||||
},
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
dataView: { readOnly: false },
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: true,
|
||||
data: chartContext.categories
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
},
|
||||
yAxis:
|
||||
{
|
||||
type: 'value',
|
||||
scale: true,
|
||||
name: 'cost(ms)',
|
||||
max: 0,
|
||||
min: 0,
|
||||
boundaryGap: [0.2, 0.2]
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
},
|
||||
series: {
|
||||
name: 'cost',
|
||||
type: 'bar',
|
||||
type: 'line',
|
||||
xAxisIndex: 0,
|
||||
yAxisIndex: 0,
|
||||
data: chartContext.data
|
||||
}
|
||||
]
|
||||
};
|
||||
});
|
||||
const updateChart = (tf: TimeFragment) => {
|
||||
while (chartContext.cur > chartContext.count) {
|
||||
chartContext.data.shift()
|
||||
chartContext.categories.shift()
|
||||
chartContext.cur--
|
||||
}
|
||||
chartContext.data.push(tf.cost)
|
||||
chartContext.categories.push(tf.index)
|
||||
chartContext.cur++
|
||||
chartContext.max = Math.max(...chartContext.data)
|
||||
chartContext.myChart!.setOption<EChartsOption>({
|
||||
xAxis: [
|
||||
{
|
||||
data: chartContext.categories
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
max: chartContext.max,
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: chartContext.data
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
const transform = (tf: TimeFragment) => {
|
||||
const map = new Map()
|
||||
@ -200,14 +142,6 @@ onBeforeMount(() => {
|
||||
pollingM.send("INIT")
|
||||
fetchS.asyncInit()
|
||||
})
|
||||
onMounted(() => {
|
||||
const chartDom = document.getElementById('ttchart')!;
|
||||
chartContext.myChart = echarts.init(chartDom);
|
||||
chartContext.myChart.on("click", e => {
|
||||
console.dir(e)
|
||||
})
|
||||
chartOption && chartContext.myChart.setOption(chartOption)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
loop.close()
|
||||
})
|
||||
@ -230,10 +164,13 @@ const alltt = () => fetchS.baseSubmit(fetchM, {
|
||||
let result = (res as CommonRes).body.results[0]
|
||||
trigerRes.clear()
|
||||
tableResults.length = 0
|
||||
// 因为要all 所以清空之前的记录
|
||||
chartContext.categories.length = 0
|
||||
chartContext.data.length = 0
|
||||
|
||||
if (result.type === "tt") {
|
||||
result.timeFragmentList.forEach(tf => {
|
||||
tableResults.unshift(transform(tf))
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
@ -317,7 +254,7 @@ const searchTt = () => {
|
||||
</button>
|
||||
</div>
|
||||
<div class="pointer-events-auto">
|
||||
<div id="ttchart" class="w-full h-60 input-btn-style mb-4"></div>
|
||||
<LineVue :option="chartOption" class="w-full h-64 mb-4"></LineVue>
|
||||
<div class="text-gray-500">
|
||||
<CmdResMenu title="invoked result" :map="trigerRes" v-if="trigerRes.size > 0">
|
||||
<template #headerAside>
|
||||
@ -334,7 +271,7 @@ const searchTt = () => {
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="normal-case" v-for="(v,i) in keyList" :key="i">{{v}}</th>
|
||||
<th class="normal-case" v-for="(v, i) in keyList" :key="i">{{ v }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="">
|
||||
@ -342,14 +279,14 @@ const searchTt = () => {
|
||||
<th class="">
|
||||
<button class="btn btn-primary btn-sm btn-outline" @click="reTrigger(map.get('index')!)">invoke</button>
|
||||
</th>
|
||||
<td class="" v-for="(key,j) in keyList" :key="j">
|
||||
<template v-if=" key !== 'params'">
|
||||
{{map.get(key)}}
|
||||
<td class="" v-for="(key, j) in keyList" :key="j">
|
||||
<template v-if="key !== 'params'">
|
||||
{{ map.get(key) }}
|
||||
</template>
|
||||
|
||||
<div class="flex flex-col" v-else>
|
||||
<div v-for="(row, k) in map.get(key)" :key="k">
|
||||
{{row}}
|
||||
{{ row }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@ -358,7 +295,7 @@ const searchTt = () => {
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="normal-case" v-for="(v,i) in keyList" :key="i">{{v}}</th>
|
||||
<th class="normal-case" v-for="(v, i) in keyList" :key="i">{{ v }}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
@ -129,14 +129,14 @@ const submit = async (data: { classItem: Item, methodItem: Item, conditon: strin
|
||||
<div class="overflow-x-auto w-full mt-4">
|
||||
<table class="table w-full table-compact">
|
||||
<thead>
|
||||
<tr>
|
||||
<tr >
|
||||
<th></th>
|
||||
<th class="0" v-for="(v, i) in keyList" :key="i">{{ v }}
|
||||
<th v-for="(v, i) in keyList" :key="i" class="normal-case">{{ v }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(map, i) in tableResults" :key="i" class="hover">
|
||||
<tr v-for="(map, i) in tableResults" :key="i" class="hover ">
|
||||
<th>{{ i + 1 }}</th>
|
||||
<td class="" v-for="(key, j) in keyList" :key="j">
|
||||
<div v-if="key !== 'value'">
|
||||
@ -151,7 +151,7 @@ const submit = async (data: { classItem: Item, methodItem: Item, conditon: strin
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="0" v-for="(v, i) in keyList" :key="i">{{ v }}
|
||||
<th class="normal-case" v-for="(v, i) in keyList" :key="i">{{ v }}
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
|
@ -200,7 +200,7 @@
|
||||
|
||||
"@xstate/vue@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmmirror.com/@xstate/vue/-/vue-2.0.0.tgz"
|
||||
resolved "https://registry.npmmirror.com/@xstate/vue/-/vue-2.0.0.tgz#bb95f91600c5fad2e8a72f872cb8f69b3b154e10"
|
||||
integrity sha512-JlrJ3d+I6rZCcFBuu3O4GP+mGJfd11O9o69wRedzPMqZ+hxcMRBsih9L5kKnJHcU9CTmdJTT172oxTaYF7thzA==
|
||||
|
||||
acorn-node@^1.8.2:
|
||||
|
Loading…
Reference in New Issue
Block a user