添加统计图
This commit is contained in:
parent
f7722ea708
commit
bc48ba4734
|
|
@ -3,6 +3,7 @@ import { defHttp } from '/@/utils/http/axios';
|
|||
enum Api {
|
||||
slcx = '/exportapi/homeApi/slcx',
|
||||
cqglfgswd = '/exportapi/homeApi/cqglfgswd',
|
||||
getStaticList = '/exportapi/homeApi/getStaticList',
|
||||
glfzb = '/exportapi/homeApi/glfzb',
|
||||
}
|
||||
|
||||
|
|
@ -21,6 +22,9 @@ export const slcx = () => {
|
|||
export const cqglfgswd = () => {
|
||||
return defHttp.post({ url: Api.cqglfgswd });
|
||||
};
|
||||
export const getStaticList = (params) => {
|
||||
return defHttp.post({ url: Api.getStaticList,params });
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,184 @@
|
|||
<template>
|
||||
<div ref="cityChartRef" ></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { slcx, cqglfgswd } from '/@/api/dashboard/api';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
const countyFlowChartRef = ref<HTMLElement | null>(null);
|
||||
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let countyChart: echarts.ECharts | null = null;
|
||||
let countyPowerChart: echarts.ECharts | null = null;
|
||||
let countyFlowChart: echarts.ECharts | null = null;
|
||||
|
||||
let cityOption: any = null;
|
||||
let countyOption: any = null;
|
||||
let countyPowerOption: any = null;
|
||||
let countyFlowOption: any = null;
|
||||
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('城区'));
|
||||
const county = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city), county: sortByTime(county) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
const { city, county } = splitByRegion(records);
|
||||
|
||||
const cityX = buildXAxis(city, 'view028');
|
||||
const citySW = city.map((r: any) => safeNum(r.view005));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view006));
|
||||
cityOption = {
|
||||
title: { text: '城区供/回水温度【实时】', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '℃' },
|
||||
series: [
|
||||
{ name: '供水温度', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水温度', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
|
||||
const countyX = buildXAxis(county, 'view028');
|
||||
const countySW = county.map((r: any) => safeNum(r.view035));
|
||||
const countyHW = county.map((r: any) => safeNum(r.view036));
|
||||
countyOption = {
|
||||
title: { text: '郊县供/回水温度【实时】', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: countyX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '℃' },
|
||||
series: [
|
||||
{ name: '供水温度', type: 'line', data: countySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水温度', type: 'line', data: countyHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#D64545', '#12A0A6']
|
||||
};
|
||||
|
||||
const powerY = county.map((r: any) => safeNum(r.view041));
|
||||
countyPowerOption = {
|
||||
title: { text: '', left: 'center', top: 8 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: { left: '6%', right: '6%', bottom: 60, top: 50, containLabel: true },
|
||||
xAxis: { type: 'category', data: countyX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '瞬时热量' },
|
||||
series: [{ name: '瞬时热量', type: 'line', data: powerY, smooth: false, areaStyle: {}, showSymbol: false, lineStyle: { type: 'solid' } }],
|
||||
color: ['#E89B3B']
|
||||
};
|
||||
|
||||
const flowY = county.map((r: any) => safeNum(r.view037));
|
||||
countyFlowOption = {
|
||||
title: { text: '', left: 'center', top: 8 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: { left: '6%', right: '6%', bottom: 60, top: 50, containLabel: true },
|
||||
xAxis: { type: 'category', data: countyX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '瞬时流量' },
|
||||
series: [{ name: '瞬时流量', type: 'line', data: flowY, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }],
|
||||
color: ['#7C55FF']
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
countyChart?.resize();
|
||||
countyPowerChart?.resize();
|
||||
countyFlowChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
function initCityIfNeed() {
|
||||
if (!cityChart && cityChartRef.value && cityOption) {
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart.setOption(cityOption);
|
||||
} else {
|
||||
cityChart?.resize();
|
||||
}
|
||||
}
|
||||
|
||||
function onTabChange(key: string) {
|
||||
nextTick(() => {
|
||||
if (key === 'city') {
|
||||
if (!cityChart && cityChartRef.value) {
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
}
|
||||
cityChart?.setOption(cityOption, true);
|
||||
cityChart?.resize();
|
||||
} else if (key === 'county') {
|
||||
countyChart?.setOption(countyOption, true);
|
||||
countyChart?.resize();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let timer: number | null = null;
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
try {
|
||||
|
||||
// 2. 获取图表数据
|
||||
const r = await cqglfgswd();
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
|
||||
// 4. 初始化或更新图表(你的这段代码)
|
||||
if (!cityChart && cityChartRef.value) {
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
}
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<div class="container2">
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('城区'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
console.log("🚀 ~ prepareOptions ~ records:", records)
|
||||
const { city } = splitByRegion(records);
|
||||
console.log("🚀 ~ prepareOptions ~ city:", city)
|
||||
|
||||
const cityX = buildXAxis(city, 'view028');
|
||||
console.log("🚀 ~ prepareOptions ~ cityX:", cityX)
|
||||
const citySW = city.map((r: any) => safeNum(r.view005));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view006));
|
||||
cityOption = {
|
||||
title: { text: '城区锅炉房供/回水温度', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '℃' },
|
||||
series: [
|
||||
{ name: '供水温度', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水温度', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await cqglfgswd();
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container2 {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<div style="background-color: #fff;padding:14px;height: 100%;">
|
||||
<a-row :span="24" style="margin-top:10px;">
|
||||
<a-col :span="4" style="padding-left: 30px;">
|
||||
<a-select ref="select"
|
||||
placeholder="选择锅炉房"
|
||||
v-model:value="queryParam.sourceId"
|
||||
style="width: 155px;"
|
||||
@focus="focus"
|
||||
@change="handleChange">
|
||||
<a-select-option :value="item.sourceId" v-for="item in heatsource" :key="item.id">{{item.sourceName}}</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-date-picker v-model:value="queryParam.startDate" value-format="YYYY-MM" picker="month" placeholder="请选择时间" @change="handleChange" />
|
||||
</a-col>
|
||||
<a-col :span="24" >
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
import { heatsourcelist } from "@/views/base/simconfig/Simconfig.api";
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
const queryParam = ref<any>({});
|
||||
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
const heatsource = ref();
|
||||
async function getHeatsource(){
|
||||
heatsource.value = await heatsourcelist({regionType: '城区'});
|
||||
}
|
||||
|
||||
async function handleChange(){
|
||||
loadData();
|
||||
}
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('城区'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
const { city } = splitByRegion(records);
|
||||
|
||||
const cityX = buildXAxis(city, 'datatime');
|
||||
const citySW = city.map((r: any) => safeNum(r.view005));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view006));
|
||||
cityOption = {
|
||||
title: { text: '城区锅炉房历史供/回水温度', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '℃' },
|
||||
series: [
|
||||
{ name: '供水温度', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水温度', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
console.log("🚀 ~ loadData ~ queryParam.value:", queryParam.value)
|
||||
queryParam.value.startTime = dayjs(queryParam.value.startDate).format('YYMM');
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await getStaticList(queryParam.value);
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted( async () => {
|
||||
await getHeatsource()
|
||||
var list = heatsource.value
|
||||
queryParam.value.sourceId = list[0].sourceId
|
||||
queryParam.value.startDate = dayjs().format('YYYY-MM');
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.bjclass {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<div class="container2">
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
console.log("🚀 ~ prepareOptions ~ records:", records)
|
||||
const { city } = splitByRegion(records);
|
||||
console.log("🚀 ~ prepareOptions ~ city:", city)
|
||||
|
||||
const cityX = buildXAxis(city, 'view028');
|
||||
console.log("🚀 ~ prepareOptions ~ cityX:", cityX)
|
||||
const citySW = city.map((r: any) => safeNum(r.view005));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view006));
|
||||
cityOption = {
|
||||
title: { text: '郊县锅炉房供/回水温度', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '℃' },
|
||||
series: [
|
||||
{ name: '供水温度', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水温度', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await cqglfgswd();
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container2 {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<div style="background-color: #fff;padding:14px;height: 100%;">
|
||||
<a-row :span="24" style="margin-top:10px;">
|
||||
<a-col :span="4" style="padding-left: 30px;">
|
||||
<a-select ref="select"
|
||||
placeholder="选择锅炉房"
|
||||
v-model:value="queryParam.sourceId"
|
||||
style="width: 155px;"
|
||||
@focus="focus"
|
||||
@change="handleChange">
|
||||
<a-select-option :value="item.sourceId" v-for="item in heatsource" :key="item.id">{{item.sourceName}}</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-date-picker v-model:value="queryParam.startDate" value-format="YYYY-MM" picker="month" placeholder="请选择时间" @change="handleChange" />
|
||||
</a-col>
|
||||
<a-col :span="24" >
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
import { heatsourcelist } from "@/views/base/simconfig/Simconfig.api";
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
const queryParam = ref<any>({});
|
||||
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
const heatsource = ref();
|
||||
async function getHeatsource(){
|
||||
heatsource.value = await heatsourcelist({regionType: '郊县'});
|
||||
}
|
||||
|
||||
async function handleChange(){
|
||||
loadData();
|
||||
}
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
const { city } = splitByRegion(records);
|
||||
|
||||
const cityX = buildXAxis(city, 'datatime');
|
||||
const citySW = city.map((r: any) => safeNum(r.view005));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view006));
|
||||
cityOption = {
|
||||
title: { text: '郊县锅炉房历史供/回水温度', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '℃' },
|
||||
series: [
|
||||
{ name: '供水温度', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水温度', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
console.log("🚀 ~ loadData ~ queryParam.value:", queryParam.value)
|
||||
queryParam.value.startTime = dayjs(queryParam.value.startDate).format('YYMM');
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await getStaticList(queryParam.value);
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted( async () => {
|
||||
await getHeatsource()
|
||||
var list = heatsource.value
|
||||
queryParam.value.sourceId = list[0].sourceId
|
||||
queryParam.value.startDate = dayjs().format('YYYY-MM');
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.bjclass {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<div class="container2">
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
console.log("🚀 ~ prepareOptions ~ records:", records)
|
||||
const { city } = splitByRegion(records);
|
||||
console.log("🚀 ~ prepareOptions ~ city:", city)
|
||||
|
||||
const cityX = buildXAxis(city, 'view028');
|
||||
console.log("🚀 ~ prepareOptions ~ cityX:", cityX)
|
||||
const citySW = city.map((r: any) => safeNum(r.view037));
|
||||
cityOption = {
|
||||
title: { text: '郊县锅炉房热流量', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: 'Kj' },
|
||||
series: [
|
||||
{ name: '热流量', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await cqglfgswd();
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container2 {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<div style="background-color: #fff;padding:14px;height: 100%;">
|
||||
<a-row :span="24" style="margin-top:10px;">
|
||||
<a-col :span="4" style="padding-left: 30px;">
|
||||
<a-select ref="select"
|
||||
placeholder="选择锅炉房"
|
||||
v-model:value="queryParam.sourceId"
|
||||
style="width: 155px;"
|
||||
@focus="focus"
|
||||
@change="handleChange">
|
||||
<a-select-option :value="item.sourceId" v-for="item in heatsource" :key="item.id">{{item.sourceName}}</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-date-picker v-model:value="queryParam.startDate" value-format="YYYY-MM" picker="month" placeholder="请选择时间" @change="handleChange" />
|
||||
</a-col>
|
||||
<a-col :span="24" >
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
import { heatsourcelist } from "@/views/base/simconfig/Simconfig.api";
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
const queryParam = ref<any>({});
|
||||
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
const heatsource = ref();
|
||||
async function getHeatsource(){
|
||||
heatsource.value = await heatsourcelist({regionType: '郊县'});
|
||||
}
|
||||
|
||||
async function handleChange(){
|
||||
loadData();
|
||||
}
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
const { city } = splitByRegion(records);
|
||||
|
||||
const cityX = buildXAxis(city, 'datatime');
|
||||
const citySW = city.map((r: any) => safeNum(r.view037));
|
||||
cityOption = {
|
||||
title: { text: '郊县锅炉房历史热流量', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: 'Kj' },
|
||||
series: [
|
||||
{ name: '热流量', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
console.log("🚀 ~ loadData ~ queryParam.value:", queryParam.value)
|
||||
queryParam.value.startTime = dayjs(queryParam.value.startDate).format('YYMM');
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await getStaticList(queryParam.value);
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted( async () => {
|
||||
await getHeatsource()
|
||||
var list = heatsource.value
|
||||
queryParam.value.sourceId = list[0].sourceId
|
||||
queryParam.value.startDate = dayjs().format('YYYY-MM');
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.bjclass {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<div class="container2">
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
console.log("🚀 ~ prepareOptions ~ records:", records)
|
||||
const { city } = splitByRegion(records);
|
||||
console.log("🚀 ~ prepareOptions ~ city:", city)
|
||||
|
||||
const cityX = buildXAxis(city, 'view028');
|
||||
console.log("🚀 ~ prepareOptions ~ cityX:", cityX)
|
||||
const citySW = city.map((r: any) => safeNum(r.view041));
|
||||
cityOption = {
|
||||
title: { text: '郊县锅炉房水流量', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: 'm³/s' },
|
||||
series: [
|
||||
{ name: '水流量', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await cqglfgswd();
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container2 {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<div style="background-color: #fff;padding:14px;height: 100%;">
|
||||
<a-row :span="24" style="margin-top:10px;">
|
||||
<a-col :span="4" style="padding-left: 30px;">
|
||||
<a-select ref="select"
|
||||
placeholder="选择锅炉房"
|
||||
v-model:value="queryParam.sourceId"
|
||||
style="width: 155px;"
|
||||
@focus="focus"
|
||||
@change="handleChange">
|
||||
<a-select-option :value="item.sourceId" v-for="item in heatsource" :key="item.id">{{item.sourceName}}</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-date-picker v-model:value="queryParam.startDate" value-format="YYYY-MM" picker="month" placeholder="请选择时间" @change="handleChange" />
|
||||
</a-col>
|
||||
<a-col :span="24" >
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
import { heatsourcelist } from "@/views/base/simconfig/Simconfig.api";
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
const queryParam = ref<any>({});
|
||||
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
const heatsource = ref();
|
||||
async function getHeatsource(){
|
||||
heatsource.value = await heatsourcelist({regionType: '郊县'});
|
||||
}
|
||||
|
||||
async function handleChange(){
|
||||
loadData();
|
||||
}
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
const { city } = splitByRegion(records);
|
||||
|
||||
const cityX = buildXAxis(city, 'datatime');
|
||||
const citySW = city.map((r: any) => safeNum(r.view037));
|
||||
cityOption = {
|
||||
title: { text: '郊县锅炉房历史水流量', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: 'm³/s' },
|
||||
series: [
|
||||
{ name: '水流量', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
console.log("🚀 ~ loadData ~ queryParam.value:", queryParam.value)
|
||||
queryParam.value.startTime = dayjs(queryParam.value.startDate).format('YYMM');
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await getStaticList(queryParam.value);
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted( async () => {
|
||||
await getHeatsource()
|
||||
var list = heatsource.value
|
||||
queryParam.value.sourceId = list[0].sourceId
|
||||
queryParam.value.startDate = dayjs().format('YYYY-MM');
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.bjclass {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<div class="container2">
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('城区'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
console.log("🚀 ~ prepareOptions ~ records:", records)
|
||||
const { city } = splitByRegion(records);
|
||||
console.log("🚀 ~ prepareOptions ~ city:", city)
|
||||
|
||||
const cityX = buildXAxis(city, 'view028');
|
||||
console.log("🚀 ~ prepareOptions ~ cityX:", cityX)
|
||||
const citySW = city.map((r: any) => safeNum(r.view007));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view008));
|
||||
cityOption = {
|
||||
title: { text: '城区锅炉房供/回水压力', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: 'Pa' },
|
||||
series: [
|
||||
{ name: '供水压力', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水压力', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await cqglfgswd();
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container2 {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<div style="background-color: #fff;padding:14px;height: 100%;">
|
||||
<a-row :span="24" style="margin-top:10px;">
|
||||
<a-col :span="4" style="padding-left: 30px;">
|
||||
<a-select ref="select"
|
||||
placeholder="选择锅炉房"
|
||||
v-model:value="queryParam.sourceId"
|
||||
style="width: 155px;"
|
||||
@focus="focus"
|
||||
@change="handleChange">
|
||||
<a-select-option :value="item.sourceId" v-for="item in heatsource" :key="item.id">{{item.sourceName}}</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-date-picker v-model:value="queryParam.startDate" value-format="YYYY-MM" picker="month" placeholder="请选择时间" @change="handleChange" />
|
||||
</a-col>
|
||||
<a-col :span="24" >
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
import { heatsourcelist } from "@/views/base/simconfig/Simconfig.api";
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
const queryParam = ref<any>({});
|
||||
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
const heatsource = ref();
|
||||
async function getHeatsource(){
|
||||
heatsource.value = await heatsourcelist({regionType: '城区'});
|
||||
}
|
||||
|
||||
async function handleChange(){
|
||||
loadData();
|
||||
}
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('城区'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
const { city } = splitByRegion(records);
|
||||
|
||||
const cityX = buildXAxis(city, 'datatime');
|
||||
const citySW = city.map((r: any) => safeNum(r.view007));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view008));
|
||||
cityOption = {
|
||||
title: { text: '城区锅炉房历史供/回水压力', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: 'Pa' },
|
||||
series: [
|
||||
{ name: '供水压力', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水压力', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
console.log("🚀 ~ loadData ~ queryParam.value:", queryParam.value)
|
||||
queryParam.value.startTime = dayjs(queryParam.value.startDate).format('YYMM');
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await getStaticList(queryParam.value);
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted( async () => {
|
||||
await getHeatsource()
|
||||
var list = heatsource.value
|
||||
queryParam.value.sourceId = list[0].sourceId
|
||||
queryParam.value.startDate = dayjs().format('YYYY-MM');
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.bjclass {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<div class="container2">
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
console.log("🚀 ~ prepareOptions ~ records:", records)
|
||||
const { city } = splitByRegion(records);
|
||||
console.log("🚀 ~ prepareOptions ~ city:", city)
|
||||
|
||||
const cityX = buildXAxis(city, 'view028');
|
||||
console.log("🚀 ~ prepareOptions ~ cityX:", cityX)
|
||||
const citySW = city.map((r: any) => safeNum(r.view007));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view008));
|
||||
cityOption = {
|
||||
title: { text: '郊县锅炉房供/回水压力', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: 'Pa' },
|
||||
series: [
|
||||
{ name: '供水压力', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水压力', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await cqglfgswd();
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container2 {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<div style="background-color: #fff;padding:14px;height: 100%;">
|
||||
<a-row :span="24" style="margin-top:10px;">
|
||||
<a-col :span="4" style="padding-left: 30px;">
|
||||
<a-select ref="select"
|
||||
placeholder="选择锅炉房"
|
||||
v-model:value="queryParam.sourceId"
|
||||
style="width: 155px;"
|
||||
@focus="focus"
|
||||
@change="handleChange">
|
||||
<a-select-option :value="item.sourceId" v-for="item in heatsource" :key="item.id">{{item.sourceName}}</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-date-picker v-model:value="queryParam.startDate" value-format="YYYY-MM" picker="month" placeholder="请选择时间" @change="handleChange" />
|
||||
</a-col>
|
||||
<a-col :span="24" >
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
import { heatsourcelist } from "@/views/base/simconfig/Simconfig.api";
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
const queryParam = ref<any>({});
|
||||
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
const heatsource = ref();
|
||||
async function getHeatsource(){
|
||||
heatsource.value = await heatsourcelist({regionType: '郊县'});
|
||||
}
|
||||
|
||||
async function handleChange(){
|
||||
loadData();
|
||||
}
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('郊县'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
const { city } = splitByRegion(records);
|
||||
|
||||
const cityX = buildXAxis(city, 'datatime');
|
||||
const citySW = city.map((r: any) => safeNum(r.view007));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view008));
|
||||
cityOption = {
|
||||
title: { text: '郊县锅炉房历史供/回水压力', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: 'Pa' },
|
||||
series: [
|
||||
{ name: '供水压力', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水压力', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
console.log("🚀 ~ loadData ~ queryParam.value:", queryParam.value)
|
||||
queryParam.value.startTime = dayjs(queryParam.value.startDate).format('YYMM');
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await getStaticList(queryParam.value);
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted( async () => {
|
||||
await getHeatsource()
|
||||
var list = heatsource.value
|
||||
queryParam.value.sourceId = list[0].sourceId
|
||||
queryParam.value.startDate = dayjs().format('YYYY-MM');
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.bjclass {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
export interface GrowCardItem {
|
||||
icon: string;
|
||||
title: string;
|
||||
value?: number;
|
||||
total: number;
|
||||
color?: string;
|
||||
action?: string;
|
||||
footer?: string;
|
||||
}
|
||||
|
||||
export const growCardList: GrowCardItem[] = [
|
||||
{
|
||||
title: '访问数',
|
||||
icon: 'visit-count|svg',
|
||||
value: 2000,
|
||||
total: 120000,
|
||||
color: 'green',
|
||||
action: '月',
|
||||
},
|
||||
{
|
||||
title: '成交额',
|
||||
icon: 'total-sales|svg',
|
||||
value: 20000,
|
||||
total: 500000,
|
||||
color: 'blue',
|
||||
action: '月',
|
||||
},
|
||||
{
|
||||
title: '下载数',
|
||||
icon: 'download-count|svg',
|
||||
value: 8000,
|
||||
total: 120000,
|
||||
color: 'orange',
|
||||
action: '周',
|
||||
},
|
||||
{
|
||||
title: '成交数',
|
||||
icon: 'transaction|svg',
|
||||
value: 5000,
|
||||
total: 50000,
|
||||
color: 'purple',
|
||||
action: '年',
|
||||
},
|
||||
];
|
||||
|
||||
export const chartCardList: GrowCardItem[] = [
|
||||
{
|
||||
title: '总销售额',
|
||||
icon: 'visit-count|svg',
|
||||
total: 126560,
|
||||
value: 234.56,
|
||||
footer: '日均销售额',
|
||||
},
|
||||
{
|
||||
title: '订单量',
|
||||
icon: 'total-sales|svg',
|
||||
value: 1234,
|
||||
total: 8846,
|
||||
color: 'blue',
|
||||
footer: '日订单量',
|
||||
},
|
||||
{
|
||||
title: '支付笔数',
|
||||
icon: 'download-count|svg',
|
||||
value: 60,
|
||||
total: 6560,
|
||||
color: 'orange',
|
||||
footer: '转化率',
|
||||
},
|
||||
{
|
||||
title: '运营活动效果',
|
||||
icon: 'transaction|svg',
|
||||
total: 78,
|
||||
},
|
||||
];
|
||||
export const bdcCardList: GrowCardItem[] = [
|
||||
{
|
||||
title: '受理量',
|
||||
icon: 'ant-design:info-circle-outlined',
|
||||
total: 100,
|
||||
value: 60,
|
||||
footer: '今日受理量',
|
||||
},
|
||||
{
|
||||
title: '办结量',
|
||||
icon: 'ant-design:info-circle-outlined',
|
||||
value: 54,
|
||||
total: 87,
|
||||
color: 'blue',
|
||||
footer: '今日办结量',
|
||||
},
|
||||
{
|
||||
title: '用户受理量',
|
||||
icon: 'ant-design:info-circle-outlined',
|
||||
value: 13,
|
||||
total: 15,
|
||||
color: 'orange',
|
||||
footer: '用户今日受理量',
|
||||
},
|
||||
{
|
||||
title: '用户办结量',
|
||||
icon: 'ant-design:info-circle-outlined',
|
||||
total: 9,
|
||||
value: 7,
|
||||
footer: '用户今日办结量',
|
||||
},
|
||||
];
|
||||
|
||||
export const table = {
|
||||
dataSource: [
|
||||
{ reBizCode: '1', type: '转移登记', acceptBy: '张三', acceptDate: '2019-01-22', curNode: '任务分派', flowRate: 60 },
|
||||
{ reBizCode: '2', type: '抵押登记', acceptBy: '李四', acceptDate: '2019-01-23', curNode: '领导审核', flowRate: 30 },
|
||||
{ reBizCode: '3', type: '转移登记', acceptBy: '王武', acceptDate: '2019-01-25', curNode: '任务处理', flowRate: 20 },
|
||||
{ reBizCode: '4', type: '转移登记', acceptBy: '赵楼', acceptDate: '2019-11-22', curNode: '部门审核', flowRate: 80 },
|
||||
{ reBizCode: '5', type: '转移登记', acceptBy: '钱就', acceptDate: '2019-12-12', curNode: '任务分派', flowRate: 90 },
|
||||
{ reBizCode: '6', type: '转移登记', acceptBy: '孙吧', acceptDate: '2019-03-06', curNode: '任务处理', flowRate: 10 },
|
||||
{ reBizCode: '7', type: '抵押登记', acceptBy: '周大', acceptDate: '2019-04-13', curNode: '任务分派', flowRate: 100 },
|
||||
{ reBizCode: '8', type: '抵押登记', acceptBy: '吴二', acceptDate: '2019-05-09', curNode: '任务上报', flowRate: 50 },
|
||||
{ reBizCode: '9', type: '抵押登记', acceptBy: '郑爽', acceptDate: '2019-07-12', curNode: '任务处理', flowRate: 63 },
|
||||
{ reBizCode: '20', type: '抵押登记', acceptBy: '林有', acceptDate: '2019-12-12', curNode: '任务打回', flowRate: 59 },
|
||||
{ reBizCode: '11', type: '转移登记', acceptBy: '码云', acceptDate: '2019-09-10', curNode: '任务签收', flowRate: 87 },
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
title: '业务号',
|
||||
align: 'center',
|
||||
dataIndex: 'reBizCode',
|
||||
},
|
||||
{
|
||||
title: '业务类型',
|
||||
align: 'center',
|
||||
dataIndex: 'type',
|
||||
},
|
||||
{
|
||||
title: '受理人',
|
||||
align: 'center',
|
||||
dataIndex: 'acceptBy',
|
||||
},
|
||||
{
|
||||
title: '受理时间',
|
||||
align: 'center',
|
||||
dataIndex: 'acceptDate',
|
||||
},
|
||||
{
|
||||
title: '当前节点',
|
||||
align: 'center',
|
||||
dataIndex: 'curNode',
|
||||
},
|
||||
{
|
||||
title: '办理时长',
|
||||
align: 'center',
|
||||
dataIndex: 'flowRate',
|
||||
},
|
||||
],
|
||||
ipagination: {
|
||||
current: 1,
|
||||
pageSize: 5,
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + '-' + range[1] + ' 共' + total + '条';
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0,
|
||||
},
|
||||
};
|
||||
export const table1 = {
|
||||
dataSource: [
|
||||
{ reBizCode: 'A001', type: '转移登记', acceptBy: '张四', acceptDate: '2019-01-22', curNode: '任务分派', flowRate: 12 },
|
||||
{ reBizCode: 'A002', type: '抵押登记', acceptBy: '李吧', acceptDate: '2019-01-23', curNode: '任务签收', flowRate: 3 },
|
||||
{ reBizCode: 'A003', type: '转移登记', acceptBy: '王三', acceptDate: '2019-01-25', curNode: '任务处理', flowRate: 24 },
|
||||
{ reBizCode: 'A004', type: '转移登记', acceptBy: '赵二', acceptDate: '2019-11-22', curNode: '部门审核', flowRate: 10 },
|
||||
{ reBizCode: 'A005', type: '转移登记', acceptBy: '钱大', acceptDate: '2019-12-12', curNode: '任务签收', flowRate: 8 },
|
||||
{ reBizCode: 'A006', type: '转移登记', acceptBy: '孙就', acceptDate: '2019-03-06', curNode: '任务处理', flowRate: 10 },
|
||||
{ reBizCode: 'A007', type: '抵押登记', acceptBy: '周晕', acceptDate: '2019-04-13', curNode: '部门审核', flowRate: 24 },
|
||||
{ reBizCode: 'A008', type: '抵押登记', acceptBy: '吴有', acceptDate: '2019-05-09', curNode: '部门审核', flowRate: 30 },
|
||||
{ reBizCode: 'A009', type: '抵押登记', acceptBy: '郑武', acceptDate: '2019-07-12', curNode: '任务分派', flowRate: 1 },
|
||||
{ reBizCode: 'A0010', type: '抵押登记', acceptBy: '林爽', acceptDate: '2019-12-12', curNode: '部门审核', flowRate: 16 },
|
||||
{ reBizCode: 'A0011', type: '转移登记', acceptBy: '码楼', acceptDate: '2019-09-10', curNode: '部门审核', flowRate: 7 },
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
title: '业务号',
|
||||
align: 'center',
|
||||
dataIndex: 'reBizCode',
|
||||
},
|
||||
{
|
||||
title: '受理人',
|
||||
align: 'center',
|
||||
dataIndex: 'acceptBy',
|
||||
},
|
||||
{
|
||||
title: '发起时间',
|
||||
align: 'center',
|
||||
dataIndex: 'acceptDate',
|
||||
},
|
||||
{
|
||||
title: '当前节点',
|
||||
align: 'center',
|
||||
dataIndex: 'curNode',
|
||||
},
|
||||
{
|
||||
title: '超时时间',
|
||||
align: 'center',
|
||||
dataIndex: 'flowRate',
|
||||
},
|
||||
],
|
||||
ipagination: {
|
||||
current: 1,
|
||||
pageSize: 5,
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + '-' + range[1] + ' 共' + total + '条';
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0,
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<div class="container">
|
||||
<div ref="cityChartRef" style="width: 100%; height: 600px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, nextTick, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { cqglfgswd,getStaticList } from '/@/api/dashboard/api';
|
||||
|
||||
/* ---- dom refs ---- */
|
||||
const cityChartRef = ref<HTMLElement | null>(null);
|
||||
/* ---- echarts instances & options ---- */
|
||||
let cityChart: echarts.ECharts | null = null;
|
||||
let cityOption: any = null;
|
||||
/* ---- helpers ---- */
|
||||
function safeNum(v: any) {
|
||||
if (v === null || v === undefined || v === '') return null;
|
||||
const n = Number(v);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
function sortByTime(arr: any[]) {
|
||||
return [...arr].sort((a, b) => {
|
||||
const ta = new Date(a.datatime || a.view032 || '').getTime();
|
||||
const tb = new Date(b.datatime || b.view032 || '').getTime();
|
||||
return (isNaN(ta) ? 0 : ta) - (isNaN(tb) ? 0 : tb);
|
||||
});
|
||||
}
|
||||
|
||||
function splitByRegion(data: any[]) {
|
||||
const city = data.filter(d => String(d.regionType).includes('城区'));
|
||||
return { city: sortByTime(city) };
|
||||
}
|
||||
function buildXAxis(records: any[], key = 'view028') {
|
||||
return records.map((r: any) => {
|
||||
return ((r[key] ?? '').toString().replace(/锅炉房/g, '')).trim();
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- build options(折线改为直线 smooth: false) ---- */
|
||||
function prepareOptions(records: any[]) {
|
||||
console.log("🚀 ~ prepareOptions ~ records:", records)
|
||||
const { city } = splitByRegion(records);
|
||||
console.log("🚀 ~ prepareOptions ~ city:", city)
|
||||
|
||||
const cityX = buildXAxis(city, 'view028');
|
||||
console.log("🚀 ~ prepareOptions ~ cityX:", cityX)
|
||||
const citySW = city.map((r: any) => safeNum(r.view005));
|
||||
const cityHW = city.map((r: any) => safeNum(r.view006));
|
||||
cityOption = {
|
||||
title: { text: '锅炉房供/回水温度', left: 'center', top: 10 },
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { top: 36, left: 'center' },
|
||||
grid: { left: '6%', right: '4%', bottom: 70, top: 70, containLabel: true },
|
||||
xAxis: { type: 'category', data: cityX, axisLabel: { rotate: 20 } },
|
||||
yAxis: { type: 'value', name: '℃' },
|
||||
series: [
|
||||
{ name: '供水温度', type: 'line', data: citySW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } },
|
||||
{ name: '回水温度', type: 'line', data: cityHW, smooth: false, showSymbol: false, lineStyle: { type: 'solid' } }
|
||||
],
|
||||
color: ['#176AB3', '#2F9E8A'] // 更稳重的直线配色
|
||||
};
|
||||
}
|
||||
|
||||
/* ---- lazy init & resize ---- */
|
||||
let resizeAdded = false;
|
||||
function ensureResize() {
|
||||
if (resizeAdded) return;
|
||||
const onResize = () => {
|
||||
cityChart?.resize();
|
||||
};
|
||||
window.addEventListener('resize', onResize);
|
||||
onUnmounted(() => window.removeEventListener('resize', onResize));
|
||||
resizeAdded = true;
|
||||
}
|
||||
|
||||
/* ---- load data ---- */
|
||||
async function loadData() {
|
||||
try {
|
||||
// 1. 获取参数
|
||||
// 2. 获取图表数据
|
||||
const r = await cqglfgswd();
|
||||
const records = r?.data ?? [];
|
||||
prepareOptions(records);
|
||||
|
||||
// 3. 等 DOM 更新完
|
||||
await nextTick();
|
||||
cityChart = echarts.init(cityChartRef.value);
|
||||
cityChart?.setOption(cityOption, true);
|
||||
|
||||
// 5. 窗口自适应
|
||||
ensureResize();
|
||||
} catch (err) {
|
||||
console.error('load error', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
height: calc(100vh - 120px); /* 需要设置容器高度 */
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue