WIP customizing x tick according to time difference
This commit is contained in:
@@ -215,3 +215,14 @@ export const setTimeStringFormatBaseOnTimeDifference = (minTimeStamp, maxTimeSta
|
|||||||
|
|
||||||
return dateFormat;
|
return dateFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of Unix timestamps to formatted date strings based on the
|
||||||
|
* specified format for use as axis ticks.
|
||||||
|
* 根據指定的格式將 Unix 時間戳數組轉換為軸標籤的格式化日期字符串。
|
||||||
|
* @param {Array<number>} timeStampArr
|
||||||
|
* @param {string} timeFormat For example, 'MM/DD'
|
||||||
|
*/
|
||||||
|
export const mapTimestampToAxisTicksByFormat = (timeStampArr, timeFormat) => {
|
||||||
|
return timeStampArr.map(ts => moment(ts).format(timeFormat));
|
||||||
|
};
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
<p class="h1">{{ i18next.t("Compare.frequency") }}</p>
|
<p class="h1">{{ i18next.t("Compare.frequency") }}</p>
|
||||||
<ul class="list-disc list-inside text-sm leading-5 pl-3">
|
<ul class="list-disc list-inside text-sm leading-5 pl-3">
|
||||||
<li v-for="(item, index) in frequencyData" :key="index" :class="{active: isActive === item.tagId}"
|
<li v-for="(item, index) in frequencyData" :key="index" :class="{active: isActive === item.tagId}"
|
||||||
@click="isActive = item.tagId" class="cursor-pointer hover:text-primary"><a :href="item.tagId">
|
@click="isActive = item.tagId" class="cursor-pointer hover:text-primary">
|
||||||
|
<a :href="item.tagId">
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</a></li>
|
</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -50,7 +51,8 @@
|
|||||||
<span class="material-symbols-outlined align-middle ml-2 cursor-pointer !text-base"
|
<span class="material-symbols-outlined align-middle ml-2 cursor-pointer !text-base"
|
||||||
v-tooltip.bottom="tooltip.avgCycleEfficiency">
|
v-tooltip.bottom="tooltip.avgCycleEfficiency">
|
||||||
{{ i18next.t("Compare.info") }}
|
{{ i18next.t("Compare.info") }}
|
||||||
</span></span>
|
</span>
|
||||||
|
</span>
|
||||||
<Chart type="bar" :data="avgCycleEfficiencyData" :options="avgCycleEfficiencyOptions" class="h-96" />
|
<Chart type="bar" :data="avgCycleEfficiencyData" :options="avgCycleEfficiencyOptions" class="h-96" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -68,7 +70,8 @@
|
|||||||
<span class="block font-bold text-sm leading-loose text-center my-2">
|
<span class="block font-bold text-sm leading-loose text-center my-2">
|
||||||
{{ contentData.avgProcessTimeByTask.title }}
|
{{ contentData.avgProcessTimeByTask.title }}
|
||||||
</span>
|
</span>
|
||||||
<Chart type="bar" :data="avgProcessTimeByTaskData" :options="avgProcessTimeByTaskOptions" class="h-[500px]"
|
<Chart type="bar" :data="avgProcessTimeByTaskData" :options="avgProcessTimeByTaskOptions"
|
||||||
|
class="h-[500px]"
|
||||||
:style="{ height: avgProcessTimeByTaskHeight }"/>
|
:style="{ height: avgProcessTimeByTaskHeight }"/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -152,7 +155,10 @@ import LoadingStore from '@/stores/loading.js';
|
|||||||
import CompareStore from '@/stores/compare.js';
|
import CompareStore from '@/stores/compare.js';
|
||||||
import SidebarStates from '@/components/Compare/SidebarStates.vue';
|
import SidebarStates from '@/components/Compare/SidebarStates.vue';
|
||||||
import { setLineChartData } from '@/module/setChartData.js';
|
import { setLineChartData } from '@/module/setChartData.js';
|
||||||
import { simpleTimeLabel, followTimeLabel, dateLabel } from '@/module/timeLabel.js';
|
import { simpleTimeLabel, followTimeLabel, dateLabel,
|
||||||
|
setTimeStringFormatBaseOnTimeDifference,
|
||||||
|
mapTimestampToAxisTicksByFormat,
|
||||||
|
} from '@/module/timeLabel.js';
|
||||||
import i18next from '@/i18n/i18n';
|
import i18next from '@/i18n/i18n';
|
||||||
|
|
||||||
const knownLayoutChartOption = {
|
const knownLayoutChartOption = {
|
||||||
@@ -403,7 +409,7 @@ export default {
|
|||||||
* 手刻折線圖 x label 時間刻度
|
* 手刻折線圖 x label 時間刻度
|
||||||
* @param { object } valueData {min: '2022-02-20T19:54:12', max: '2023-11-27T07:21:53'}
|
* @param { object } valueData {min: '2022-02-20T19:54:12', max: '2023-11-27T07:21:53'}
|
||||||
*/
|
*/
|
||||||
xLabelsData(valueData) {
|
setXLabelsData(valueData) {
|
||||||
let min = new Date(valueData.min).getTime();
|
let min = new Date(valueData.min).getTime();
|
||||||
let max = new Date(valueData.max).getTime();
|
let max = new Date(valueData.max).getTime();
|
||||||
let numPoints = 12;
|
let numPoints = 12;
|
||||||
@@ -434,7 +440,7 @@ export default {
|
|||||||
* @param { object } chartData chart data
|
* @param { object } chartData chart data
|
||||||
* @param { object } content titels 標題文字
|
* @param { object } content titels 標題文字
|
||||||
* @param { string } yUnit y 軸單位 'date' | 'count',可傳入以上任一。
|
* @param { string } yUnit y 軸單位 'date' | 'count',可傳入以上任一。
|
||||||
* @returns { [setData, setOption] } 這兩者為符合 PriveVue 圖表格式的數據資料
|
* @returns { [primeVueSetData, primeVueSetOption] } 這兩者為符合 primeVue 圖表格式的數據資料
|
||||||
*/
|
*/
|
||||||
getLineChart(chartData, content, yUnit) {
|
getLineChart(chartData, content, yUnit) {
|
||||||
let datasetsPrimary;
|
let datasetsPrimary;
|
||||||
@@ -442,33 +448,45 @@ export default {
|
|||||||
let minX = chartData.x_axis.min;
|
let minX = chartData.x_axis.min;
|
||||||
let maxX = chartData.x_axis.max;
|
let maxX = chartData.x_axis.max;
|
||||||
let maxY = chartData.y_axis.max;
|
let maxY = chartData.y_axis.max;
|
||||||
let xData;
|
let xLabelData;
|
||||||
let labelPrimary = chartData.data[0].label;
|
let labelPrimary = chartData.data[0].label;
|
||||||
let labelSecondary = chartData.data[1].label;
|
let labelSecondary = chartData.data[1].label;
|
||||||
let setData = {};
|
let primeVueSetData = {};
|
||||||
let setOption = {};
|
let primeVueSetOption = {};
|
||||||
const getMoment = (time)=> {
|
const getMoment = (time)=> {
|
||||||
return this.$moment(time).format('YYYY/M/D hh:mm:ss')
|
return this.$moment(time).format('YYYY/M/D hh:mm:ss')
|
||||||
};
|
};
|
||||||
const getSimpleTimeLabel = simpleTimeLabel;
|
const getSimpleTimeLabel = simpleTimeLabel;
|
||||||
const getFollowTimeLabel = followTimeLabel;
|
const getFollowTimeLabel = followTimeLabel;
|
||||||
|
|
||||||
|
// fabricate x label according to y unit
|
||||||
switch (yUnit) {
|
switch (yUnit) {
|
||||||
case 'date':
|
case 'date':
|
||||||
datasetsPrimary = setLineChartData(chartData.data[0].data, chartData.x_axis.max, chartData.x_axis.min, false,
|
datasetsPrimary = setLineChartData(chartData.data[0].data, chartData.x_axis.max, chartData.x_axis.min, false,
|
||||||
chartData.y_axis.max, chartData.y_axis.min);
|
chartData.y_axis.max, chartData.y_axis.min);
|
||||||
datasetsSecondary = setLineChartData(chartData.data[1].data, chartData.x_axis.max, chartData.x_axis.min, false,
|
datasetsSecondary = setLineChartData(chartData.data[1].data, chartData.x_axis.max, chartData.x_axis.min, false,
|
||||||
chartData.y_axis.max, chartData.y_axis.min);
|
chartData.y_axis.max, chartData.y_axis.min);
|
||||||
xData = this.xLabelsData(chartData.x_axis);
|
xLabelData = this.setXLabelsData(chartData.x_axis);
|
||||||
break;
|
break;
|
||||||
case 'count': // 次數 10 個點
|
case 'count': // 次數 10 個點
|
||||||
datasetsPrimary = chartData.data[0].data;
|
datasetsPrimary = chartData.data[0].data;
|
||||||
datasetsSecondary = chartData.data[1].data;
|
datasetsSecondary = chartData.data[1].data;
|
||||||
xData = chartData.data[0].data.map(item => new Date(item.x).getTime());
|
xLabelData = chartData.data[0].data.map(item => new Date(item.x).getTime());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setData = {
|
|
||||||
labels: xData,
|
// Customize X axis ticks due to different differences between min and max of data group
|
||||||
|
const formatToSet = setTimeStringFormatBaseOnTimeDifference(minX, maxX);
|
||||||
|
const ticksOfXAxis = mapTimestampToAxisTicksByFormat(xLabelData, formatToSet);
|
||||||
|
const customizedScaleOption = this.getCustomizedScaleOption(
|
||||||
|
knownScaleLineChartOptions, {
|
||||||
|
customizeOptions: {
|
||||||
|
content, ticksOfXAxis,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
primeVueSetData = {
|
||||||
|
labels: xLabelData,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: labelPrimary,
|
label: labelPrimary,
|
||||||
@@ -488,7 +506,7 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
setOption = {
|
primeVueSetOption = {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
layout: {
|
layout: {
|
||||||
@@ -514,11 +532,11 @@ export default {
|
|||||||
display: false,
|
display: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
scales: this.customizeScaleChartOptionTitleByContent(knownScaleLineChartOptions, content),
|
scales: customizedScaleOption,
|
||||||
};
|
};
|
||||||
switch (yUnit) {
|
switch (yUnit) {
|
||||||
case 'date':
|
case 'date':
|
||||||
setOption.plugins.tooltip.callbacks.label = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||||
let value = getSimpleTimeLabel(context.parsed.y, 2);
|
let value = getSimpleTimeLabel(context.parsed.y, 2);
|
||||||
|
|
||||||
switch (context.datasetIndex) {
|
switch (context.datasetIndex) {
|
||||||
@@ -528,15 +546,15 @@ export default {
|
|||||||
return `${labelSecondary}: ${value}`;
|
return `${labelSecondary}: ${value}`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
setOption.scales.x.min = minX;
|
primeVueSetOption.scales.x.min = minX;
|
||||||
setOption.scales.x.max = maxX;
|
primeVueSetOption.scales.x.max = maxX;
|
||||||
setOption.scales.y.ticks.callback = function (value, index, ticks) {
|
primeVueSetOption.scales.y.ticks.callback = function (value, index, ticks) {
|
||||||
return getFollowTimeLabel(value, maxY, 1)
|
return getFollowTimeLabel(value, maxY, 1)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'count':
|
case 'count':
|
||||||
setOption.scales.y.ticks.precision = 0; // y 軸顯示小數點後 0 位
|
primeVueSetOption.scales.y.ticks.precision = 0; // y 軸顯示小數點後 0 位
|
||||||
setOption.plugins.tooltip.callbacks.label = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||||
let value = context.parsed.y;
|
let value = context.parsed.y;
|
||||||
|
|
||||||
switch (context.datasetIndex) {
|
switch (context.datasetIndex) {
|
||||||
@@ -549,7 +567,7 @@ export default {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [setData, setOption]
|
return [primeVueSetData, primeVueSetOption]
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 建立長條圖
|
* 建立長條圖
|
||||||
@@ -569,8 +587,8 @@ export default {
|
|||||||
let xDataSecondary;
|
let xDataSecondary;
|
||||||
let yDataSecondary;
|
let yDataSecondary;
|
||||||
let labelSecondary = chartData.data[1].label;
|
let labelSecondary = chartData.data[1].label;
|
||||||
let setData = {};
|
let primeVueSetData = {};
|
||||||
let setOption = {};
|
let primeVueSetOption = {};
|
||||||
|
|
||||||
// 轉為百分比
|
// 轉為百分比
|
||||||
datasetsPrimary = datasetsPrimary.map(value => {
|
datasetsPrimary = datasetsPrimary.map(value => {
|
||||||
@@ -590,7 +608,7 @@ export default {
|
|||||||
xDataSecondary = datasetsSecondary.map(i => i.x);
|
xDataSecondary = datasetsSecondary.map(i => i.x);
|
||||||
yDataSecondary = datasetsSecondary.map(i => i.y);
|
yDataSecondary = datasetsSecondary.map(i => i.y);
|
||||||
|
|
||||||
setData = {
|
primeVueSetData = {
|
||||||
labels: xDataPrimary,
|
labels: xDataPrimary,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
@@ -605,7 +623,7 @@ export default {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
setOption = {
|
primeVueSetOption = {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
layout: knownLayoutChartOption,
|
layout: knownLayoutChartOption,
|
||||||
@@ -644,7 +662,7 @@ export default {
|
|||||||
scales: this.customizeScaleChartOptionTitleByContent(knownScaleBarChartOptions, content),
|
scales: this.customizeScaleChartOptionTitleByContent(knownScaleBarChartOptions, content),
|
||||||
};
|
};
|
||||||
|
|
||||||
return [setData, setOption]
|
return [primeVueSetData, primeVueSetOption]
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 建立水平長條圖
|
* 建立水平長條圖
|
||||||
@@ -659,8 +677,8 @@ export default {
|
|||||||
const getFollowTimeLabel = followTimeLabel;
|
const getFollowTimeLabel = followTimeLabel;
|
||||||
const labelPrimary = chartData.data[0].label;
|
const labelPrimary = chartData.data[0].label;
|
||||||
const labelSecondary = chartData.data[1].label;
|
const labelSecondary = chartData.data[1].label;
|
||||||
let setData = {};
|
let primeVueSetData = {};
|
||||||
let setOption = {};
|
let primeVueSetOption = {};
|
||||||
|
|
||||||
// 大到小排序: Primary 為主
|
// 大到小排序: Primary 為主
|
||||||
const datasetsPrimary = chartData.data[0].data;
|
const datasetsPrimary = chartData.data[0].data;
|
||||||
@@ -677,12 +695,12 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 找出排序後,分別拉出 x, y Data
|
// 找出排序後,分別拉出 x, y Data
|
||||||
const xData = datasetsPrimary.map(item => item.x);
|
const xLabelData = datasetsPrimary.map(item => item.x);
|
||||||
const yDataPrimary = datasetsPrimary.map(item => item.y);
|
const yDataPrimary = datasetsPrimary.map(item => item.y);
|
||||||
const yDataSecondary = datasetsSecondary.map(item => item.y);
|
const yDataSecondary = datasetsSecondary.map(item => item.y);
|
||||||
|
|
||||||
setData = {
|
primeVueSetData = {
|
||||||
labels: xData,
|
labels: xLabelData,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: labelPrimary,
|
label: labelPrimary,
|
||||||
@@ -696,7 +714,7 @@ export default {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
setOption = {
|
primeVueSetOption = {
|
||||||
indexAxis: 'y',
|
indexAxis: 'y',
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
@@ -723,7 +741,7 @@ export default {
|
|||||||
};
|
};
|
||||||
switch (xUnit) {
|
switch (xUnit) {
|
||||||
case 'date':
|
case 'date':
|
||||||
setOption.plugins.tooltip.callbacks.label = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||||
let value = context.parsed.y;
|
let value = context.parsed.y;
|
||||||
|
|
||||||
value = context.parsed.x === null ? "n/a" : getSimpleTimeLabel(context.parsed.x, 2);
|
value = context.parsed.x === null ? "n/a" : getSimpleTimeLabel(context.parsed.x, 2);
|
||||||
@@ -734,13 +752,13 @@ export default {
|
|||||||
return `${labelSecondary}: ${value}`;
|
return `${labelSecondary}: ${value}`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
setOption.scales.x.ticks.callback = function (value, index, ticks) {
|
primeVueSetOption.scales.x.ticks.callback = function (value, index, ticks) {
|
||||||
return getFollowTimeLabel(value, maxY, 1)
|
return getFollowTimeLabel(value, maxY, 1)
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'count':
|
case 'count':
|
||||||
setOption.scales.x.ticks.precision = 0; // x 軸顯示小數點後 0 位
|
primeVueSetOption.scales.x.ticks.precision = 0; // x 軸顯示小數點後 0 位
|
||||||
setOption.plugins.tooltip.callbacks.label = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||||
let value = context.parsed.y;
|
let value = context.parsed.y;
|
||||||
|
|
||||||
value = context.parsed.x === null ? "n/a" : context.parsed.x;
|
value = context.parsed.x === null ? "n/a" : context.parsed.x;
|
||||||
@@ -754,22 +772,22 @@ export default {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(isSingle) { // 設定一個活動的 y label、提示框文字
|
if(isSingle) { // 設定一個活動的 y label、提示框文字
|
||||||
setOption.plugins.tooltip.callbacks.title = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.title = function(context) {
|
||||||
return `${content.y}: ${context[0].label}`;
|
return `${content.y}: ${context[0].label}`;
|
||||||
};
|
};
|
||||||
setOption.scales.y.ticks.callback = function (value, index, ticks) {
|
primeVueSetOption.scales.y.ticks.callback = function (value, index, ticks) {
|
||||||
let label = xData[index];
|
let label = xLabelData[index];
|
||||||
if(label) {
|
if(label) {
|
||||||
return label.length > 21 ? `${label.substring(0, 18)}...` : label
|
return label.length > 21 ? `${label.substring(0, 18)}...` : label
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}else { // 設定「活動」到「活動」的 y label、提示框文字
|
}else { // 設定「活動」到「活動」的 y label、提示框文字
|
||||||
setOption.plugins.tooltip.callbacks.title = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.title = function(context) {
|
||||||
return `${content.y}: ${context[0].label.replace(',', ' - ')}`
|
return `${content.y}: ${context[0].label.replace(',', ' - ')}`
|
||||||
};
|
};
|
||||||
setOption.scales.y.ticks.callback = function (value, index, ticks) {
|
primeVueSetOption.scales.y.ticks.callback = function (value, index, ticks) {
|
||||||
let label = xData[index];
|
let label = xLabelData[index];
|
||||||
let labelStart = label[0];
|
let labelStart = label[0];
|
||||||
let labelEnd = label[1];
|
let labelEnd = label[1];
|
||||||
|
|
||||||
@@ -779,9 +797,28 @@ export default {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return [setData, setOption]
|
return [primeVueSetData, primeVueSetOption]
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 在一個基本的物件上加以客製化這個物件,客製化的參照來源是 content 的內容
|
||||||
|
* 之所以有辦法這樣撰寫,是因為我們知道物件的順序是先 x 再 title 再 text
|
||||||
* This function alters the title property of known scales object of Chart option
|
* 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.
|
* 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 {object} whichScaleObj PrimeVue scale option object to reference to
|
||||||
@@ -812,7 +849,28 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} scaleObjectToAlter this object follows the format of prive vue chart
|
||||||
|
* @param {Array<string>} 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() {
|
async created() {
|
||||||
this.isLoading = true; // moubeted 才停止 loading
|
this.isLoading = true; // moubeted 才停止 loading
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ export default {
|
|||||||
* 手刻折線圖 x label 時間刻度
|
* 手刻折線圖 x label 時間刻度
|
||||||
* @param { object } valueData {min: '2022-02-20T19:54:12', max: '2023-11-27T07:21:53'}
|
* @param { object } valueData {min: '2022-02-20T19:54:12', max: '2023-11-27T07:21:53'}
|
||||||
*/
|
*/
|
||||||
xLabelsData(valueData) {
|
setXLabelsData(valueData) {
|
||||||
let min = new Date(valueData.min).getTime();
|
let min = new Date(valueData.min).getTime();
|
||||||
let max = new Date(valueData.max).getTime();
|
let max = new Date(valueData.max).getTime();
|
||||||
let numPoints = 12;
|
let numPoints = 12;
|
||||||
@@ -260,8 +260,8 @@ export default {
|
|||||||
let maxX = chartData.x_axis.max;
|
let maxX = chartData.x_axis.max;
|
||||||
let maxY = chartData.y_axis.max;
|
let maxY = chartData.y_axis.max;
|
||||||
let xData;
|
let xData;
|
||||||
let setData = {};
|
let primeVueSetData = {};
|
||||||
let setOption = {};
|
let primeVueSetOption = {};
|
||||||
const getMoment = (time)=> {
|
const getMoment = (time)=> {
|
||||||
return this.$moment(time).format('YYYY/M/D hh:mm:ss')
|
return this.$moment(time).format('YYYY/M/D hh:mm:ss')
|
||||||
};
|
};
|
||||||
@@ -272,14 +272,14 @@ export default {
|
|||||||
case 'date':
|
case 'date':
|
||||||
datasets = setLineChartData(chartData.data, chartData.x_axis.max, chartData.x_axis.min, false, chartData.y_axis.max,
|
datasets = setLineChartData(chartData.data, chartData.x_axis.max, chartData.x_axis.min, false, chartData.y_axis.max,
|
||||||
chartData.y_axis.min);
|
chartData.y_axis.min);
|
||||||
xData = this.xLabelsData(chartData.x_axis);
|
xData = this.setXLabelsData(chartData.x_axis);
|
||||||
break;
|
break;
|
||||||
case 'count': // 次數 10 個點
|
case 'count': // 次數 10 個點
|
||||||
datasets = chartData.data;
|
datasets = chartData.data;
|
||||||
xData = chartData.data.map(item => new Date(item.x).getTime());
|
xData = chartData.data.map(item => new Date(item.x).getTime());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setData = {
|
primeVueSetData = {
|
||||||
labels: xData,
|
labels: xData,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
@@ -291,7 +291,7 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
setOption = {
|
primeVueSetOption = {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
layout: {
|
layout: {
|
||||||
@@ -374,24 +374,24 @@ export default {
|
|||||||
};
|
};
|
||||||
switch (yUnit) {
|
switch (yUnit) {
|
||||||
case 'date':
|
case 'date':
|
||||||
setOption.plugins.tooltip.callbacks.label = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||||
return `${content.y}: ${getSimpleTimeLabel(context.parsed.y, 2)}`;
|
return `${content.y}: ${getSimpleTimeLabel(context.parsed.y, 2)}`;
|
||||||
};
|
};
|
||||||
setOption.scales.x.min = minX;
|
primeVueSetOption.scales.x.min = minX;
|
||||||
setOption.scales.x.max = maxX;
|
primeVueSetOption.scales.x.max = maxX;
|
||||||
setOption.scales.y.ticks.callback = function (value, index, ticks) {
|
primeVueSetOption.scales.y.ticks.callback = function (value, index, ticks) {
|
||||||
return getFollowTimeLabel(value, maxY, 1)
|
return getFollowTimeLabel(value, maxY, 1)
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'count':
|
case 'count':
|
||||||
setOption.scales.y.ticks.precision = 0; // y 軸顯示小數點後 0 位
|
primeVueSetOption.scales.y.ticks.precision = 0; // y 軸顯示小數點後 0 位
|
||||||
setOption.plugins.tooltip.callbacks.label = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||||
return `${content.y}: ${context.parsed.y}`;
|
return `${content.y}: ${context.parsed.y}`;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [setData, setOption]
|
return [primeVueSetData, primeVueSetOption]
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 建立長條圖
|
* 建立長條圖
|
||||||
@@ -406,8 +406,8 @@ export default {
|
|||||||
let datasets = chartData.data;
|
let datasets = chartData.data;
|
||||||
let xData;
|
let xData;
|
||||||
let yData;
|
let yData;
|
||||||
let setData = {};
|
let primeVueSetData = {};
|
||||||
let setOption = {};
|
let primeVueSetOption = {};
|
||||||
|
|
||||||
datasets = datasets.map(value => {
|
datasets = datasets.map(value => {
|
||||||
return {
|
return {
|
||||||
@@ -418,7 +418,7 @@ export default {
|
|||||||
xData = datasets.map(i => i.x);
|
xData = datasets.map(i => i.x);
|
||||||
yData = datasets.map(i => i.y)
|
yData = datasets.map(i => i.y)
|
||||||
|
|
||||||
setData = {
|
primeVueSetData = {
|
||||||
labels: xData,
|
labels: xData,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
@@ -428,7 +428,7 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
setOption = {
|
primeVueSetOption = {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
layout: {
|
layout: {
|
||||||
@@ -505,7 +505,7 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return [setData, setOption]
|
return [primeVueSetData, primeVueSetOption]
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 建立水平長條圖
|
* 建立水平長條圖
|
||||||
@@ -518,15 +518,15 @@ export default {
|
|||||||
const maxY = chartData.y_axis.max;
|
const maxY = chartData.y_axis.max;
|
||||||
const getSimpleTimeLabel = simpleTimeLabel;
|
const getSimpleTimeLabel = simpleTimeLabel;
|
||||||
const getFollowTimeLabel = followTimeLabel;
|
const getFollowTimeLabel = followTimeLabel;
|
||||||
let setData = {};
|
let primeVueSetData = {};
|
||||||
let setOption = {};
|
let primeVueSetOption = {};
|
||||||
|
|
||||||
// 大到小排序
|
// 大到小排序
|
||||||
chartData.data.sort((a, b) => b.y - a.y);
|
chartData.data.sort((a, b) => b.y - a.y);
|
||||||
const xData = chartData.data.map(item => item.x);
|
const xData = chartData.data.map(item => item.x);
|
||||||
const yData = chartData.data.map(item => item.y);
|
const yData = chartData.data.map(item => item.y);
|
||||||
|
|
||||||
setData = {
|
primeVueSetData = {
|
||||||
labels: xData,
|
labels: xData,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
@@ -536,7 +536,7 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
setOption = {
|
primeVueSetOption = {
|
||||||
indexAxis: 'y',
|
indexAxis: 'y',
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
@@ -609,33 +609,33 @@ export default {
|
|||||||
};
|
};
|
||||||
switch (xUnit) {
|
switch (xUnit) {
|
||||||
case 'date':
|
case 'date':
|
||||||
setOption.plugins.tooltip.callbacks.label = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||||
return `${content.x}: ${getSimpleTimeLabel(context.parsed.x, 2)}`;
|
return `${content.x}: ${getSimpleTimeLabel(context.parsed.x, 2)}`;
|
||||||
};
|
};
|
||||||
setOption.scales.x.ticks.callback = function (value, index, ticks) {
|
primeVueSetOption.scales.x.ticks.callback = function (value, index, ticks) {
|
||||||
return getFollowTimeLabel(value, maxY, 1)
|
return getFollowTimeLabel(value, maxY, 1)
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'count':
|
case 'count':
|
||||||
setOption.scales.x.ticks.precision = 0; // x 軸顯示小數點後 0 位
|
primeVueSetOption.scales.x.ticks.precision = 0; // x 軸顯示小數點後 0 位
|
||||||
setOption.plugins.tooltip.callbacks.label = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.label = function(context) {
|
||||||
return `${content.x}: ${context.parsed.x}`;
|
return `${content.x}: ${context.parsed.x}`;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(isSingle) { // 設定一個活動的 y label、提示框文字
|
if(isSingle) { // 設定一個活動的 y label、提示框文字
|
||||||
setOption.plugins.tooltip.callbacks.title = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.title = function(context) {
|
||||||
return `${content.y}: ${context[0].label}`;
|
return `${content.y}: ${context[0].label}`;
|
||||||
};
|
};
|
||||||
setOption.scales.y.ticks.callback = function (value, index, ticks) {
|
primeVueSetOption.scales.y.ticks.callback = function (value, index, ticks) {
|
||||||
let label = xData[index];
|
let label = xData[index];
|
||||||
return label.length > 21 ? `${label.substring(0, 18)}...` : label
|
return label.length > 21 ? `${label.substring(0, 18)}...` : label
|
||||||
};
|
};
|
||||||
}else { // 設定「活動」到「活動」的 y label、提示框文字
|
}else { // 設定「活動」到「活動」的 y label、提示框文字
|
||||||
setOption.plugins.tooltip.callbacks.title = function(context) {
|
primeVueSetOption.plugins.tooltip.callbacks.title = function(context) {
|
||||||
return `${content.y}: ${context[0].label.replace(',', ' - ')}`
|
return `${content.y}: ${context[0].label.replace(',', ' - ')}`
|
||||||
};
|
};
|
||||||
setOption.scales.y.ticks.callback = function (value, index, ticks) {
|
primeVueSetOption.scales.y.ticks.callback = function (value, index, ticks) {
|
||||||
let label = xData[index];
|
let label = xData[index];
|
||||||
let labelStart = label[0];
|
let labelStart = label[0];
|
||||||
let labelEnd = label[1];
|
let labelEnd = label[1];
|
||||||
@@ -646,7 +646,7 @@ export default {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return [setData, setOption]
|
return [primeVueSetData, primeVueSetOption]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
|
|||||||
Reference in New Issue
Block a user