WIP #300 Performance page done. Use ref() instead of reactive() in independant Vue3 component.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Chart type="line" :data="freqChartData" :options="freqChartOptions" class="h-96" />
|
||||
<Chart type="line" :data="primeVueSetDataState" :options="primeVueSetOptionsState" class="h-96" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -19,51 +19,23 @@ const cloneDeep = (obj) => JSON.parse(JSON.stringify(obj));
|
||||
// 試著把 chart 獨立成一個 vue component
|
||||
// 企圖防止 PrimeVue 誤用其他圖表 option 值的 bug
|
||||
export default {
|
||||
setup() {
|
||||
props: {
|
||||
chartData: {
|
||||
type: Object,
|
||||
},
|
||||
content: {
|
||||
type: Object,
|
||||
},
|
||||
yUnit: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const performanceStore = usePerformanceStore();
|
||||
|
||||
const freqChartData = computed(() => performanceStore.freqChartData);
|
||||
const originalFreqChartOptions = computed(() => performanceStore.freqChartOptions);
|
||||
const minX = computed(() => performanceStore.freqChartXData.minX);
|
||||
const maxX = computed(() => performanceStore.freqChartXData.maxX);
|
||||
const xData = computed(() => performanceStore.freqChartXData.xData);
|
||||
const content = computed(() => performanceStore.freqChartXData.content);
|
||||
const customizedScaleOption = computed(() => {});
|
||||
|
||||
const updatedFreqChartOptions = ref(cloneDeep(originalFreqChartOptions.value));
|
||||
|
||||
const customizeOptionsFunc = () => {
|
||||
// Customize X axis ticks due to different differences between min and max of data group
|
||||
// Compare page and Performance page share the same logic
|
||||
const formatToSet = setTimeStringFormatBaseOnTimeDifference(minX.value, maxX.value);
|
||||
const ticksOfXAxis = mapTimestampToAxisTicksByFormat(xData.value, formatToSet);
|
||||
|
||||
|
||||
customizedScaleOption.value = getCustomizedScaleOption(
|
||||
knownScaleLineChartOptions, {
|
||||
customizeOptions: {
|
||||
content, ticksOfXAxis,
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const newTicksCallback = (value, index, values) => {
|
||||
return value; // 沒有單位,只有數值,因為是取計算數量
|
||||
};
|
||||
|
||||
const updateTicksCallback = () => {
|
||||
|
||||
//在這裡額外宣告本圖表的 callback, 區分跟其他圖表的 callback,避免共用 option 造成不預期的共用與混淆
|
||||
if (updatedFreqChartOptions.value.scales && updatedFreqChartOptions.value.scales.y) {
|
||||
updatedFreqChartOptions.value = customizedScaleOption;
|
||||
updatedFreqChartOptions.value.scales.y.ticks.callback = newTicksCallback;
|
||||
}
|
||||
};
|
||||
|
||||
watch(originalFreqChartOptions, (newOptions) => {
|
||||
updatedFreqChartOptions.value = cloneDeep(newOptions);
|
||||
});
|
||||
|
||||
const primeVueSetDataState = ref(null);
|
||||
const primeVueSetOptionsState = ref(null);
|
||||
|
||||
/**
|
||||
* Compare page and Performance have this same function.
|
||||
@@ -102,7 +74,7 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/** Compare page and Performance have this same function.
|
||||
@@ -140,14 +112,91 @@ export default {
|
||||
};
|
||||
};
|
||||
|
||||
const getLineChartPrimeVueSetting = (chartData, content) => {
|
||||
let datasets;
|
||||
let minX = chartData?.x_axis?.min;
|
||||
let maxX = chartData?.x_axis?.max;
|
||||
let maxY = chartData?.y_axis?.max;
|
||||
let xData;
|
||||
let primeVueSetData = {};
|
||||
let primeVueSetOption = {};
|
||||
const getMoment = (time)=> {
|
||||
return this.$moment(time).format('YYYY/M/D hh:mm:ss')
|
||||
};
|
||||
|
||||
datasets = chartData.data;
|
||||
xData = chartData.data.map(item => new Date(item.x).getTime());
|
||||
|
||||
// Customize X axis ticks due to different differences between min and max of data group
|
||||
// Compare page and Performance page share the same logic
|
||||
const formatToSet = setTimeStringFormatBaseOnTimeDifference(minX, maxX);
|
||||
const ticksOfXAxis = mapTimestampToAxisTicksByFormat(xData, formatToSet);
|
||||
const customizedScaleOption = getCustomizedScaleOption(
|
||||
knownScaleLineChartOptions, {
|
||||
customizeOptions: {
|
||||
content, ticksOfXAxis,
|
||||
}
|
||||
});
|
||||
|
||||
primeVueSetData = {
|
||||
labels: xData,
|
||||
datasets: [
|
||||
{
|
||||
label: content.title,
|
||||
data: datasets,
|
||||
fill: false,
|
||||
tension: 0, // 貝茲曲線張力
|
||||
borderColor: '#0099FF',
|
||||
}
|
||||
]
|
||||
};
|
||||
primeVueSetOption = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
layout: {
|
||||
padding: {
|
||||
top: 16,
|
||||
left: 8,
|
||||
right: 8,
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: false, // 圖例
|
||||
tooltip: {
|
||||
displayColors: false,
|
||||
titleFont: {weight: 'normal'},
|
||||
callbacks: {
|
||||
title: function(context) {
|
||||
return `${content.x}: ${getMoment(context[0].parsed.x)}`;
|
||||
}
|
||||
},
|
||||
},
|
||||
title: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
scales: customizedScaleOption,
|
||||
};
|
||||
|
||||
primeVueSetOption.scales.y.ticks.precision = 0; // y 軸顯示小數點後 0 位
|
||||
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||
return `${content.y}: ${context.parsed.y}`;
|
||||
};
|
||||
primeVueSetOption.scales.y.ticks.callback = function (value, index, ticks) {
|
||||
return value;
|
||||
};
|
||||
primeVueSetDataState.value = primeVueSetData;
|
||||
primeVueSetOptionsState.value = primeVueSetOption;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
customizeOptionsFunc();
|
||||
getLineChartPrimeVueSetting(props.chartData, props.content);
|
||||
});
|
||||
|
||||
return {
|
||||
freqChartData,
|
||||
updatedFreqChartOptions,
|
||||
updateTicksCallback,
|
||||
...props,
|
||||
primeVueSetDataState,
|
||||
primeVueSetOptionsState,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user