Translate all Chinese comments and strings to English
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -317,7 +317,7 @@ const convertSecToDay = (sec) => {
|
||||
* @param {number} no - The trace number.
|
||||
*/
|
||||
const openMore = async (no) => {
|
||||
// async await 解決非同步資料延遲傳遞導致未讀取到而出錯的問題
|
||||
// Use async/await to prevent errors caused by asynchronous data not being available yet
|
||||
issuesNo.value = no;
|
||||
await conformanceStore.getConformanceIssue(no);
|
||||
traceId.value = await issueTraces.value[0].id;
|
||||
@@ -330,7 +330,7 @@ const openMore = async (no) => {
|
||||
* @param {number} no - The trace number.
|
||||
*/
|
||||
const openLoopMore = async (no) => {
|
||||
// async await 解決非同步資料延遲傳遞導致未讀取到而出錯的問題
|
||||
// Use async/await to prevent errors caused by asynchronous data not being available yet
|
||||
loopNo.value = no;
|
||||
await conformanceStore.getConformanceLoop(no);
|
||||
looptraceId.value = await loopTraces.value[0].id;
|
||||
@@ -428,9 +428,9 @@ const setConformanceTempReportData = (newData) => {
|
||||
result.timeTrend.yMin = newData.charts.time.y_axis.min;
|
||||
}
|
||||
|
||||
setRateChartData(result.charts.rate.data); // 建立圖表 Rate Chart.js
|
||||
setCasesChartData(result.charts.cases.data.conforming, result.charts.cases.data.not_conforming, newData.charts.cases.x_axis.max, newData.charts.cases.x_axis.min); // 建立圖表 Cases Chart.js
|
||||
if(newData.charts.time) setTimeChartData(result.timeTrend.chart, result.timeTrend.xMax, result.timeTrend.xMin, result.timeTrend.yMax, result.timeTrend.yMin); // 建立圖表 Time Chart.js
|
||||
setRateChartData(result.charts.rate.data); // Build the Rate Chart.js chart
|
||||
setCasesChartData(result.charts.cases.data.conforming, result.charts.cases.data.not_conforming, newData.charts.cases.x_axis.max, newData.charts.cases.x_axis.min); // Build the Cases Chart.js chart
|
||||
if(newData.charts.time) setTimeChartData(result.timeTrend.chart, result.timeTrend.xMax, result.timeTrend.xMin, result.timeTrend.yMax, result.timeTrend.yMin); // Build the Time Chart.js chart
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -446,8 +446,8 @@ const setRateChartData = (chartData) => {
|
||||
label: 'Rate',
|
||||
data: chartData,
|
||||
fill: false,
|
||||
pointRadius: 0, // 隱藏點
|
||||
pointHoverRadius: 0, // 隱藏點的 hover
|
||||
pointRadius: 0, // Hide data points
|
||||
pointHoverRadius: 0, // Hide data points on hover
|
||||
tension: 0.4,
|
||||
borderColor: '#0099FF',
|
||||
x: 'x',
|
||||
@@ -467,9 +467,9 @@ const setRateChartData = (chartData) => {
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: false, // 圖例
|
||||
legend: false, // Hide legend
|
||||
tooltip: {
|
||||
enabled: false // 隱藏 工具提示框
|
||||
enabled: false // Hide tooltip
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
@@ -479,17 +479,17 @@ const setRateChartData = (chartData) => {
|
||||
display: false,
|
||||
},
|
||||
grid: {
|
||||
display: false, // 隱藏 x 軸網格
|
||||
display: false, // Hide x-axis grid lines
|
||||
},
|
||||
border: {
|
||||
color: '#334155',
|
||||
},
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true, // scale 包含 0
|
||||
beginAtZero: true, // Scale includes 0
|
||||
suggestedMin: 0,
|
||||
suggestedMax: 1,
|
||||
ticks:{ // 設定間隔數值
|
||||
ticks:{ // Set tick intervals
|
||||
includeBounds: true,
|
||||
color: '#334155',
|
||||
align: 'inner',
|
||||
@@ -500,7 +500,7 @@ const setRateChartData = (chartData) => {
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
display: false, // 隱藏 y 軸網格
|
||||
display: false, // Hide y-axis grid lines
|
||||
},
|
||||
border: {
|
||||
color: '#334155',
|
||||
@@ -550,7 +550,7 @@ const setCasesChartData = (conformingData, notConformingData, xMax, xMin) => {
|
||||
mode: 'index',
|
||||
intersect: false
|
||||
},
|
||||
legend: false, // 圖例
|
||||
legend: false, // Hide legend
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
@@ -559,7 +559,7 @@ const setCasesChartData = (conformingData, notConformingData, xMax, xMin) => {
|
||||
display: false,
|
||||
},
|
||||
grid: {
|
||||
display: false, // 隱藏 x 軸網格
|
||||
display: false, // Hide x-axis grid lines
|
||||
},
|
||||
border: {
|
||||
color: '#334155',
|
||||
@@ -567,7 +567,7 @@ const setCasesChartData = (conformingData, notConformingData, xMax, xMin) => {
|
||||
},
|
||||
y: {
|
||||
stacked: true,
|
||||
beginAtZero: true, // scale 包含 0
|
||||
beginAtZero: true, // Scale includes 0
|
||||
ticks:{
|
||||
color: '#334155',
|
||||
align: 'inner',
|
||||
@@ -578,7 +578,7 @@ const setCasesChartData = (conformingData, notConformingData, xMax, xMin) => {
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
// display: false, // 隱藏 y 軸網格
|
||||
// display: false, // Hide y-axis grid lines
|
||||
color: function(context) {
|
||||
return context.tick.value === 0 ? '#334155' : null;
|
||||
},
|
||||
@@ -647,18 +647,18 @@ const setTimeChartData = (chartData, xMax, xMin, yMax, yMin) => {
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: false, // 圖例
|
||||
legend: false, // Hide legend
|
||||
tooltip: false,
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
maxRotation: 0, // 不旋轉 lable 0~50
|
||||
maxRotation: 0, // Do not rotate labels (0~50)
|
||||
color: '#334155',
|
||||
display: true,
|
||||
},
|
||||
grid: {
|
||||
display: false, // 隱藏 x 軸網格
|
||||
display: false, // Hide x-axis grid lines
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
@@ -667,18 +667,18 @@ const setTimeChartData = (chartData, xMax, xMin, yMax, yMin) => {
|
||||
},
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true, // scale 包含 0
|
||||
beginAtZero: true, // Scale includes 0
|
||||
max: max,
|
||||
ticks: { // 設定間隔數值
|
||||
display: false, // 隱藏數值,只顯示格線
|
||||
ticks: { // Set tick intervals
|
||||
display: false, // Hide values, only show grid lines
|
||||
stepSize: max / 4,
|
||||
},
|
||||
grid: {
|
||||
color: 'rgba(100,116,139)',
|
||||
drawTicks: false // 隱藏左側多的空間
|
||||
drawTicks: false // Hide extra space on the left
|
||||
},
|
||||
border: {
|
||||
display: false, // 隱藏左側多出來的線
|
||||
display: false, // Hide the extra border line on the left
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
@@ -705,7 +705,7 @@ watch(conformanceTempReportData, (newValue) => {
|
||||
emitter.on('coverPlate', boolean => {
|
||||
isCoverPlate.value = boolean;
|
||||
});
|
||||
// 取得 selectTimeTange 給 Tiem Trend 使用
|
||||
// Get selectTimeRange for use by Time Trend
|
||||
emitter.on('timeRangeMaxMin', newData => selectDurationTime.value = newData);
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
@@ -201,7 +201,7 @@ const selectCfmCtEteEnd = ref(null);
|
||||
const selectCfmCtEteSEStart = ref(null);
|
||||
const selectCfmCtEteSEEnd = ref(null);
|
||||
const isAlreadySubmit = ref(false);
|
||||
const isSubmittedData = ref(null); // 已 Apply 後,沒有重新改變規則的 Data
|
||||
const isSubmittedData = ref(null); // Data after Apply, unchanged unless rules are modified
|
||||
const isSubmitTask = ref(null);
|
||||
const isSubmitStartAndEnd = ref(null); // Activity sequence
|
||||
const isSubmitCfmSeqDirectly = ref([]);
|
||||
@@ -247,7 +247,7 @@ const isSubmitShowDataSeq = ref({
|
||||
taskEnd: null,
|
||||
isStartSelected: null,
|
||||
isEndSelected: null
|
||||
}); // To Start & End 連動資料
|
||||
}); // Linked data for Start & End
|
||||
const isSubmitShowDataPtEte = ref({
|
||||
task: null,
|
||||
taskStart: null,
|
||||
@@ -348,7 +348,7 @@ watch(isSubmittedData, (newValue) => {
|
||||
isSubmittedData.value = newValue;
|
||||
});
|
||||
|
||||
// 打開 rule 檔要顯示儲存的選項、規則、時間
|
||||
// When opening a rule file, display the saved options, rules, and time
|
||||
watch(conformanceTempReportData, (newValue) => {
|
||||
setTimeout(() => {
|
||||
if(newValue !== null) {
|
||||
@@ -357,11 +357,11 @@ watch(conformanceTempReportData, (newValue) => {
|
||||
isSubmittedData.value = newValue.rule;
|
||||
isAlreadySubmit.value = true;
|
||||
switch (rule.type) {
|
||||
case 'contains-tasks': // Rule Type 選 Have activity 的行為
|
||||
case 'contains-tasks': // Behavior when Rule Type is Have activity
|
||||
selectedRuleType.value = 'Have activity';
|
||||
isSubmitTask.value = rule.tasks;
|
||||
break;
|
||||
case 'start-end': // Rule Type 選 Activity sequence 的行為
|
||||
case 'start-end': // Behavior when Rule Type is Activity sequence
|
||||
selectedRuleType.value = 'Activity sequence';
|
||||
selectedActivitySequence.value = 'Start & End';
|
||||
isSubmitStartAndEnd.value = [
|
||||
@@ -369,7 +369,7 @@ watch(conformanceTempReportData, (newValue) => {
|
||||
{category: 'End', task: rule.ends_with},
|
||||
];
|
||||
break;
|
||||
case 'directly-follows': // Activity Sequence 選 Sequence 的行為
|
||||
case 'directly-follows': // Behavior when Activity Sequence is Sequence
|
||||
selectedRuleType.value = 'Activity sequence';
|
||||
selectedActivitySequence.value = 'Sequence';
|
||||
selectedMode.value = 'Directly follows';
|
||||
@@ -391,7 +391,7 @@ watch(conformanceTempReportData, (newValue) => {
|
||||
selectedActivitySequence.value = 'Sequence';
|
||||
selectedMode.value = 'Self loop(s)';
|
||||
break;
|
||||
case 'task-duration': // Rule Type 選 Activity duration 的行為
|
||||
case 'task-duration': // Behavior when Rule Type is Activity duration
|
||||
selectedRuleType.value = 'Activity duration';
|
||||
selectDurationData.value = [rule.task];
|
||||
isSubmitDurationData.value = [rule.task];
|
||||
@@ -400,7 +400,7 @@ watch(conformanceTempReportData, (newValue) => {
|
||||
rule: { min: rule.min, max: rule.max},
|
||||
};
|
||||
break;
|
||||
case 'processing-time-end-to-end-whole': // Rule Type 選 Processing time 的行為
|
||||
case 'processing-time-end-to-end-whole': // Behavior when Rule Type is Processing time
|
||||
selectedRuleType.value = 'Processing time';
|
||||
selectedProcessScope.value = 'End to end';
|
||||
selectedActSeqMore.value = 'All';
|
||||
@@ -489,7 +489,7 @@ watch(conformanceTempReportData, (newValue) => {
|
||||
};
|
||||
isSubmitShowDataPtP.value = setSubmitShowDataByStartEnd(rule.start, rule.end);
|
||||
break;
|
||||
case 'waiting-time-end-to-end-whole': // Rule Type 選 Waiting time 的行為
|
||||
case 'waiting-time-end-to-end-whole': // Behavior when Rule Type is Waiting time
|
||||
selectedRuleType.value = 'Waiting time';
|
||||
selectedProcessScope.value = 'End to end';
|
||||
selectedActSeqMore.value = 'All';
|
||||
@@ -578,7 +578,7 @@ watch(conformanceTempReportData, (newValue) => {
|
||||
};
|
||||
isSubmitShowDataWtP.value = setSubmitShowDataByStartEnd(rule.start, rule.end);
|
||||
break;
|
||||
case 'cycle-time-end-to-end-whole': // Rule Type 選 Cycle time 的行為
|
||||
case 'cycle-time-end-to-end-whole': // Behavior when Rule Type is Cycle time
|
||||
selectedRuleType.value = 'Cycle time';
|
||||
selectedProcessScope.value = 'End to end';
|
||||
selectedActSeqMore.value = 'All';
|
||||
@@ -651,7 +651,7 @@ function maxTotalSeconds(e) {
|
||||
* select Time Reset
|
||||
*/
|
||||
function selectTimeReset() {
|
||||
// 不包含 selectDurationTime
|
||||
// Does not include selectDurationTime
|
||||
selectConformanceTask.value = null; // Have activity
|
||||
selectConformanceStartAndEnd.value = null; // Activity Sequence
|
||||
selectCfmSeqStart.value = null;
|
||||
@@ -686,7 +686,7 @@ function selectTimeReset() {
|
||||
* is submit select Reset
|
||||
*/
|
||||
function isSubmitReset() {
|
||||
// 不包含 isSubmittedData
|
||||
// Does not include isSubmittedData
|
||||
isSubmitTask.value = null;
|
||||
isSubmitStartAndEnd.value = null;
|
||||
isSubmitCfmSeqDirectly.value = [];
|
||||
@@ -731,17 +731,17 @@ function isSubmitReset() {
|
||||
* Clears all form selections and resets the sidebar state.
|
||||
*/
|
||||
function reset() {
|
||||
// Results page Cover Plate(遮罩為 ture)
|
||||
// Results page cover plate (mask enabled)
|
||||
emitter.emit('coverPlate', true);
|
||||
// is submit select Reset
|
||||
isSubmitReset();
|
||||
isSubmittedData.value = null; // 已 Apply 後,沒有重新改變規則的 Data
|
||||
isSubmittedData.value = null; // Data after Apply, unchanged unless rules are modified
|
||||
isAlreadySubmit.value = false;
|
||||
|
||||
// 其他子元件 reset
|
||||
// Reset other child components
|
||||
selectTimeReset();
|
||||
emitter.emit('reset', null);
|
||||
// reset 成功訊息
|
||||
// Reset success message
|
||||
$toast.success(i18next.t("Conformance.RuleCleared"));
|
||||
isShowBarOpen.value = true;
|
||||
}
|
||||
@@ -783,22 +783,22 @@ async function submitConformance() {
|
||||
emitter.emit('timeRangeMaxMin', selectDurationTime.value);
|
||||
|
||||
switch (selectedRuleType.value) {
|
||||
case 'Have activity': // Rule Type 選 Have activity 的行為
|
||||
case 'Have activity': // Behavior when Rule Type is Have activity
|
||||
dataToSave = getHaveActivityData();
|
||||
break;
|
||||
case 'Activity sequence': // Rule Type 選 Activity sequence 的行為
|
||||
case 'Activity sequence': // Behavior when Rule Type is Activity sequence
|
||||
dataToSave = getActivitySequenceData();
|
||||
break;
|
||||
case 'Activity duration': // Rule Type 選 Activity duration 的行為
|
||||
case 'Activity duration': // Behavior when Rule Type is Activity duration
|
||||
dataToSave = getActivityDurationData();
|
||||
break;
|
||||
case 'Processing time': // Rule Type 選 Processing time 的行為
|
||||
case 'Processing time': // Behavior when Rule Type is Processing time
|
||||
dataToSave = getProcessingTimeData();
|
||||
break;
|
||||
case 'Waiting time': // Rule Type 選 Waiting time 的行為
|
||||
case 'Waiting time': // Behavior when Rule Type is Waiting time
|
||||
dataToSave = getWaitingTimeData();
|
||||
break;
|
||||
case 'Cycle time': // Rule Type 選 Cycle time 的行為
|
||||
case 'Cycle time': // Behavior when Rule Type is Cycle time
|
||||
dataToSave = getCycleTimeData();
|
||||
break;
|
||||
}
|
||||
@@ -812,8 +812,8 @@ async function submitConformance() {
|
||||
|
||||
isLoading.value = true;
|
||||
isAlreadySubmit.value = true;
|
||||
isSubmittedData.value = dataToSave; // 已 Apply 後,沒有重新改變規則的 Data
|
||||
conformanceRuleData.value = dataToSave; // 給存檔的 Data
|
||||
isSubmittedData.value = dataToSave; // Data after Apply, unchanged unless rules are modified
|
||||
conformanceRuleData.value = dataToSave; // Data for saving to file
|
||||
await conformanceStore.addConformanceCheckId(dataToSave);
|
||||
await conformanceStore.getConformanceReport();
|
||||
isShowBarOpen.value = false;
|
||||
@@ -1580,7 +1580,7 @@ function checkStartAndEnd(start, end) {
|
||||
|
||||
// created() logic
|
||||
isShowBarOpen.value = !(conformanceLogCreateCheckId.value || conformanceFilterCreateCheckId.value);
|
||||
// 選取 list 的結果
|
||||
// Result of list selection
|
||||
emitter.on('actListData', (data) => {
|
||||
selectConformanceTask.value = data;
|
||||
});
|
||||
@@ -1588,7 +1588,7 @@ emitter.on('actListData', (data) => {
|
||||
setTaskByCategoryOnRadioEmitting();
|
||||
setTaskByCategoryOnListSeqEmitting();
|
||||
|
||||
// Radio 切換時,資料要清空
|
||||
// Clear data when radio selection changes
|
||||
emitter.on('isRadioChange', (data) => {
|
||||
if(data) {
|
||||
selectTimeReset();
|
||||
|
||||
@@ -65,7 +65,7 @@ const lastItemIndex = ref(null);
|
||||
const isSelect = ref(true);
|
||||
|
||||
const datadata = computed(() => {
|
||||
// Activity List 要排序
|
||||
// Sort the Activity List
|
||||
let newData;
|
||||
if(props.data !== null) {
|
||||
newData = JSON.parse(JSON.stringify(props.data));
|
||||
@@ -108,10 +108,10 @@ function getComponentData() {
|
||||
function onStart(evt) {
|
||||
const lastChild = evt.to.lastChild.lastChild;
|
||||
lastChild.style.display = 'none';
|
||||
// 隱藏拖曳元素原位置
|
||||
// Hide the dragged element at its original position
|
||||
const originalElement = evt.item;
|
||||
originalElement.style.display = 'none';
|
||||
// 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
||||
// When dragging the last element, hide the arrow of the second-to-last element
|
||||
const listIndex = listSequence.value.length - 1;
|
||||
if(evt.oldIndex === listIndex) lastItemIndex.value = listIndex;
|
||||
}
|
||||
@@ -120,16 +120,16 @@ function onStart(evt) {
|
||||
* Element dragging ended
|
||||
*/
|
||||
function onEnd(evt) {
|
||||
// 顯示拖曳元素
|
||||
// Show the dragged element
|
||||
const originalElement = evt.item;
|
||||
originalElement.style.display = '';
|
||||
// 拖曳結束要顯示箭頭,但最後一個不用
|
||||
// Show the arrow after drag ends, except for the last element
|
||||
const lastChild = evt.item.lastChild;
|
||||
const listIndex = listSequence.value.length - 1;
|
||||
if (evt.oldIndex !== listIndex) {
|
||||
lastChild.style.display = '';
|
||||
}
|
||||
// reset: 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
||||
// Reset: hide the second-to-last element's arrow when dragging the last element
|
||||
lastItemIndex.value = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ function changeRadio() {
|
||||
selectedProcessScope.value = 'End to end';
|
||||
selectedActSeqMore.value = 'All';
|
||||
selectedActSeqFromTo.value = 'From';
|
||||
emitter.emit('isRadioChange', true); // Radio 切換時,資料要清空
|
||||
emitter.emit('isRadioChange', true); // Clear data when switching radio buttons
|
||||
}
|
||||
/** Emits event when the activity sequence radio changes. */
|
||||
function changeRadioSeq() {
|
||||
|
||||
@@ -190,7 +190,7 @@ emitter.on('actListData', (data) => {
|
||||
state.containstTasksData = data;
|
||||
});
|
||||
emitter.on('actRadioData', (newData) => {
|
||||
const data = JSON.parse(JSON.stringify(newData)); // 深拷貝原始 cases 的內容
|
||||
const data = JSON.parse(JSON.stringify(newData)); // Deep copy the original cases data
|
||||
|
||||
const categoryMapping = {
|
||||
'cfmSeqStart': ['Start', 'selectCfmSeqStart', 'selectCfmSeqEnd'],
|
||||
@@ -252,7 +252,7 @@ emitter.on('getListSequence', (data) => {
|
||||
emitter.on('reset', (data) => {
|
||||
reset();
|
||||
});
|
||||
// Radio 切換時,資料要清空
|
||||
// Clear data when switching radio buttons
|
||||
emitter.on('isRadioChange', (data) => {
|
||||
if(data) reset();
|
||||
});
|
||||
|
||||
@@ -224,7 +224,7 @@ const cfmCtEteSEEndData = computed(() => {
|
||||
return isStartSelected.value ? setStartAndEndData(cfmCtEteSE.value, 'start', task.value) : setTaskData(cfmCtEteSE.value, 'end');
|
||||
});
|
||||
|
||||
// Watchers - 解決儲存後的 Rule 檔,無法重新更改規則之問題
|
||||
// Watchers - Fix issue where saved rule files could not be re-edited
|
||||
watch(() => props.isSubmitShowDataSeq, (newValue) => {
|
||||
taskStart.value = newValue.taskStart;
|
||||
taskEnd.value = newValue.taskEnd;
|
||||
@@ -258,7 +258,7 @@ watch(() => props.isSubmitShowDataCt, (newValue) => {
|
||||
*/
|
||||
function setTaskData(data, category) {
|
||||
let newData = data.map(i => i[category]);
|
||||
newData = [...new Set(newData)]; // Set 是一種集合型別,只會儲存獨特的值。
|
||||
newData = [...new Set(newData)]; // Set is a collection type that only stores unique values.
|
||||
return newData;
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,7 @@ const durationMax = ref(null);
|
||||
|
||||
/** Deep-copies timeData min/max values to the Vue component boundaries. */
|
||||
function setTimeValue() {
|
||||
// 深拷貝原始 timeData 的內容
|
||||
// Deep copy the original timeData values
|
||||
minVuemin.value = JSON.parse(JSON.stringify(timeData.value.min));
|
||||
minVuemax.value = JSON.parse(JSON.stringify(timeData.value.max));
|
||||
maxVuemin.value = JSON.parse(JSON.stringify(timeData.value.min));
|
||||
|
||||
@@ -93,7 +93,7 @@ const contentClass = ref('!bg-neutral-100 border-t border-neutral-300 h-full');
|
||||
const showTraceId = ref(null);
|
||||
const infiniteData = ref(null);
|
||||
const maxItems = ref(false);
|
||||
const infiniteFinish = ref(true); // 無限滾動是否載入完成
|
||||
const infiniteFinish = ref(true); // Whether infinite scroll loading is complete
|
||||
const startNum = ref(0);
|
||||
const processMap = ref({
|
||||
nodes:[],
|
||||
@@ -121,24 +121,24 @@ const traceList = computed(() => {
|
||||
|
||||
const caseData = computed(() => {
|
||||
if(infiniteData.value !== null){
|
||||
const data = JSON.parse(JSON.stringify(infiniteData.value)); // 深拷貝原始 cases 的內容
|
||||
const data = JSON.parse(JSON.stringify(infiniteData.value)); // Deep copy the original cases data
|
||||
data.forEach(item => {
|
||||
item.facets.forEach((facet, index) => {
|
||||
item[`fac_${index}`] = facet.value; // 建立新的 key-value pair
|
||||
item[`fac_${index}`] = facet.value; // Create a new key-value pair
|
||||
});
|
||||
delete item.facets; // 刪除原本的 facets 屬性
|
||||
delete item.facets; // Remove the original facets property
|
||||
|
||||
item.attributes.forEach((attribute, index) => {
|
||||
item[`att_${index}`] = attribute.value; // 建立新的 key-value pair
|
||||
item[`att_${index}`] = attribute.value; // Create a new key-value pair
|
||||
});
|
||||
delete item.attributes; // 刪除原本的 attributes 屬性
|
||||
delete item.attributes; // Remove the original attributes property
|
||||
})
|
||||
return data;
|
||||
}
|
||||
});
|
||||
|
||||
const columnData = computed(() => {
|
||||
const data = JSON.parse(JSON.stringify(props.cases)); // 深拷貝原始 cases 的內容
|
||||
const data = JSON.parse(JSON.stringify(props.cases)); // Deep copy the original cases data
|
||||
const facetName = facName => facName.trim().replace(/^(.)(.*)$/, (match, firstChar, restOfString) => firstChar.toUpperCase() + restOfString.toLowerCase());
|
||||
|
||||
const result = [
|
||||
@@ -152,7 +152,7 @@ const columnData = computed(() => {
|
||||
});
|
||||
|
||||
// watch
|
||||
watch(() => props.listModal, (newValue) => { // 第一次打開 Modal 要繪圖
|
||||
watch(() => props.listModal, (newValue) => { // Draw the chart when the modal is opened for the first time
|
||||
if(newValue) createCy();
|
||||
});
|
||||
|
||||
@@ -161,7 +161,7 @@ watch(() => props.taskSeq, (newValue) => {
|
||||
});
|
||||
|
||||
watch(() => props.traceId, (newValue) => {
|
||||
// 當 traceId 屬性變化時更新 showTraceId
|
||||
// Update showTraceId when the traceId prop changes
|
||||
showTraceId.value = newValue;
|
||||
});
|
||||
|
||||
@@ -210,15 +210,15 @@ async function switchCaseData(id) {
|
||||
if(props.category === 'issue') result = await conformanceStore.getConformanceTraceDetail(props.listNo, id, 0);
|
||||
else if(props.category === 'loop') result = await conformanceStore.getConformanceLoopsTraceDetail(props.listNo, id, 0);
|
||||
infiniteData.value = await result;
|
||||
showTraceId.value = id; // 放 getDetail 為了 case table 載入完再切換 showTraceId
|
||||
showTraceId.value = id; // Set after getDetail so the case table finishes loading before switching showTraceId
|
||||
}
|
||||
/**
|
||||
* Assembles the trace element nodes data for Cytoscape rendering.
|
||||
*/
|
||||
function setNodesData(){
|
||||
// 避免每次渲染都重複累加
|
||||
// Clear nodes to prevent accumulation on each render
|
||||
processMap.value.nodes = [];
|
||||
// 將 api call 回來的資料帶進 node
|
||||
// Populate nodes with data returned from the API call
|
||||
if(props.taskSeq !== null) {
|
||||
props.taskSeq.forEach((node, index) => {
|
||||
processMap.value.nodes.push({
|
||||
@@ -252,7 +252,7 @@ function setEdgesData(){
|
||||
});
|
||||
});
|
||||
};
|
||||
// 關係線數量筆節點少一個
|
||||
// The number of edges is one less than the number of nodes
|
||||
processMap.value.edges.pop();
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -93,7 +93,7 @@ const filteredData = ref(props.filterTaskData);
|
||||
const lastItemIndex = ref(null);
|
||||
|
||||
const data = computed(() => {
|
||||
// Activity List 要排序
|
||||
// Sort the Activity List
|
||||
filteredData.value = filteredData.value.sort((x, y) => {
|
||||
const diff = y.occurrences - x.occurrences;
|
||||
return diff !== 0 ? diff : sortNumEngZhtwForFilter(x.label, y.label);
|
||||
@@ -139,10 +139,10 @@ function getComponentData() {
|
||||
function onStart(evt) {
|
||||
const lastChild = evt.to.lastChild.lastChild;
|
||||
lastChild.style.display = 'none';
|
||||
// 隱藏拖曳元素原位置
|
||||
// Hide the dragged element at its original position
|
||||
const originalElement = evt.item;
|
||||
originalElement.style.display = 'none';
|
||||
// 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
||||
// When dragging the last element, hide the arrow of the second-to-last element
|
||||
const listIndex = listSequence.value.length - 1;
|
||||
if(evt.oldIndex === listIndex) lastItemIndex.value = listIndex;
|
||||
}
|
||||
@@ -152,16 +152,16 @@ function onStart(evt) {
|
||||
* @param {Event} evt - The drag end event.
|
||||
*/
|
||||
function onEnd(evt) {
|
||||
// 顯示拖曳元素
|
||||
// Show the dragged element
|
||||
const originalElement = evt.item;
|
||||
originalElement.style.display = '';
|
||||
// 拖曳結束要顯示箭頭,但最後一個不用
|
||||
// Show the arrow after drag ends, except for the last element
|
||||
const lastChild = evt.item.lastChild;
|
||||
const listIndex = listSequence.value.length - 1
|
||||
if (evt.oldIndex !== listIndex) {
|
||||
lastChild.style.display = '';
|
||||
}
|
||||
// reset: 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
||||
// Reset: hide the second-to-last element's arrow when dragging the last element
|
||||
lastItemIndex.value = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</ColumnGroup>
|
||||
<Column selectionMode="single" bodyClass="!p-2 !border-0"></Column>
|
||||
<Column field="label" header="Activity" bodyClass="break-words !py-2 !border-0"></Column>
|
||||
<Column header="進度條" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<Column header="Progress" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<template #body="slotProps">
|
||||
<div class="h-4 w-full bg-neutral-300 rounded-sm overflow-hidden">
|
||||
<div class="h-full bg-primary" :style="progressWidth(slotProps.data.occ_value)"></div>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</ColumnGroup>
|
||||
<Column selectionMode="multiple" bodyClass="!p-2 !border-0"></Column>
|
||||
<Column field="label" header="Activity" bodyClass="break-words !py-2 !border-0"></Column>
|
||||
<Column header="進度條" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<Column header="Progress" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<template #body="slotProps">
|
||||
<div class="h-4 w-full bg-neutral-300 rounded-sm overflow-hidden">
|
||||
<div class="h-full bg-primary" :style="progressWidth(slotProps.data.occ_value)"></div>
|
||||
@@ -25,7 +25,7 @@
|
||||
</Column>
|
||||
<Column field="occurrences" header="Occurrences" bodyClass="!text-right !py-2 !border-0"></Column>
|
||||
<Column field="occurrence_ratio" header="O2" bodyClass="!text-right !py-2 !border-0"></Column>
|
||||
<Column header="進度條" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<Column header="Progress" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<template #body="slotProps">
|
||||
<div class="h-4 w-full bg-neutral-300 rounded-sm overflow-hidden">
|
||||
<div class="h-full bg-primary" :style="progressWidth(slotProps.data.case_value)"></div>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
<Column header="進度條" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<Column header="Progress" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<template #body="slotProps">
|
||||
<div class="h-4 w-full bg-neutral-300 rounded-sm overflow-hidden">
|
||||
<div class="h-full bg-primary" :style="progressWidth(slotProps.data.occ_progress_bar)"></div>
|
||||
@@ -71,7 +71,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
<Column header="進度條" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<Column header="Progress" bodyClass="!py-2 !border-0 min-w-[96px]">
|
||||
<template #body="slotProps">
|
||||
<div class="h-4 w-full bg-neutral-300 rounded-sm overflow-hidden">
|
||||
<div class="h-full bg-primary" :style="progressWidth(slotProps.data.occ_progress_bar)"></div>
|
||||
@@ -152,9 +152,9 @@ const valueTypes = ['int', 'float', 'date'];
|
||||
const classTypes = ['boolean', 'string'];
|
||||
const chartData = ref({});
|
||||
const chartOptions = ref({});
|
||||
const chartComplete = ref(null); // 已出圖的 chart.js 資料
|
||||
const chartComplete = ref(null); // Rendered chart.js instance data
|
||||
const selectArea = ref(null);
|
||||
const selectRange = ref(1000); // 更改 select 的切分數
|
||||
const selectRange = ref(1000); // Number of divisions for the selection range
|
||||
const startTime = ref(null); // PrimeVue Calendar v-model
|
||||
const endTime = ref(null); // PrimeVue Calendar v-model
|
||||
const startMinDate = ref(null);
|
||||
@@ -162,7 +162,7 @@ const startMaxDate = ref(null);
|
||||
const endMinDate = ref(null);
|
||||
const endMaxDate = ref(null);
|
||||
const valueStart = ref(null); // PrimeVue InputNumber v-model
|
||||
const valueEnd = ref(null); // PrimeVue InputNumber v-model
|
||||
const valueEnd = ref(null); // PrimeVue InputNumber v-model
|
||||
const valueStartMin = ref(null);
|
||||
const valueStartMax = ref(null);
|
||||
const valueEndMin = ref(null);
|
||||
@@ -226,16 +226,16 @@ const attRangeData = computed(() => {
|
||||
return data.sort((x, y) => y.freq - x.freq);
|
||||
});
|
||||
|
||||
// 取出選取的 Attribute radio 數值型的資料
|
||||
// Get the selected Attribute radio's numeric-type data
|
||||
const valueData = computed(() => {
|
||||
// filter 回傳陣列,find 回傳遞一個找到的元素,因此使用 find 方法。
|
||||
// filter returns an array, find returns the first matched element, so use find here.
|
||||
if(valueTypes.includes(selectedAttName.value.type)){
|
||||
const data = filterAttrs.value.find(item => item.type === selectedAttName.value.type && item.key === selectedAttName.value.key);
|
||||
return data
|
||||
}
|
||||
});
|
||||
|
||||
// 找出 slidrData,時間格式:毫秒時間戳
|
||||
// Compute slider data; time format: millisecond timestamps
|
||||
const sliderDataComputed = computed(() => {
|
||||
let xAxisMin;
|
||||
let xAxisMax;
|
||||
@@ -298,7 +298,7 @@ const attValueTypeStartEnd = computed(() => {
|
||||
end = valueEnd.value;
|
||||
break;
|
||||
}
|
||||
const data = { // 傳給後端的資料
|
||||
const data = { // Data to send to the backend
|
||||
type: type,
|
||||
data: {
|
||||
key: selectedAttName.value.key,
|
||||
@@ -385,43 +385,43 @@ function switchAttNameRadio(e) {
|
||||
endTime.value = null;
|
||||
valueStart.value = null;
|
||||
valueEnd.value = null;
|
||||
if(valueData.value) { // 切換 Attribute Name
|
||||
// 初始化雙向綁定
|
||||
if(valueData.value) { // Switch Attribute Name
|
||||
// Initialize two-way bindings
|
||||
selectArea.value = [0, selectRange.value];
|
||||
const min = valueData.value.min;
|
||||
const max = valueData.value.max;
|
||||
switch (selectedAttName.value.type) {
|
||||
case 'dummy': //sonar-qube
|
||||
case 'date':
|
||||
// 除了 date 外雙向綁定為空
|
||||
// Clear two-way bindings except for date
|
||||
valueStart.value = null;
|
||||
valueEnd.value = null;
|
||||
// 初始化: Calendar
|
||||
// Initialize Calendar
|
||||
startMinDate.value = new Date(min);
|
||||
startMaxDate.value = new Date(max);
|
||||
endMinDate.value = new Date(min);
|
||||
endMaxDate.value = new Date(max);
|
||||
// 初始化: 讓日曆的範圍等於時間軸的範圍
|
||||
// Initialize: set the calendar range to match the timeline range
|
||||
startTime.value = new Date(min);
|
||||
endTime.value = new Date(max);
|
||||
break;
|
||||
default:
|
||||
// date 雙向綁定為空
|
||||
// Clear date two-way bindings
|
||||
startTime.value = null;
|
||||
endTime.value = null;
|
||||
// 初始化:InputNumber
|
||||
// Initialize InputNumber
|
||||
valueStartMin.value = min;
|
||||
valueStartMax.value = max;
|
||||
valueEndMin.value = min;
|
||||
valueEndMax.value = max;
|
||||
// 初始化: 讓 InputNumber 的範圍等於時間軸的範圍
|
||||
// Initialize: set the InputNumber range to match the timeline range
|
||||
valueStart.value = min;
|
||||
valueEnd.value = max;
|
||||
break;
|
||||
}
|
||||
// 傳給後端
|
||||
// attValueTypeStartEnd.value; 是否有要呼叫函數? sonar-qube
|
||||
// 建立圖表
|
||||
// Send to backend
|
||||
// attValueTypeStartEnd.value; should this function be called? sonar-qube
|
||||
// Create chart
|
||||
createChart();
|
||||
}
|
||||
}
|
||||
@@ -545,7 +545,7 @@ function createChart() {
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: false, // 圖例
|
||||
legend: false, // Hide legend
|
||||
filler: {
|
||||
propagate: false
|
||||
},
|
||||
@@ -562,10 +562,10 @@ function createChart() {
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true, // scale 包含 0
|
||||
beginAtZero: true, // Scale includes 0
|
||||
max: max,
|
||||
ticks: { // 設定間隔數值
|
||||
display: false, // 隱藏數值,只顯示格線
|
||||
ticks: { // Set tick intervals
|
||||
display: false, // Hide values, only show grid lines
|
||||
stepSize: max / 4,
|
||||
},
|
||||
grid: {
|
||||
@@ -573,7 +573,7 @@ function createChart() {
|
||||
z: 1,
|
||||
},
|
||||
border: {
|
||||
display: false, // 隱藏左側多出來的線
|
||||
display: false, // Hide the extra border line on the left
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -584,17 +584,17 @@ function createChart() {
|
||||
ticks: {
|
||||
min: minX,
|
||||
max: maxX,
|
||||
autoSkip: true, // 依比例判斷要不要換算時間單位
|
||||
maxRotation: 0, // 不旋轉 lable 0~50
|
||||
autoSkip: true, // Automatically determine whether to convert time units
|
||||
maxRotation: 0, // Do not rotate labels (0~50)
|
||||
color: '#334155',
|
||||
display: true,
|
||||
source: 'labels', // 依比例彈性顯示 label 數量
|
||||
source: 'labels', // Flexibly display label count proportionally
|
||||
},
|
||||
grid: {
|
||||
display: false, // 隱藏 x 軸網格
|
||||
display: false, // Hide x-axis grid lines
|
||||
},
|
||||
time: {
|
||||
minUnit: 'day', // 顯示最小單位
|
||||
minUnit: 'day', // Minimum display unit
|
||||
// displayFormats: {
|
||||
// minute: 'HH:mm MMM d',
|
||||
// hour: 'HH:mm MMM d',
|
||||
@@ -609,7 +609,7 @@ function createChart() {
|
||||
max: maxX,
|
||||
ticks: {
|
||||
autoSkip: true,
|
||||
maxRotation: 0, // 不旋轉 lable 0~50
|
||||
maxRotation: 0, // Do not rotate labels (0~50)
|
||||
color: '#334155',
|
||||
callback: ((value, index, values) => {
|
||||
let x;
|
||||
@@ -627,15 +627,15 @@ function createChart() {
|
||||
default:
|
||||
x = Math.round(value * 100) / 100;
|
||||
}
|
||||
// 處理科學記號等格式轉換
|
||||
// Decimal 無法處理超過 16 位數
|
||||
// Handle scientific notation and other format conversions
|
||||
// Decimal cannot handle numbers exceeding 16 digits
|
||||
x = new Intl.NumberFormat(undefined, {useGrouping: false}).format(x);
|
||||
return x
|
||||
}
|
||||
})
|
||||
},
|
||||
grid: {
|
||||
display: false, // 隱藏 x 軸網格
|
||||
display: false, // Hide x-axis grid lines
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -648,32 +648,32 @@ function createChart() {
|
||||
* @param {array} e [1, 100]
|
||||
*/
|
||||
function changeSelectArea(e) {
|
||||
// 日曆改變時,滑塊跟著改變
|
||||
// When the calendar changes, the slider follows
|
||||
const sliderData = sliderDataComputed.value;
|
||||
const start = sliderData[e[0].toFixed()];
|
||||
const end = sliderData[e[1].toFixed()]; // 取得 index,須為整數。
|
||||
const end = sliderData[e[1].toFixed()]; // Get the index, which must be an integer.
|
||||
|
||||
switch (selectedAttName.value.type) {
|
||||
case 'dummy':
|
||||
case 'date':
|
||||
startTime.value = new Date(start);
|
||||
endTime.value = new Date(end);
|
||||
// 重新設定 start end 日曆選取範圍
|
||||
// Reset the start/end calendar selection range
|
||||
endMinDate.value = new Date(start);
|
||||
startMaxDate.value = new Date(end);
|
||||
break;
|
||||
default:
|
||||
valueStart.value = start;
|
||||
valueEnd.value = end;
|
||||
// 重新設定 start end 日曆選取範圍
|
||||
// Reset the start/end selection range
|
||||
valueEndMin.value = start;
|
||||
valueStartMax.value = end;
|
||||
break;
|
||||
}
|
||||
// 重新算圖
|
||||
// Recalculate the chart mask
|
||||
resizeMask(chartComplete.value);
|
||||
// 執行 timeFrameStartEnd 才會改變數據
|
||||
// attValueTypeStartEnd.value; 是否有要呼叫函數? sonar-qube
|
||||
// Execute timeFrameStartEnd to update the data
|
||||
// attValueTypeStartEnd.value; should this function be called? sonar-qube
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -682,7 +682,7 @@ function changeSelectArea(e) {
|
||||
* @param {string} direction start or end
|
||||
*/
|
||||
function sliderValueRange(e, direction) {
|
||||
// 找到最鄰近的 index,時間格式: 毫秒時間戳
|
||||
// Find the closest index; time format: millisecond timestamps
|
||||
const sliderData = sliderDataComputed.value;
|
||||
const isDateType = selectedAttName.value.type === 'date';
|
||||
let targetTime = [];
|
||||
@@ -698,9 +698,9 @@ function sliderValueRange(e, direction) {
|
||||
result = result > selectRange.value ? selectRange.value : result;
|
||||
return result
|
||||
});
|
||||
// 改變滑塊
|
||||
// Update the slider
|
||||
selectArea.value = closestIndexes;
|
||||
// 重新設定 start end 日曆選取範圍
|
||||
// Reset the start/end calendar selection range
|
||||
if(!isDateType) inputValue = Number(e.value.replace(/,/g, '')) ;
|
||||
if(direction === 'start') {
|
||||
if(isDateType){
|
||||
@@ -716,7 +716,7 @@ function sliderValueRange(e, direction) {
|
||||
valueStartMax.value = inputValue;
|
||||
};
|
||||
}
|
||||
// 重新算圖
|
||||
// Recalculate the chart mask
|
||||
if(!isNaN(closestIndexes[0]) && !isNaN(closestIndexes[1])) resizeMask(chartComplete.value);
|
||||
else return;
|
||||
}
|
||||
@@ -740,7 +740,7 @@ emitter.on('map-filter-reset', value => {
|
||||
|
||||
onMounted(() => {
|
||||
// Slider
|
||||
selectArea.value = [0, selectRange.value]; // 初始化滑塊
|
||||
selectArea.value = [0, selectRange.value]; // Initialize the slider
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
|
||||
@@ -70,8 +70,8 @@ const { hasResultRule, temporaryData, postRuleData, ruleData, isRuleData, tempFi
|
||||
*/
|
||||
function isRule(e, index){
|
||||
const rule = isRuleData.value[index];
|
||||
// 先取得 rule object
|
||||
// 為了讓 data 順序不亂掉,將值指向 0,submitAll 時再刪掉
|
||||
// First get the rule object
|
||||
// To preserve data order, set the value to 0 and remove it during submitAll
|
||||
if(!e) temporaryData.value[index] = 0;
|
||||
else temporaryData.value[index] = rule;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ async function deleteRule(index) {
|
||||
isLoading.value = true;
|
||||
tempFilterId.value = await null;
|
||||
await allMapDataStore.getAllMapData();
|
||||
await allMapDataStore.getAllTrace(); // SidebarTrace 要連動
|
||||
await allMapDataStore.getAllTrace(); // SidebarTrace needs to update in sync
|
||||
await emit('submit-all');
|
||||
isLoading.value = false;
|
||||
}
|
||||
@@ -104,9 +104,9 @@ async function deleteRule(index) {
|
||||
|
||||
/** Submits all enabled filter rules and refreshes the map data. */
|
||||
async function submitAll() {
|
||||
postRuleData.value = temporaryData.value.filter(item => item !== 0); // 取得 submit 的資料,有 toggle button 的話,找出並刪除陣列中為 0 的項目
|
||||
postRuleData.value = temporaryData.value.filter(item => item !== 0); // Get submit data; if toggle buttons are used, find and remove items set to 0
|
||||
if(!postRuleData.value?.length) return $toast.error('Not selected');
|
||||
await allMapDataStore.checkHasResult(); // 後端快速檢查有沒有結果
|
||||
await allMapDataStore.checkHasResult(); // Quick backend check for results
|
||||
|
||||
if(hasResultRule.value === null) {
|
||||
return;
|
||||
@@ -114,7 +114,7 @@ async function submitAll() {
|
||||
isLoading.value = true;
|
||||
await allMapDataStore.addTempFilterId();
|
||||
await allMapDataStore.getAllMapData();
|
||||
await allMapDataStore.getAllTrace(); // SidebarTrace 要連動
|
||||
await allMapDataStore.getAllTrace(); // SidebarTrace needs to update in sync
|
||||
if(temporaryData.value[0]?.type) {
|
||||
allMapDataStore.traceId = await allMapDataStore.traces[0]?.id;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ const props = defineProps(['selectValue']);
|
||||
const allMapDataStore = useAllMapDataStore();
|
||||
const { filterTimeframe, selectTimeFrame } = storeToRefs(allMapDataStore);
|
||||
|
||||
const selectRange = ref(1000); // 更改 select 的切分數
|
||||
const selectRange = ref(1000); // Number of divisions for the selection range
|
||||
const selectArea = ref(null);
|
||||
const chart = ref(null);
|
||||
const canvasId = ref(null);
|
||||
@@ -73,12 +73,12 @@ const panelProps = ref({
|
||||
const timeFrameStartEnd = computed(() => {
|
||||
const start = getMoment(startTime.value).format('YYYY-MM-DDTHH:mm:00');
|
||||
const end = getMoment(endTime.value).format('YYYY-MM-DDTHH:mm:00');
|
||||
selectTimeFrame.value = [start, end]; // 傳給後端的資料
|
||||
selectTimeFrame.value = [start, end]; // Data to send to the backend
|
||||
|
||||
return [start, end];
|
||||
});
|
||||
|
||||
// 找出 slidrData,時間格式:毫秒時間戳
|
||||
// Compute slider data; time format: millisecond timestamps
|
||||
const sliderData = computed(() => {
|
||||
const xAxisMin = new Date(filterTimeframe.value.x_axis.min).getTime();
|
||||
const xAxisMax = new Date(filterTimeframe.value.x_axis.max).getTime();
|
||||
@@ -93,16 +93,16 @@ const sliderData = computed(() => {
|
||||
return data;
|
||||
});
|
||||
|
||||
// 加入最大、最小值
|
||||
// Add the minimum and maximum values
|
||||
const timeFrameData = computed(() => {
|
||||
const data = filterTimeframe.value.data.map(i=>({x:i.x,y:i.y}))
|
||||
// y 軸斜率計算請參考 ./public/timeFrameSlope 的圖
|
||||
// x 值為 0 ~ 11,
|
||||
// 將三的座標(ax, ay), (bx, by), (cx, cy)命名為 (a, b), (c, d), (e, f)
|
||||
// 最小值: (f - b)(c - a) = (e - a)(d - b),求 b = (ed - ad - fa - fc) / (e - c - a)
|
||||
// 最大值: (f - b)(e - c) = (f - d)(e - a),求 f = (be - bc -de + da) / (a - c)
|
||||
// See ./public/timeFrameSlope for the y-axis slope calculation diagram
|
||||
// x values are 0 ~ 11,
|
||||
// Name three coordinates (ax, ay), (bx, by), (cx, cy) as (a, b), (c, d), (e, f)
|
||||
// Minimum: (f - b)(c - a) = (e - a)(d - b), solve for b = (ed - ad - fa - fc) / (e - c - a)
|
||||
// Maximum: (f - b)(e - c) = (f - d)(e - a), solve for f = (be - bc - de + da) / (a - c)
|
||||
|
||||
// y 軸最小值
|
||||
// Y-axis minimum value
|
||||
const a = 0;
|
||||
let b;
|
||||
const c = 1;
|
||||
@@ -113,7 +113,7 @@ const timeFrameData = computed(() => {
|
||||
if(b < 0) {
|
||||
b = 0;
|
||||
}
|
||||
// y 軸最大值
|
||||
// Y-axis maximum value
|
||||
const ma = 9;
|
||||
const mb = filterTimeframe.value.data[8].y;
|
||||
const mc = 10;
|
||||
@@ -124,12 +124,12 @@ const timeFrameData = computed(() => {
|
||||
mf = 0;
|
||||
}
|
||||
|
||||
// 添加最小值
|
||||
// Add the minimum value
|
||||
data.unshift({
|
||||
x: filterTimeframe.value.x_axis.min_base,
|
||||
y: b,
|
||||
})
|
||||
// 添加最大值
|
||||
// Add the maximum value
|
||||
data.push({
|
||||
x: filterTimeframe.value.x_axis.max_base,
|
||||
y: mf,
|
||||
@@ -234,13 +234,13 @@ function createChart() {
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: false, // 圖例
|
||||
legend: false, // Hide legend
|
||||
filler: {
|
||||
propagate: false
|
||||
},
|
||||
title: false
|
||||
},
|
||||
// animations: false, // 取消動畫
|
||||
// animations: false, // Disable animations
|
||||
animation: {
|
||||
onComplete: e => {
|
||||
resizeMask(e.chart);
|
||||
@@ -256,16 +256,16 @@ function createChart() {
|
||||
max: maxX,
|
||||
ticks: {
|
||||
autoSkip: true,
|
||||
maxRotation: 0, // 不旋轉 lable 0~50
|
||||
maxRotation: 0, // Do not rotate labels (0~50)
|
||||
color: '#334155',
|
||||
display: true,
|
||||
source: 'labels',
|
||||
},
|
||||
grid: {
|
||||
display: false, // 隱藏 x 軸網格
|
||||
display: false, // Hide x-axis grid lines
|
||||
},
|
||||
time: {
|
||||
minUnit: 'day', // 顯示最小單位
|
||||
minUnit: 'day', // Minimum display unit
|
||||
// displayFormats: {
|
||||
// minute: 'HH:mm MMM d',
|
||||
// hour: 'HH:mm MMM d',
|
||||
@@ -273,10 +273,10 @@ function createChart() {
|
||||
}
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true, // scale 包含 0
|
||||
beginAtZero: true, // Scale includes 0
|
||||
max: max,
|
||||
ticks: { // 設定間隔數值
|
||||
display: false, // 隱藏數值,只顯示格線
|
||||
ticks: { // Set tick intervals
|
||||
display: false, // Hide values, only show grid lines
|
||||
stepSize: max / 4,
|
||||
},
|
||||
grid: {
|
||||
@@ -284,7 +284,7 @@ function createChart() {
|
||||
z: 1,
|
||||
},
|
||||
border: {
|
||||
display: false, // 隱藏左側多出來的線
|
||||
display: false, // Hide the extra border line on the left
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -303,19 +303,19 @@ function createChart() {
|
||||
* @param {array} e [1, 100]
|
||||
*/
|
||||
function changeSelectArea(e) {
|
||||
// 日曆改變時,滑塊跟著改變
|
||||
// When the calendar changes, the slider follows
|
||||
const sliderDataVal = sliderData.value;
|
||||
const start = sliderDataVal[e[0].toFixed()];
|
||||
const end = sliderDataVal[e[1].toFixed()]; // 取得 index,須為整數。
|
||||
const end = sliderDataVal[e[1].toFixed()]; // Get the index, which must be an integer.
|
||||
|
||||
startTime.value = new Date(start);
|
||||
endTime.value = new Date(end);
|
||||
// 重新設定 start end 日曆選取範圍
|
||||
// Reset the start/end calendar selection range
|
||||
endMinDate.value = new Date(start);
|
||||
startMaxDate.value = new Date(end);
|
||||
// 重新算圖
|
||||
// Recalculate the chart mask
|
||||
resizeMask(chart.value);
|
||||
// 執行 timeFrameStartEnd 才會改變數據
|
||||
// Execute timeFrameStartEnd to update the data
|
||||
timeFrameStartEnd.value;
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ function changeSelectArea(e) {
|
||||
* @param {string} direction start or end
|
||||
*/
|
||||
function sliderTimeRange(e, direction) {
|
||||
// 找到最鄰近的 index,時間格式: 毫秒時間戳
|
||||
// Find the closest index; time format: millisecond timestamps
|
||||
const sliderDataVal = sliderData.value;
|
||||
const targetTime = [new Date(timeFrameStartEnd.value[0]).getTime(), new Date(timeFrameStartEnd.value[1]).getTime()];
|
||||
const closestIndexes = targetTime.map(target => {
|
||||
@@ -336,12 +336,12 @@ function sliderTimeRange(e, direction) {
|
||||
return result
|
||||
});
|
||||
|
||||
// 改變滑塊
|
||||
// Update the slider
|
||||
selectArea.value = closestIndexes;
|
||||
// 重新設定 start end 日曆選取範圍
|
||||
// Reset the start/end calendar selection range
|
||||
if(direction === 'start') endMinDate.value = e;
|
||||
else if(direction === 'end') startMaxDate.value = e;
|
||||
// 重新算圖
|
||||
// Recalculate the chart mask
|
||||
if(!isNaN(closestIndexes[0]) && !isNaN(closestIndexes[1])) resizeMask(chart.value);
|
||||
else return;
|
||||
}
|
||||
@@ -357,7 +357,7 @@ onMounted(() => {
|
||||
startMaxDate.value = new Date(filterTimeframe.value.x_axis.max);
|
||||
endMinDate.value = new Date(filterTimeframe.value.x_axis.min);
|
||||
endMaxDate.value = new Date(filterTimeframe.value.x_axis.max);
|
||||
// 讓日曆的範圍等於時間軸的範圍
|
||||
// Set the calendar range to match the timeline range
|
||||
startTime.value = startMinDate.value;
|
||||
endTime.value = startMaxDate.value;
|
||||
timeFrameStartEnd.value;
|
||||
|
||||
@@ -99,7 +99,7 @@ const processMap = ref({
|
||||
const showTraceId = ref(null);
|
||||
const infinitMaxItems = ref(false);
|
||||
const infiniteData = ref([]);
|
||||
const infiniteFinish = ref(true); // 無限滾動是否載入完成
|
||||
const infiniteFinish = ref(true); // Whether infinite scroll loading is complete
|
||||
const chartOptions = ref(null);
|
||||
const selectArea = ref([0, 1]);
|
||||
const cyTraceRef = ref(null);
|
||||
@@ -138,11 +138,11 @@ const chartData = computed(() => {
|
||||
const data = baseTraces.value.map(trace => getPercentLabel(trace.count / traceCountTotal.value));
|
||||
const selectAreaData = baseTraces.value.map((trace, index) => index >= start && index <= end ? 'rgba(0,153,255)' : 'rgba(203, 213, 225)');
|
||||
|
||||
return { // 要呈現的資料
|
||||
return { // Data to display
|
||||
labels,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Trace', // 資料的標題標籤
|
||||
label: 'Trace', // Dataset label
|
||||
data,
|
||||
backgroundColor: selectAreaData,
|
||||
categoryPercentage: 1.0,
|
||||
@@ -153,18 +153,18 @@ const chartData = computed(() => {
|
||||
});
|
||||
|
||||
const caseData = computed(() => {
|
||||
const data = JSON.parse(JSON.stringify(infiniteData.value)); // 深拷貝原始 cases 的內容
|
||||
const data = JSON.parse(JSON.stringify(infiniteData.value)); // Deep copy the original cases data
|
||||
data.forEach(item => {
|
||||
item.attributes.forEach((attribute, index) => {
|
||||
item[`att_${index}`] = attribute.value; // 建立新的 key-value pair
|
||||
item[`att_${index}`] = attribute.value; // Create a new key-value pair
|
||||
});
|
||||
delete item.attributes; // 刪除原本的 attributes 屬性
|
||||
delete item.attributes; // Remove the original attributes property
|
||||
})
|
||||
return data;
|
||||
});
|
||||
|
||||
const columnData = computed(() => {
|
||||
const data = JSON.parse(JSON.stringify(baseCases.value)); // 深拷貝原始 cases 的內容
|
||||
const data = JSON.parse(JSON.stringify(baseCases.value)); // Deep copy the original cases data
|
||||
let result = [
|
||||
{ field: 'id', header: 'Case Id' },
|
||||
{ field: 'started_at', header: 'Start time' },
|
||||
@@ -184,7 +184,7 @@ const columnData = computed(() => {
|
||||
watch(selectArea, (newValue, oldValue) => {
|
||||
const roundValue = Math.round(newValue[1].toFixed());
|
||||
if(newValue[1] !== roundValue) selectArea.value[1] = roundValue;
|
||||
if(newValue != oldValue) emit('filter-trace-selectArea', newValue); // 判斷 Apply 是否 disable
|
||||
if(newValue != oldValue) emit('filter-trace-selectArea', newValue); // Determine whether Apply should be disabled
|
||||
});
|
||||
|
||||
watch(infinit404, (newValue) => {
|
||||
@@ -211,7 +211,7 @@ function barOptions(){
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: { // 圖例
|
||||
legend: { // Legend
|
||||
display: false,
|
||||
},
|
||||
tooltip: {
|
||||
@@ -228,8 +228,8 @@ function barOptions(){
|
||||
display:false
|
||||
},
|
||||
y: {
|
||||
ticks: { // 設定間隔數值
|
||||
display: false, // 隱藏數值,只顯示格線
|
||||
ticks: { // Set tick intervals
|
||||
display: false, // Hide values, only show grid lines
|
||||
min: 0,
|
||||
max: traceList.value[0]?.ratio,
|
||||
stepSize: (traceList.value[0]?.ratio)/4,
|
||||
@@ -239,7 +239,7 @@ function barOptions(){
|
||||
z: 1,
|
||||
},
|
||||
border: {
|
||||
display: false, // 隱藏左側多出來的線
|
||||
display: false, // Hide the extra border line on the left
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,15 +271,15 @@ function progressWidth(value){
|
||||
* @param {number} count - The total number of cases.
|
||||
*/
|
||||
async function switchCaseData(id, count) {
|
||||
// 點同一筆 id 不要有動作
|
||||
// Do nothing if clicking the same id
|
||||
if(id == showTraceId.value) return;
|
||||
isLoading.value = true; // 都要 loading 畫面
|
||||
isLoading.value = true; // Always show loading screen
|
||||
infinit404.value = null;
|
||||
infinitMaxItems.value = false;
|
||||
baseInfiniteStart.value = 0;
|
||||
allMapDataStore.baseTraceId = id;
|
||||
infiniteData.value = await allMapDataStore.getBaseTraceDetail();
|
||||
showTraceId.value = id; // 放 getDetail 為了 case table 載入完再切換 showTraceId
|
||||
showTraceId.value = id; // Set after getDetail so the case table finishes loading before switching showTraceId
|
||||
createCy();
|
||||
isLoading.value = false;
|
||||
}
|
||||
@@ -288,9 +288,9 @@ async function switchCaseData(id, count) {
|
||||
* Assembles the trace element nodes data for Cytoscape rendering.
|
||||
*/
|
||||
function setNodesData(){
|
||||
// 避免每次渲染都重複累加
|
||||
// Clear nodes to prevent accumulation on each render
|
||||
processMap.value.nodes = [];
|
||||
// 將 api call 回來的資料帶進 node
|
||||
// Populate nodes with data returned from the API call
|
||||
baseTraceTaskSeq.value.forEach((node, index) => {
|
||||
processMap.value.nodes.push({
|
||||
data: {
|
||||
@@ -321,7 +321,7 @@ function setEdgesData(){
|
||||
}
|
||||
});
|
||||
});
|
||||
// 關係線數量筆節點少一個
|
||||
// The number of edges is one less than the number of nodes
|
||||
processMap.value.edges.pop();
|
||||
}
|
||||
|
||||
@@ -367,7 +367,7 @@ async function fetchData() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
isLoading.value = true; // createCy 執行完關閉
|
||||
isLoading.value = true; // Will be closed after createCy finishes
|
||||
setNodesData();
|
||||
setEdgesData();
|
||||
createCy();
|
||||
|
||||
@@ -134,7 +134,7 @@ const { hasResultRule, temporaryData, postRuleData, ruleData, isRuleData, select
|
||||
|
||||
const selectFilter = {
|
||||
'Filter Type': ['Sequence', 'Attributes', 'Trace', 'Timeframes'],
|
||||
// 'Filter Type': ['Sequence', 'Trace', 'Timeframes'],
|
||||
// 'Filter Type': ['Sequence', 'Trace', 'Timeframes'], // without Attributes
|
||||
'Activity Sequence':['Have activity(s)', 'Start & End', 'Sequence'],
|
||||
'Start & End': ['Start', 'End', 'Start & End'],
|
||||
'Mode': ['Directly follows', 'Eventually follows'],
|
||||
@@ -160,12 +160,12 @@ const selectFilterEnd = ref(null);
|
||||
const selectFilterStartToEnd = ref(null);
|
||||
const selectFilterEndToStart = ref(null);
|
||||
const listSeq = ref([]);
|
||||
//若第一次選擇 start, 則 end 連動改變,若第一次選擇 end, 則 start 連動改變
|
||||
// If start is selected first, end updates accordingly; if end is selected first, start updates accordingly
|
||||
const isStartSelected = ref(null);
|
||||
const isEndSelected = ref(null);
|
||||
const isActAllTask = ref(true);
|
||||
const rowData = ref([]);
|
||||
const selectTraceArea = ref([]); // Trace 滑快
|
||||
const selectTraceArea = ref([]); // Trace slider
|
||||
const isDisabled = ref(true); // Apply Button disabled setting
|
||||
const filterTraceViewRef = ref(null);
|
||||
const tooltip = {
|
||||
@@ -285,7 +285,7 @@ function progressWidth(value){
|
||||
return `width:${value}%;`
|
||||
}
|
||||
|
||||
//設定 Have activity(s) 內容
|
||||
// Set up the Have activity(s) content
|
||||
/**
|
||||
* @param {array} data filterTaskData
|
||||
*/
|
||||
@@ -305,7 +305,7 @@ function setHaveAct(data){
|
||||
}).sort((x, y) => y.occurrences_base - x.occurrences_base);
|
||||
}
|
||||
|
||||
// 調整 filterStartData / filterEndData / filterStartToEndData / filterEndToStartData 的內容
|
||||
// Adjust the content of filterStartData / filterEndData / filterStartToEndData / filterEndToStartData
|
||||
/**
|
||||
* @param {Array} array - filterStartToEnd or filterEndToStart data array.
|
||||
*/
|
||||
@@ -362,7 +362,7 @@ function onUpdateListSeq(newListSeq) {
|
||||
isActAllTask.value = false;
|
||||
}
|
||||
|
||||
// 在 Start & End 若第一次選擇 start, 則 end 連動改變,若第一次選擇 end, 則 start 連動改變
|
||||
// In Start & End mode, if start is selected first, end updates accordingly; if end is selected first, start updates accordingly
|
||||
/**
|
||||
* @param {object} e object contains selected row's data
|
||||
*/
|
||||
@@ -387,7 +387,7 @@ function endRow(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// 重新設定連動的 filterStartToEndData / filterEndToStartData 內容
|
||||
// Reset the linked filterStartToEndData / filterEndToStartData content
|
||||
/**
|
||||
* @param {array} eventData Start or End List
|
||||
* @param {object} rowDataVal - The selected row's data.
|
||||
@@ -492,7 +492,7 @@ function reset(message) {
|
||||
filterTraceViewRef.value.showTraceId = null;
|
||||
filterTraceViewRef.value.selectArea = [0, filterTraceViewRef.value.traceTotal];
|
||||
};
|
||||
// 成功訊息
|
||||
// Success message
|
||||
if(message) {
|
||||
$toast.success('Filter cleared.')
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
</TabPanel>
|
||||
<!-- 從shortest_traces開始迭代 -->
|
||||
<!-- Iterate starting from shortest_traces -->
|
||||
<TabPanel v-for="([field, label], i) in fieldNamesAndLabelNames" :key="i" :header="label"
|
||||
contentClass="text-sm">
|
||||
<p v-if="insights[field].length === 0" class="bg-neutral-100 p-2 rounded">No data</p>
|
||||
@@ -202,7 +202,7 @@
|
||||
<input type="radio" name="customRadio" :value="key2" v-model="clickedPathListIndex"
|
||||
class="hidden peer" @click="onPathOptionClick(key2)"
|
||||
/>
|
||||
<!-- 若為BPMN檢視模式,則不允許點亮路徑 -->
|
||||
<!-- If in BPMN view mode, path highlighting is not allowed -->
|
||||
<span v-if="!isBPMNOn" @click="onPathOptionClick(key2)"
|
||||
:class="[
|
||||
'w-[18px] h-[18px] rounded-full border-2 inline-flex items-center justify-center cursor-pointer bg-[#FFFFFF]',
|
||||
@@ -261,7 +261,7 @@ import getMoment from 'moment';
|
||||
import i18next from '@/i18n/i18n';
|
||||
import { INSIGHTS_FIELDS_AND_LABELS } from '@/constants/constants';
|
||||
|
||||
// 刪除第一個和第二個元素
|
||||
// Remove the first and second elements
|
||||
const fieldNamesAndLabelNames = [...INSIGHTS_FIELDS_AND_LABELS].slice(2);
|
||||
|
||||
const props = defineProps({
|
||||
@@ -332,7 +332,7 @@ function switchTab(newTab) {
|
||||
*/
|
||||
function timeLabel(time){ // sonar-qube prevent super-linear runtime due to backtracking; change * to ?
|
||||
//
|
||||
const label = getTimeLabel(time).replace(/\s+/g, ' '); // 將所有連續空白字符壓縮為一個空白
|
||||
const label = getTimeLabel(time).replace(/\s+/g, ' '); // Collapse all consecutive whitespace into a single space
|
||||
const result = label.match(/^(\d+)\s?([a-zA-Z]+)$/); // add ^ and $ to meet sonar-qube need
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ const processMap = ref({
|
||||
const showTraceId = ref(null);
|
||||
const infinitMaxItems = ref(false);
|
||||
const infiniteData = ref([]);
|
||||
const infiniteFinish = ref(true); // 無限滾動是否載入完成
|
||||
const infiniteFinish = ref(true); // Whether infinite scroll loading is complete
|
||||
const cyTraceRef = ref(null);
|
||||
|
||||
const traceTotal = computed(() => {
|
||||
@@ -113,18 +113,18 @@ const traceList = computed(() => {
|
||||
});
|
||||
|
||||
const caseData = computed(() => {
|
||||
const data = JSON.parse(JSON.stringify(infiniteData.value)); // 深拷貝原始 cases 的內容
|
||||
const data = JSON.parse(JSON.stringify(infiniteData.value)); // Deep copy the original cases data
|
||||
data.forEach(item => {
|
||||
item.attributes.forEach((attribute, index) => {
|
||||
item[`att_${index}`] = attribute.value; // 建立新的 key-value pair
|
||||
item[`att_${index}`] = attribute.value; // Create a new key-value pair
|
||||
});
|
||||
delete item.attributes; // 刪除原本的 attributes 屬性
|
||||
delete item.attributes; // Remove the original attributes property
|
||||
})
|
||||
return data;
|
||||
});
|
||||
|
||||
const columnData = computed(() => {
|
||||
const data = JSON.parse(JSON.stringify(props.cases)); // 深拷貝原始 cases 的內容
|
||||
const data = JSON.parse(JSON.stringify(props.cases)); // Deep copy the original cases data
|
||||
let result = [
|
||||
{ field: 'id', header: 'Case Id' },
|
||||
{ field: 'started_at', header: 'Start time' },
|
||||
@@ -183,23 +183,23 @@ function progressWidth(value){
|
||||
* @param {number} count - The total number of cases.
|
||||
*/
|
||||
async function switchCaseData(id, count) {
|
||||
// 點同一筆 id 不要有動作
|
||||
// Do nothing if clicking the same id
|
||||
if(id == showTraceId.value) return;
|
||||
isLoading.value = true; // 都要 loading 畫面
|
||||
isLoading.value = true; // Always show loading screen
|
||||
infinit404.value = null;
|
||||
infinitMaxItems.value = false;
|
||||
showTraceId.value = id;
|
||||
infiniteStart.value = 0;
|
||||
emit('switch-Trace-Id', {id: showTraceId.value, count: count}); // 傳遞到 Map index 再關掉 loading
|
||||
emit('switch-Trace-Id', {id: showTraceId.value, count: count}); // Pass to Map index, which will close loading
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles the trace element nodes data for Cytoscape rendering.
|
||||
*/
|
||||
function setNodesData(){
|
||||
// 避免每次渲染都重複累加
|
||||
// Clear nodes to prevent accumulation on each render
|
||||
processMap.value.nodes = [];
|
||||
// 將 api call 回來的資料帶進 node
|
||||
// Populate nodes with data returned from the API call
|
||||
traceTaskSeq.value.forEach((node, index) => {
|
||||
processMap.value.nodes.push({
|
||||
data: {
|
||||
@@ -230,7 +230,7 @@ function setEdgesData(){
|
||||
}
|
||||
});
|
||||
});
|
||||
// 關係線數量筆節點少一個
|
||||
// The number of edges is one less than the number of nodes
|
||||
processMap.value.edges.pop();
|
||||
}
|
||||
|
||||
@@ -249,8 +249,8 @@ function createCy(){
|
||||
* create map
|
||||
*/
|
||||
async function show() {
|
||||
isLoading.value = true; // createCy 執行完關閉
|
||||
// 因 trace api 連動,所以關閉側邊欄時讓數值歸 traces 第一筆 id
|
||||
isLoading.value = true; // Will be closed after createCy finishes
|
||||
// Reset to the first trace id when sidebar closes, due to trace API dependency
|
||||
showTraceId.value = traces.value[0]?.id;
|
||||
infiniteStart.value = 0;
|
||||
setNodesData();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="my-4 border-b border-neutral-200">
|
||||
<p class="h2">View</p>
|
||||
<ul class="space-y-3 mb-4">
|
||||
<!-- 選擇 bpmn / processmap button -->
|
||||
<!-- Select bpmn / processmap button -->
|
||||
<li class="btn-toggle-content">
|
||||
<span class="btn-toggle-item" :class="mapType === 'processMap'?'btn-toggle-show ':''" @click="onProcessMapClick()">
|
||||
Process Map
|
||||
@@ -17,7 +17,7 @@
|
||||
BPMN Model
|
||||
</span>
|
||||
</li>
|
||||
<!-- 選擇繪畫樣式 bezier / unbundled-bezier button-->
|
||||
<!-- Select drawing style: bezier / unbundled-bezier button -->
|
||||
<li class="btn-toggle-content">
|
||||
<span class="btn-toggle-item" :class="curveStyle === 'unbundled-bezier'?'btn-toggle-show ':''" @click="switchCurveStyles('unbundled-bezier')">
|
||||
Curved
|
||||
@@ -26,7 +26,7 @@
|
||||
Elbow
|
||||
</span>
|
||||
</li>
|
||||
<!-- 直向 TB | 橫向 LR -->
|
||||
<!-- Vertical TB | Horizontal LR -->
|
||||
<li class="btn-toggle-content">
|
||||
<span class="btn-toggle-item" :class="rank === 'LR'?'btn-toggle-show ':''" @click="switchRank('LR')">
|
||||
Horizontal
|
||||
@@ -124,7 +124,7 @@ const dataLayerType = ref(null); // freq | duration
|
||||
const dataLayerOption = ref(null);
|
||||
const selectedFreq = ref('');
|
||||
const selectedDuration = ref('');
|
||||
const rank = ref('LR'); // 直向 TB | 橫向 LR
|
||||
const rank = ref('LR'); // Vertical TB | Horizontal LR
|
||||
|
||||
/**
|
||||
* Switches the map type and emits the change event.
|
||||
|
||||
@@ -163,7 +163,7 @@ onMounted(async () => {
|
||||
}
|
||||
await allMapDataStore.getAllMapData();
|
||||
await getStatData();
|
||||
isPanel.value = false; // 預設不打開
|
||||
isPanel.value = false; // Collapsed by default
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user