From d6cb329a5ce46cc0820417eafba584a48fa23caa Mon Sep 17 00:00:00 2001 From: Cindy Chang Date: Fri, 7 Jun 2024 15:55:51 +0800 Subject: [PATCH] fix #258. Compare page and Performance pages are featured with formatted x ticks. The author supposes this issue is not a bug but a feature. --- src/stores/conformanceInput.js | 8 +- src/views/Compare/Dashboard/index.vue | 1 + src/views/Discover/Performance/index.vue | 199 ++++++++++++++++------- 3 files changed, 149 insertions(+), 59 deletions(-) diff --git a/src/stores/conformanceInput.js b/src/stores/conformanceInput.js index 0092c27..4cd5045 100644 --- a/src/stores/conformanceInput.js +++ b/src/stores/conformanceInput.js @@ -19,7 +19,7 @@ export default defineStore('conformanceInputStore', { getters: { }, actions: { - /** + /** UNUSED * Set input activity radio data * @param {object} actRadioData */ @@ -28,6 +28,7 @@ export default defineStore('conformanceInputStore', { }, /** * Sets the activity radio global state for either the start ('From') or end ('To') of a task. + * We arrange in this way because backend needs us to communicate in this way. * @param {object} actRadioData * @param {string} fromToStr 'From' or 'To' */ @@ -44,20 +45,21 @@ export default defineStore('conformanceInputStore', { } }, /** + * UNUSED * Temporarily set conformance input data which is probably fed to backend later. * @param {object} userInputObj */ setConformanceUserInput(userInputObj){ this.inputDataToSave = {...userInputObj}; }, - /** + /** UNUSED * Set the starting time of time range to be saved later * @param {string} startStr */ setConformanceInputStart(startStr){ this.inputDataToSave.inputStart = moment(startStr).format('YYYY-MM-DDTHH:mm:ss'); }, - /** + /** UNUSED * Set the ending time of time range to be saved later * @param {string} startStr */ diff --git a/src/views/Compare/Dashboard/index.vue b/src/views/Compare/Dashboard/index.vue index 4c0149d..689e142 100644 --- a/src/views/Compare/Dashboard/index.vue +++ b/src/views/Compare/Dashboard/index.vue @@ -476,6 +476,7 @@ export default { } // 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(xLabelData, formatToSet); const customizedScaleOption = this.getCustomizedScaleOption( diff --git a/src/views/Discover/Performance/index.vue b/src/views/Discover/Performance/index.vue index 3223e2b..ed440ea 100644 --- a/src/views/Discover/Performance/index.vue +++ b/src/views/Discover/Performance/index.vue @@ -143,7 +143,64 @@ import PerformanceStore from '@/stores/performance.js'; import ConformanceStore from '@/stores/conformance.js'; import StatusBar from '@/components/Discover/StatusBar.vue'; import { setLineChartData } from '@/module/setChartData.js'; -import { simpleTimeLabel, followTimeLabel, dateLabel } from '@/module/timeLabel.js'; +import { simpleTimeLabel, followTimeLabel, dateLabel, + setTimeStringFormatBaseOnTimeDifference, + mapTimestampToAxisTicksByFormat, + } from '@/module/timeLabel.js'; + +const knownScaleLineChartOptions = { + x: { + type: 'time', + title: { + display: true, + color: '#334155', + font: { + size: 12, + lineHeight: 2 + } + }, + time: { + displayFormats: { + second: 'h:mm:ss', // ex: 1:11:11 + minute: 'M/d h:mm', // ex: 1/1 1:11 + hour: 'M/d h:mm', // ex: 1/1 1:11 + day: 'M/d h', // ex: 1/1 1 + month: 'y/M/d', // ex: 1911/1/1 + }, + round: true + }, + ticks: { + display: true, + maxRotation: 0, // 不旋轉 lable 0~50 + color: '#64748b', + source: 'labels', // 依比例彈性顯示 label 數量 + }, + border: { + color: '#64748b', + }, + }, + y: { + beginAtZero: true, // scale 包含 0 + title: { + display: true, + color: '#334155', + font: { + size: 12, + lineHeight: 2 + }, + }, + ticks:{ + color: '#64748b', + padding: 8, + }, + grid: { + color: '#64748b', + }, + border: { + display: false, // 隱藏左側多出來的線 + }, + }, +} export default { setup() { @@ -279,6 +336,18 @@ export default { xData = chartData.data.map(item => new Date(item.x).getTime()); break; } + + // 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 = this.getCustomizedScaleOption( + knownScaleLineChartOptions, { + customizeOptions: { + content, ticksOfXAxis, + } + }); + primeVueSetData = { labels: xData, datasets: [ @@ -316,61 +385,7 @@ export default { display: false, }, }, - scales: { - x: { - type: 'time', - title: { - display: true, - text: content.x, - color: '#334155', - font: { - size: 12, - lineHeight: 2 - } - }, - time: { - displayFormats: { - second: 'h:mm:ss', // ex: 1:11:11 - minute: 'M/d h:mm', // ex: 1/1 1:11 - hour: 'M/d h:mm', // ex: 1/1 1:11 - day: 'M/d h', // ex: 1/1 1 - month: 'y/M/d', // ex: 1911/1/1 - }, - round: true - }, - ticks: { - display: true, - maxRotation: 0, // 不旋轉 lable 0~50 - color: '#64748b', - source: 'labels', // 依比例彈性顯示 label 數量 - }, - border: { - color: '#64748b', - }, - }, - y: { - beginAtZero: true, // scale 包含 0 - title: { - display: true, - text: content.y, - color: '#334155', - font: { - size: 12, - lineHeight: 2 - }, - }, - ticks:{ - color: '#64748b', - padding: 8, - }, - grid: { - color: '#64748b', - }, - border: { - display: false, // 隱藏左側多出來的線 - }, - }, - }, + scales: customizedScaleOption, }; switch (yUnit) { case 'date': @@ -648,6 +663,78 @@ export default { return [primeVueSetData, primeVueSetOption] }, + /** + * Compare page and Performance have this same function. + * @param whichScaleObj PrimeVue scale option object to reference to + * @param customizeOptions + * @param customizeOptions.content + * @param customizeOptions.ticksOfXAxis + */ + getCustomizedScaleOption(whichScaleObj, {customizeOptions: { + content, + ticksOfXAxis, + }, + }) { + let resultScaleObj; + resultScaleObj = this.customizeScaleChartOptionTitleByContent(whichScaleObj, content); + resultScaleObj = this.customizeScaleChartOptionTicks(resultScaleObj, ticksOfXAxis); + return resultScaleObj; + }, + /** Compare page and Performance have this same function. + * 在一個基本的物件上加以客製化這個物件,客製化的參照來源是 content 的內容 + * 之所以有辦法這樣撰寫,是因為我們知道物件的順序是先 x 再 title 再 text + * This function alters the title property of known scales object of Chart option + * This is based on the fact that we know the order must be x -> title -> text. + * @param {object} whichScaleObj PrimeVue scale option object to reference to + * @param content whose property includes x and y and stand for titles + * + * @returns { object } an object modified with two titles + */ + customizeScaleChartOptionTitleByContent(whichScaleObj, content){ + if (!content) { + // Early return + return whichScaleObj; + } + + return { + ...whichScaleObj, + x: { + ...whichScaleObj.x, + title: { + ...whichScaleObj.x.title, + text: content.x + } + }, + y: { + ...whichScaleObj.y, + title: { + ...whichScaleObj.y.title, + text: content.y + } + } + }; + }, + /** + * Compare page and Performance have this same function. + * @param {object} scaleObjectToAlter this object follows the format of prive vue chart + * @param {Array} ticksOfXAxis For example, ['05/06', '05,07', '05/08'] + * or ['08:03:01', '08:11:18', '09:03:41', ], and so on. + */ + customizeScaleChartOptionTicks(scaleObjectToAlter, ticksOfXAxis) { + return { + ...scaleObjectToAlter, + x: { + ...scaleObjectToAlter.x, + ticks: { + ...scaleObjectToAlter.x.ticks, + callback: function(value, index) { + // console.log('根據不同的級距客製化 x 軸的時間刻度'); + return ticksOfXAxis[index]; + }, + }, + }, + }; + }, }, async created() { this.isLoading = true; // moubeted 才停止 loading