'commit'
This commit is contained in:
123
static/js/app.js
123
static/js/app.js
@@ -35,6 +35,8 @@ createApp({
|
||||
const priceTableRows = ref([]);
|
||||
const hourlyPricesByOperator = ref({});
|
||||
let chartInstance = null;
|
||||
const chartType = ref('line');
|
||||
let chartInterval = null;
|
||||
|
||||
const initChart = () => {
|
||||
const dom = document.getElementById("chart");
|
||||
@@ -43,6 +45,75 @@ createApp({
|
||||
}
|
||||
};
|
||||
|
||||
const renderChart = () => {
|
||||
if (!chartInstance) return;
|
||||
|
||||
const series = operators.value.map(op => {
|
||||
const seriesData = [];
|
||||
for (let h = 0; h < 24; h++) {
|
||||
const list = hourlyPricesByOperator.value[op.value] || [];
|
||||
seriesData.push(list[h] !== undefined ? list[h] : null);
|
||||
}
|
||||
|
||||
if (chartType.value === 'bar') {
|
||||
return {
|
||||
name: op.label,
|
||||
type: "bar",
|
||||
barGap: 0,
|
||||
emphasis: { focus: 'series' },
|
||||
data: seriesData
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
name: op.label,
|
||||
type: "line",
|
||||
smooth: true,
|
||||
emphasis: { focus: 'series' },
|
||||
data: seriesData
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const hours = [];
|
||||
for (let h = 0; h < 24; h++) {
|
||||
hours.push(h.toString().padStart(2,"0") + ":00");
|
||||
}
|
||||
|
||||
const option = {
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
backgroundColor: 'rgba(30, 41, 59, 0.9)',
|
||||
borderColor: '#334155',
|
||||
textStyle: { color: '#f1f5f9' },
|
||||
axisPointer: { type: chartType.value === 'bar' ? 'shadow' : 'line' }
|
||||
},
|
||||
legend: {
|
||||
data: operators.value.map(o => o.label),
|
||||
textStyle: { color: "#94a3b8" },
|
||||
bottom: 0
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: hours,
|
||||
axisLine: { lineStyle: { color: "#475569" } },
|
||||
axisLabel: { color: "#94a3b8" }
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
name: "元/度",
|
||||
nameTextStyle: { color: "#94a3b8" },
|
||||
axisLine: { lineStyle: { color: "#475569" } },
|
||||
axisLabel: { color: "#94a3b8" },
|
||||
splitLine: { lineStyle: { color: "#334155", type: 'dashed' } }
|
||||
},
|
||||
grid: { left: 50, right: 30, top: 40, bottom: 40 },
|
||||
series: series
|
||||
};
|
||||
|
||||
chartInstance.setOption(option, true);
|
||||
};
|
||||
|
||||
const buildPriceTable = () => {
|
||||
const rows = [];
|
||||
for (let h = 0; h < 24; h++) {
|
||||
@@ -55,48 +126,7 @@ createApp({
|
||||
rows.push(row);
|
||||
}
|
||||
priceTableRows.value = rows;
|
||||
if (chartInstance) {
|
||||
const series = operators.value.map(op => {
|
||||
const seriesData = [];
|
||||
for (let h = 0; h < 24; h++) {
|
||||
const list = hourlyPricesByOperator.value[op.value] || [];
|
||||
seriesData.push(list[h] !== undefined ? list[h] : null);
|
||||
}
|
||||
return {name: op.label, type:"line", smooth:true, data:seriesData};
|
||||
});
|
||||
const hours = rows.map(r => r.hour);
|
||||
const option = {
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
backgroundColor: 'rgba(30, 41, 59, 0.9)',
|
||||
borderColor: '#334155',
|
||||
textStyle: { color: '#f1f5f9' }
|
||||
},
|
||||
legend: {
|
||||
data: operators.value.map(o => o.label),
|
||||
textStyle: { color: "#94a3b8" },
|
||||
bottom: 0
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: hours,
|
||||
axisLine: { lineStyle: { color: "#475569" } },
|
||||
axisLabel: { color: "#94a3b8" }
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
name: "元/度",
|
||||
nameTextStyle: { color: "#94a3b8" },
|
||||
axisLine: { lineStyle: { color: "#475569" } },
|
||||
axisLabel: { color: "#94a3b8" },
|
||||
splitLine: { lineStyle: { color: "#334155", type: 'dashed' } }
|
||||
},
|
||||
grid: { left: 50, right: 30, top: 40, bottom: 40 },
|
||||
series: series
|
||||
};
|
||||
chartInstance.setOption(option);
|
||||
}
|
||||
renderChart();
|
||||
};
|
||||
|
||||
const loadAllOperatorsPrices = async () => {
|
||||
@@ -440,6 +470,7 @@ createApp({
|
||||
{left: '\\(', right: '\\)', display: false},
|
||||
{left: '\\[', right: '\\]', display: true}
|
||||
],
|
||||
ignoredTags: ["script", "noscript", "style", "textarea"], // Removed 'pre', 'code' to allow math in code blocks
|
||||
throwOnError: false
|
||||
});
|
||||
}
|
||||
@@ -457,6 +488,7 @@ createApp({
|
||||
{left: '\\(', right: '\\)', display: false},
|
||||
{left: '\\[', right: '\\]', display: true}
|
||||
],
|
||||
ignoredTags: ["script", "noscript", "style", "textarea"], // Removed 'pre', 'code' to allow math in code blocks
|
||||
throwOnError: false
|
||||
});
|
||||
}
|
||||
@@ -474,6 +506,13 @@ createApp({
|
||||
initChart();
|
||||
loadAllOperatorsPrices();
|
||||
startAiAnalysis();
|
||||
|
||||
// Start Chart Type Carousel (10s interval)
|
||||
if (chartInterval) clearInterval(chartInterval);
|
||||
chartInterval = setInterval(() => {
|
||||
chartType.value = chartType.value === 'line' ? 'bar' : 'line';
|
||||
renderChart();
|
||||
}, 10000);
|
||||
|
||||
// Degree QR Code
|
||||
if (!isMobile.value && typeof QRCode !== 'undefined') {
|
||||
|
||||
Reference in New Issue
Block a user