Commit 2c6f846b authored by xinzhedeai's avatar xinzhedeai

add:浸润线绘制接口数据对接 处理

parent 30508fd6
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="new-container" style="display: flex">
<div class="canvas-wrapper" style="width: 1000px;">
<!-- 替换为 Canvas 元素 -->
<canvas
ref="canvas"
id="mainCanvas"
width="1000"
style="background: #f0f0f0"
></canvas>
</div>
<div class="chart-wrapper" style="padding-left: 0px;">
<div
ref="chartContainer"
style="width: 870px; height: 550px; margin-bottom: 20px;border:1px solid gainsboro;"
></div>
<div class="chart-btn-group">
<button
size="small"
:type="currentChartType === 'line' ? 'primary' : ''"
@click="switchChartType('line')"
>
折线图
</button>
<button
size="small"
:type="currentChartType === 'column' ? 'primary' : ''"
@click="switchChartType('column')"
>
柱状图
</button>
</div>
</div>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button
v-for="(item, key) in form.config.otherBtn"
size="mini"
:type="item.type"
:icon="item.icon"
@click="item.callback.call(_self, $event)"
>{{ item.name }}</el-button
>
</div>
<div>
<el-button
v-for="(item, key) in form.config.rightBtn"
size="mini"
:type="item.type"
:icon="item.icon"
@click="item.callback.call(_self, $event)"
>{{ item.name }}</el-button
>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import Highcharts from "highcharts";
import { reqApi, Config } from "@/assets/js/httpApi.js";
import { Tools } from "@/assets/js/common.js";
import DateRangePicker from "@/components/DateRangePicker";
import TableFilter from "@/components/TableFilter";
import cuForm from "@/components/cuForm";
import cuTable from "@/components/cuTable";
import request from "@/utils/request";
export default {
name: "Dashboard",
components: {
DateRangePicker,
TableFilter,
cuForm,
cuTable
},
data() {
return {
Dict: { selectList: [] },
table: {
page: 1,
size: 10,
total: 0,
loading: false,
dataList: []
},
rules: {},
form: {
title: "",
visible: false,
reqType: "add",
historyDialog: false,
status: { cu: 0 },
query: {},
search: {},
item: {},
file: 0,
config: {}
},
// 新增图表相关数据
chartVisible: true, // 图表弹窗可见性
deviceList: [{ id: "test001", name: "测试设备1" }], // 设备列表数据
selectedDevice: null, // 选中设备ID
dateRange: [null, null], // 日期范围选择
currentChartType: "line", // 当前图表类型(line/column)
chartLoading: false, // 图表加载状态
chartInstance: null, // Highcharts实例引用
// ...原有data属性保持不变...
canvas: null, // Canvas 实例
ctx: null, // 2D 上下文
bgImage: null, // 背景图对象
waterImage: null, // 新增:water.png 图片对象
poImage: null, // 新增:po.png 图片对象
// Canvas绘制配置(支持批量扩展)
poConfigs: [
{ x: 0, y: null, width: 879, height: 150 }, // 第一张po.png配置
{ x: 0, y: null, width: 879 - 250, height: 150 } // 第二张po.png配置(宽度减少250px)
],
poConfigs: [
{ x: null, y: null, width: 6, height: 121, image: "guanImage" }, // 第一张guan0.png
{ x: null, y: null, width: 6, height: 200, image: "guanImage" } // 第二张guan0.png(高度调整)
],
lineConfigs: [
{ points: [], color: "red", lineWidth: 2 }, // 红色连接线配置
{ points: [], color: "yellow", lineWidth: 2 } // 黄色连接线配置
],
canvasDataReal: [],
// canvasData: [
// {
// name: "剖面名称",
// height: "剖面高度",
// width: "剖面宽度",
// code: "剖面编号",
// sdeg: "水区扇形起始角度",
// diameter: "总直径",
// jrxStepsDtoList: [
// {
// name: "台阶名称",
// code: "台阶编号",
// height: "高度(米)",
// width: "宽度(米)",
// slope: "坡度(deg)"
// }
// ],
// equipmentDataList: [
// {
// sensorid: "设备id",
// sensorname: "设备名称",
// unit: "设备单位",
// stage: "水位(传感器到水面的距离)",
// depth: "浸润线埋深(水位到管口的距离)(m)",
// smhb: "// 水面海拔",
// time: "时间",
// holeDepth: "孔口高程",
// jrxTrepanning: "浸润线开口深度",
// redAlarm: "红色预警 此预警值针对的是depth 浸润线埋深",
// orangeAlarm: "橙色预警",
// yellowAlarm: "黄色预警",
// blueAlarm: "蓝色预警"
// }
// ]
// }
// ]
};
},
created() {
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || this.Dict.rules || {};
this.pageApi.created && this.pageApi.created();
// 新增:获取地址栏deviceId参数并设置到form.query.code
const deviceId = this.$route.query.deviceId;
if (deviceId) {
this.form.query.sensorid = deviceId; // 将deviceId赋值到查询条件的code字段
}
// this.handleCanvasData(this.canvasData);
},
mounted() {
// 新增:动态调整Canvas尺寸 目前支持7层。
const poCount = 4;
const lineCount = 5;
let canvasWidth = 1000; // 默认宽度
let canvasHeight = 600; // 默认高度
if (poCount > 4) {
canvasHeight = poCount * 150; // 高度 = 个数 × 150px
// canvasWidth = 1000 + (poCount - 4) * 150; // 宽度 = 原宽度 + (个数-4)×150px
}
// 更新Canvas元素属性和样式
const canvasEl = this.$refs.canvas;
if (canvasEl) {
// 实际绘图区域尺寸(关键属性)
canvasEl.width = canvasWidth;
canvasEl.height = canvasHeight;
// 显示尺寸(与绘图区域保持一致)
canvasEl.style.width = `${canvasWidth}px`;
canvasEl.style.height = `${canvasHeight}px`;
}
// // 数据清洗
// const po_pad_right = poCount > 4 ? 130 : 180; // 第一个台阶距离画布的距离
// const poH = 150;
// const line_color = ["red", "yellow", "green", "blue", "white"];
// this.poConfigs = [];
// this.guanConfigs = [];
// this.lineConfigs = [];
// for (let index = 0; index < poCount; index++) {
// // 坡数据数据格式处理
// this.poConfigs.push({
// x: 0,
// y: canvasHeight - (index + 1) * poH,
// width: canvasWidth - (index + 1) * po_pad_right,
// height: poH
// });
// // 管孔数据数据格式处理
// this.guanConfigs.push({
// x: this.poConfigs[index].width * 0.75,
// y: canvasHeight - this.poConfigs[index].height * (index + 1) + 30,
// width: 6,
// height: index == 0 ? 100 : 200,
// image: "guanImage"
// });
// }
// // 警戒线逻辑- 初始化4条线
// for (let index1 = 0; index1 < lineCount; index1++) {
// this.lineConfigs.push({
// // 设置
// points: [],
// color: line_color[index1],
// lineWidth: 2,
// cha: 20 * index1 // 每条线之间的差值
// });
// }
// // 警戒线种类下,根据管孔个数,设定对应的坐标点
// this.lineConfigs.forEach((line, index) => {
// // 几个管孔几个坐标点
// this.guanConfigs.forEach((guan, subindex) => {
// line.points.push({
// x: guan.x + 1,
// y: guan.y + 30 + line.cha
// });
// });
// });
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next) {
if (typeof value === "function") {
value.call(this.Dict).then(function(res) {
selectList[key] = res;
next();
});
} else {
next();
}
});
this.getCanvasData()
// 新增:在图表初始化的 $nextTick 后初始化 Canvas(确保 DOM 已渲染)
this.$nextTick(() => {
// 初始化 Canvas
// setTimeout(() => {
// this.initCanvas();
// }, 1000);
});
},
methods: {
getCanvasData(){
const params = {}
request({
url: "tab/jrx/dissect/visual-xinHua",
method: "get",
params
}).then(res => {
const data = res.body;
console.log('接口数据', data)
this.handleCanvasData(data)
this.initCanvas()
})
},
handleCanvasData(list = []) {
// 新增:动态调整Canvas尺寸 目前支持7层。
const poCount = list[0].jrxStepsDtoList.length;
const lineCount = 5;
let canvasWidth = 1000; // 默认宽度
let canvasHeight = 600; // 默认高度
if (poCount > 4) {
canvasHeight = poCount * 150; // 高度 = 个数 × 150px
// canvasWidth = 1000 + (poCount - 4) * 150; // 宽度 = 原宽度 + (个数-4)×150px
}
// 更新Canvas元素属性和样式
const canvasEl = this.$refs.canvas;
if (canvasEl) {
// 实际绘图区域尺寸(关键属性)
canvasEl.width = canvasWidth;
canvasEl.height = canvasHeight;
// 显示尺寸(与绘图区域保持一致)
canvasEl.style.width = `${canvasWidth}px`;
canvasEl.style.height = `${canvasHeight}px`;
}
// 数据清洗
const po_pad_right = poCount > 4 ? 130 : 180; // 第一个台阶距离画布的距离
const poH = 150;
const line_color = ["red", "yellow", "green", "blue", "white"];
this.canvasData.poConfigs = [];
this.canvasData.guanConfigs = [];
this.canvasData.lineConfigs = [];
for (let index = 0; index < poCount; index++) {
// 坡数据数据格式处理
this.poConfigs.push({
x: 0,
y: canvasHeight - (index + 1) * poH,
width: canvasWidth - (index + 1) * po_pad_right,
height: poH
});
// 管孔数据数据格式处理
this.guanConfigs.push({
x: this.poConfigs[index].width * 0.75,
y: canvasHeight - this.poConfigs[index].height * (index + 1) + 30,
width: 6,
height: index == 0 ? 100 : 200,
image: "guanImage"
});
}
// 警戒线逻辑- 初始化4条线
for (let index1 = 0; index1 < lineCount; index1++) {
this.lineConfigs.push({
// 设置
points: [],
color: line_color[index1],
lineWidth: 2,
cha: 20 * index1 // 每条线之间的差值
});
}
// 警戒线种类下,根据管孔个数,设定对应的坐标点
this.lineConfigs.forEach((line, index) => {
// 几个管孔几个坐标点
this.guanConfigs.forEach((guan, subindex) => {
line.points.push({
x: guan.x + 1,
y: guan.y + 30 + line.cha
});
});
});
},
// 处理canvas数据
handleCanvasData1(list = []) {
const canvasData = { poConfigs: [], guanConfigs: [], lineConfigs: [] };
canvasData.lineConfigs = [
{ points: [], color: "red", lineWidth: 2 }, // 红色连接线配置
{ points: [], color: "yellow", lineWidth: 2 }, // 黄色连接线配置
{ points: [], color: "green", lineWidth: 2 }, // 绿色连接线配置
{ points: [], color: "blue", lineWidth: 2 }, // 蓝色连接线配置
{ points: [], color: "white", lineWidth: 2 } // 实际连接线配置
];
const tjNumber = list[0].jrxStepsDtoList.length;
//第一层台阶的开孔深度和设备图片相除的系数
const sbHeightModulus = list[0].equipmentDataList[0].jrxTrepanning / 130;
for (let index = 0; index < tjNumber; index++) {
canvasData.poConfigs.push({
x: 0,
y: 600- (150 * index),
width: 879 - 250 * index,
height: 150
});
canvasData.guanConfigs.push({
x: 820 - 250 * index,
y: 600 - 150 * index,
width: 6,
height:
list[0].equipmentDataList[index].jrxTrepanning * sbHeightModulus,
image: "guanImage"
});
// 向红色连接线配置push数据
canvasData.lineConfigs[0].points.push({
x: 820 - 250 * index, // x坐标
y:
600 -
150 * index +
list[0].equipmentDataList[index].redAlarm * sbHeightModulus // y坐标
});
// 向黄色连接线配置push数据
canvasData.lineConfigs[1].points.push({
x: 820 - 250 * index, // x坐标
y:
600 -
150 * index +
list[0].equipmentDataList[index].orangeAlarm * sbHeightModulus // y坐标
});
// 向绿色连接线配置push数据
canvasData.lineConfigs[2].points.push({
x: 820 - 250 * index, // x坐标
y:
600 -
150 * index +
list[0].equipmentDataList[index].yellowAlarm * sbHeightModulus // y坐标
});
// 向蓝色连接线配置push数据
canvasData.lineConfigs[3].points.push({
x: 820 - 250 * index, // x坐标
y:
600 -
150 * index +
list[0].equipmentDataList[index].blueAlarm * sbHeightModulus // y坐标
});
// 向实际连接线配置push数据
canvasData.lineConfigs[4].points.push({
x: 820 - 250 * index, // x坐标
y:
600 -
150 * index +
list[0].equipmentDataList[index].depth * sbHeightModulus // y坐标
});
}
console.log('加工后的数据结构', canvasData)
this.canvasDataReal = canvasData
},
/** 初始化 Canvas 画布及坐标系 */
initCanvas() {
// 获取 Canvas 元素和上下文
this.canvas = this.$refs.canvas; // document.getElementById('mainCanvas')
if (!this.canvas) {
console.error("Canvas 元素未找到");
return;
}
console.log(this.canvas, "canvas");
this.ctx = this.canvas.getContext("2d");
// 坐标系变换:将原点移至左下角(默认原点在左上角)
this.ctx.translate(0, this.canvas.height); // 向下移动画布高度
this.ctx.scale(1, -1); // 翻转 Y 轴方向(上为正)
// // 加载背景图并绘制
// this.loadBackgroundImage();
// 加载所有图片并绘制
this.loadAllImages();
},
// 绘制单个po.png(支持配置参数)
drawPoImage(config) {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// 动态计算y坐标(若未指定则默认画布底部-高度)
this.ctx.drawImage(
this.poImage,
config.x,
config.y,
config.width,
config.height
);
this.ctx.restore();
},
// 绘制单个guan.png(支持不同图片类型)
drawGuanImage(config) {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
const targetImage = this[config.image]; // 根据配置获取具体图片对象(如guanImage/guanImage1)
this.ctx.drawImage(
targetImage,
config.x,
config.y,
config.width,
config.height
);
this.ctx.restore();
},
// 绘制连接线(支持多坐标点)
drawLine(config) {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.strokeStyle = config.color;
this.ctx.lineWidth = config.lineWidth;
this.ctx.beginPath();
config.points.forEach((point, index) => {
index === 0
? this.ctx.moveTo(point.x, point.y)
: this.ctx.lineTo(point.x, point.y);
});
this.ctx.stroke();
this.ctx.restore();
},
// 绘制背景图(独立方法)
drawBackground() {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.drawImage(
this.bgImage,
0,
0,
this.canvas.width,
this.canvas.height
);
this.ctx.restore();
},
// 绘制water.png(独立方法)
drawWaterImage() {
this.ctx.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.drawImage(
this.waterImage,
0,
this.canvas.height - 255,
485,
255
);
this.ctx.restore();
},
// 重构后的统一绘制入口(通过配置驱动)
drawAllImages() {
// 1. 绘制背景图
this.drawBackground();
// 2. 绘制po.png(遍历配置数组)
console.log(this.canvasDataReal.poConfigs, "poConfigs");
this.canvasDataReal.poConfigs.forEach((config, index) => {
this.drawPoImage(config);
});
// 3. 绘制guan.png(遍历配置数组)
console.log(this.canvasDataReal.guanConfigs, "guanConfigs");
this.canvasDataReal.guanConfigs.forEach((config, index) => {
this.drawGuanImage(config);
});
// 4. 绘制连接线(遍历配置数组)
this.canvasDataReal.lineConfigs.forEach((config, index) => {
this.drawLine(config);
});
// 5. 绘制water.png
this.drawWaterImage();
},
/** 加载所有图片并绘制 */
loadAllImages() {
// 加载背景图(原有)
this.bgImage = new Image();
this.bgImage.src = require("@/assets/images/jrx/bg.png");
// 加载 water.png
this.waterImage = new Image();
this.waterImage.src = require("@/assets/images/jrx/water.png");
// 加载 po.png
this.poImage = new Image();
this.poImage.src = require("@/assets/images/jrx/po.png");
// 加载 guan.png
this.guanImage = new Image();
this.guanImage.src = require("@/assets/images/jrx/guan0.png");
// 等待所有图片加载完成
Promise.all([
new Promise(resolve => (this.bgImage.onload = resolve)),
new Promise(resolve => (this.waterImage.onload = resolve)),
new Promise(resolve => (this.poImage.onload = resolve)),
new Promise(resolve => (this.guanImage.onload = resolve))
])
.then(() => {
// 所有图片加载完成后绘制
this.drawAllImages();
})
.catch(() => {
console.error("部分图片加载失败");
});
},
/** 初始化图表(关键修改:调整图例位置) */
initChart1() {
let params = {
sort: "date,desc"
};
if (this.form.query.daterange) {
params.daterange = this.form.query.daterange.join(",");
}
if (this.form.query.sensorid) {
params.code = this.form.query.sensorid;
}
request({
url: "data/st/imghistory",
method: "get",
params
}).then(res => {
const data = res.body;
// const data = this.getChartData().body
console.log("data", data);
const chartData = this.seriesDataFormat(data, { datekey: "date" });
var warningLine = undefined; // this.form.config.warningLine;
var option = {
valEnabled: true,
opacity: 1,
lineWidth: 3
};
var alarmData = this.discernValidAlarmValue(
data.alarm,
data.lists,
chartData.series,
warningLine,
option
);
// const chartData = data
console.log("chartCData", chartData);
Highcharts.setOptions({
global: {
useUTC: false
},
lang: {
resetZoom: "重置缩放比例"
}
});
this.chartInstance = new Highcharts.chart(this.$refs.chartContainer, {
chart: {
//type: '',
backgroundColor: "transparent",
//marginTop:30,
//marginBottom:30,
//marginLeft:30,
zoomType: "x" // xy
},
valEnabled: true,
opacity: 1,
lineWidth: 3,
title: {
text: ""
},
subtitle: {
text: ""
},
tooltip: {
enabled: false,
borderWidth: 10
},
xAxis: {
type: "datetime",
// 最为关键的代码:如果为空数组,则导致日期格式化失效!!
categories: chartData.categories[0] && chartData.categories,
lineWidth: 0,
//lineColor:'#ff0000',
gridLineColor: "#aaa",
dateTimeLabelFormats: {
millisecond: "%H:%M:%S.%L",
second: "%H:%M:%S",
minute: "%H:%M",
hour: "%H:%M",
day: "%m-%d",
week: "%m-%d",
month: "%Y-%m",
year: "%Y"
}
},
yAxis: {
title: {
text: ""
},
labels: {
x: -6
},
gridLineColor: "#aaa",
max: null
},
plotOptions: {
column: {
borderWidth: 0
//y:50,
//itemMarginTop:50,
},
bar: {
borderWidth: 0
}
},
tooltip: {
// {point.y:.4f} // 保留4位小数
//headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormat:
'<tr><td style="color:{series.color};padding:0">{series.name}:</td>' +
'<td style="padding:0"><b>{point.y}' +
data.danwei +
"</b> </td></tr>",
footerFormat: "</table>",
shared: true,
useHTML: true,
dateTimeLabelFormats: {
millisecond: "%H:%M:%S.%L",
second: "%H:%M:%S",
minute: "%H:%M",
hour: "%H:%M",
day: "%m-%d %H时",
week: "%m-%d",
month: "%Y-%m",
year: "%Y"
}
},
legend: {
enabled: chartData.series.length > 1 ? true : false,
// 图例定位
layout: "horizontal", // 水平布局:“horizontal”, 垂直布局:“vertical”
floating: false, // 图列是否浮动
align: "right",
// 图例容器
//width:'100%', // number || String
padding: 2, // 内边距
margin: 2,
borderRadius: 5,
//borderWidth:1,
verticalAlign: "top",
// 图例项
//itemWidth:120, // 宽度
itemDistance: 10, // 间距 20
y: -10,
itemMarginTop: 2,
itemStyle: {},
itemHoverStyle: {}
},
credits: {
enabled: false
},
series: chartData.series
});
});
},
seriesDataFormat(data, opts) {
var names = data.names || [],
list = data.list || data.lists,
series = [],
categories = [],
maxVal = 0;
if (names[0] && list) {
var colors = [
"#7CB5EC",
"#90ED7D",
"#F7A35C",
"#8085E9",
"#F15C80",
"#E4D354",
"#2B908F",
"#F45B5B",
"#91E8E1",
"#0769CB",
"#00ABBD",
"#ffd886",
"#9F2E61",
"#4D670C"
];
var len = names.length;
for (var i = 0; i < len; i++) {
var item = names[i];
var serie = {
name: item.name,
data: [],
key: item.key,
type: data.chartType,
color: colors[i]
};
opts && serie.type && (serie.type = opts.type);
series.push(serie);
}
for (var item of list) {
var values = item.values;
//var datetime = item[opts.datekey || 'dateUnit'];
//var time = datetime.indexOf(' ') > 0 ? datetime.split(' ')[1] : datetime;
var timestamp = item["date"];
//categories.push(timestamp);
for (var serie of series) {
var value = values[serie.key] * 1;
Math.abs(value) > maxVal && (maxVal = Math.abs(value));
serie.data.push([timestamp, value]);
}
}
}
return { series: series, categories: categories, maxVal: maxVal };
},
discernValidAlarmValue(alarms, list, series, direction, opts) {
var xLength = (list || []).length,
maxAlarm = 0,
opts = opts || {};
if (alarms && xLength) {
var value = alarms.value;
// discern
var levelDist = [
{ color: "red", name: "红色报警线" },
{ color: "orange", name: "橙色报警线" },
{ color: "yellow", name: "黄色报警线" },
{ color: "blue", name: "蓝色报警线" }
],
alarmLine = {},
setAlarmSerie = function(value, name, color) {
// 修改蓝色色值
color === "blue" && (color = "#3BAFFB");
var sx = list[0].date,
ex = list[xLength - 1].date;
var serie = {
name: name,
type: "spline",
data: [{ x: sx, y: value }, { x: ex, y: value }],
color: color,
enableMouseTracking: false,
legend: false,
showInLegend: false,
dashStyle: "ShortDot",
lineWidth: opts.lineWidth || 1,
states: {
inactive: {
opacity: opts.opacity
}
},
dataLabels: {
enabled: opts.valEnabled || false, // 数据值, 2022/11/11(周五) 因多条报警线暂时关闭
//backgroundColor:'red',
verticalAlign: "middle",
padding: 0,
defer: false,
allowOverlap: true,
color: color,
style: {
textOutline: "none"
}
},
tooltip: {
//footerFormat:'',
//pointFormat:'',
headerFormat: ""
//nullFormat:'',
},
marker: {
enabled: false
},
zIndex: -10
};
series.push(serie);
};
/* 智能报警线
var level = (~~alarms.alarmLevel || levelDist.length+1) - 1;
var nearLevel = level ? level - 1 : level;
var alarm = levelDist[level];
var nearAlarm = levelDist[nearLevel];
nearAlarm.value = value[nearAlarm.color];
alarmLine[nearAlarm.color] = nearAlarm;
if(alarm){
alarm.value = value[alarm.color];
alarmLine[alarm.color] = alarm;
}; */
// 多条报警线
for (var item of levelDist) {
item.value = value[item.color];
alarmLine[item.color] = item;
}
// add
for (var key in alarmLine) {
var line = alarmLine[key];
line.value > maxAlarm && (maxAlarm = line.value);
setAlarmSerie(line.value, line.name, line.color);
direction && setAlarmSerie(0 - line.value, line.name, line.color);
}
}
return { series, maxAlarm };
},
/** 切换图表类型 */
switchChartType(type) {
this.currentChartType = type;
if (this.chartInstance) {
this.chartInstance.series.forEach(series => {
series.update({ type: this.currentChartType });
});
}
},
loadData: function() {
console.log(this.form, "form");
this.initChart1();
return reqApi.common.getRequst;
},
cancelForm() {
this.form.visible = false;
},
submitForm(form, item) {
reqApi.common.submitForm.call(this, form, item);
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz {
}
</style>
......@@ -12,7 +12,7 @@
</div>
<div class="new-container" style="display: flex">
<div class="canvas-wrapper" style="width: 1000px;">
<div class="canvas-wrapper" style="width: 1000px">
<!-- 替换为 Canvas 元素 -->
<canvas
ref="canvas"
......@@ -21,10 +21,15 @@
style="background: #f0f0f0"
></canvas>
</div>
<div class="chart-wrapper" style="padding-left: 0px;">
<div class="chart-wrapper" style="padding-left: 0px">
<div
ref="chartContainer"
style="width: 870px; height: 550px; margin-bottom: 20px;border:1px solid gainsboro;"
style="
width: 870px;
height: 550px;
margin-bottom: 20px;
border: 1px solid gainsboro;
"
></div>
<div class="chart-btn-group">
<button
......@@ -113,7 +118,7 @@ export default {
DateRangePicker,
TableFilter,
cuForm,
cuTable
cuTable,
},
data() {
return {
......@@ -123,7 +128,7 @@ export default {
size: 10,
total: 0,
loading: false,
dataList: []
dataList: [],
},
rules: {},
form: {
......@@ -136,7 +141,7 @@ export default {
search: {},
item: {},
file: 0,
config: {}
config: {},
},
// 新增图表相关数据
chartVisible: true, // 图表弹窗可见性
......@@ -153,55 +158,58 @@ export default {
bgImage: null, // 背景图对象
waterImage: null, // 新增:water.png 图片对象
poImage: null, // 新增:po.png 图片对象
canvasDataReal: {
// Canvas绘制配置(支持批量扩展)
poConfigs: [
{ x: 0, y: null, width: 879, height: 150 }, // 第一张po.png配置
{ x: 0, y: null, width: 879 - 250, height: 150 } // 第二张po.png配置(宽度减少250px)
{ x: 0, y: null, width: 879 - 250, height: 150 }, // 第二张po.png配置(宽度减少250px)
],
poConfigs: [
{ x: null, y: null, width: 6, height: 121, image: "guanImage" }, // 第一张guan0.png
{ x: null, y: null, width: 6, height: 200, image: "guanImage" } // 第二张guan0.png(高度调整)
{ x: null, y: null, width: 6, height: 200, image: "guanImage" }, // 第二张guan0.png(高度调整)
],
lineConfigs: [
{ points: [], color: "red", lineWidth: 2 }, // 红色连接线配置
{ points: [], color: "yellow", lineWidth: 2 } // 黄色连接线配置
],
canvasData: [
{
name: "剖面名称",
height: "剖面高度",
width: "剖面宽度",
code: "剖面编号",
sdeg: "水区扇形起始角度",
diameter: "总直径",
jrxStepsDtoList: [
{
name: "台阶名称",
code: "台阶编号",
height: "高度(米)",
width: "宽度(米)",
slope: "坡度(deg)"
}
{ points: [], color: "yellow", lineWidth: 2 }, // 黄色连接线配置
],
equipmentDataList: [
{
sensorid: "设备id",
sensorname: "设备名称",
unit: "设备单位",
stage: "水位(传感器到水面的距离)",
depth: "浸润线埋深(水位到管口的距离)(m)",
smhb: "// 水面海拔",
time: "时间",
holeDepth: "孔口高程",
jrxTrepanning: "浸润线开口深度",
redAlarm: "红色预警 此预警值针对的是depth 浸润线埋深",
orangeAlarm: "橙色预警",
yellowAlarm: "黄色预警",
blueAlarm: "蓝色预警"
}
]
}
]
},
// canvasData: [
// {
// name: "剖面名称",
// height: "剖面高度",
// width: "剖面宽度",
// code: "剖面编号",
// sdeg: "水区扇形起始角度",
// diameter: "总直径",
// jrxStepsDtoList: [
// {
// name: "台阶名称",
// code: "台阶编号",
// height: "高度(米)",
// width: "宽度(米)",
// slope: "坡度(deg)"
// }
// ],
// equipmentDataList: [
// {
// sensorid: "设备id",
// sensorname: "设备名称",
// unit: "设备单位",
// stage: "水位(传感器到水面的距离)",
// depth: "浸润线埋深(水位到管口的距离)(m)",
// smhb: "// 水面海拔",
// time: "时间",
// holeDepth: "孔口高程",
// jrxTrepanning: "浸润线开口深度",
// redAlarm: "红色预警 此预警值针对的是depth 浸润线埋深",
// orangeAlarm: "橙色预警",
// yellowAlarm: "黄色预警",
// blueAlarm: "蓝色预警"
// }
// ]
// }
// ]
};
},
created() {
......@@ -217,7 +225,7 @@ export default {
if (deviceId) {
this.form.query.sensorid = deviceId; // 将deviceId赋值到查询条件的code字段
}
this.handleCanvasData(this.canvasData);
// this.handleCanvasData(this.canvasData);
},
mounted() {
// 新增:动态调整Canvas尺寸 目前支持7层。
......@@ -241,89 +249,185 @@ export default {
canvasEl.style.height = `${canvasHeight}px`;
}
// // 数据清洗
// const po_pad_right = poCount > 4 ? 130 : 180; // 第一个台阶距离画布的距离
// const poH = 150;
// const line_color = ["red", "yellow", "green", "blue", "white"];
// this.poConfigs = [];
// this.guanConfigs = [];
// this.lineConfigs = [];
// for (let index = 0; index < poCount; index++) {
// // 坡数据数据格式处理
// this.poConfigs.push({
// x: 0,
// y: canvasHeight - (index + 1) * poH,
// width: canvasWidth - (index + 1) * po_pad_right,
// height: poH
// });
// // 管孔数据数据格式处理
// this.guanConfigs.push({
// x: this.poConfigs[index].width * 0.75,
// y: canvasHeight - this.poConfigs[index].height * (index + 1) + 30,
// width: 6,
// height: index == 0 ? 100 : 200,
// image: "guanImage"
// });
// }
// // 警戒线逻辑- 初始化4条线
// for (let index1 = 0; index1 < lineCount; index1++) {
// this.lineConfigs.push({
// // 设置
// points: [],
// color: line_color[index1],
// lineWidth: 2,
// cha: 20 * index1 // 每条线之间的差值
// });
// }
// // 警戒线种类下,根据管孔个数,设定对应的坐标点
// this.lineConfigs.forEach((line, index) => {
// // 几个管孔几个坐标点
// this.guanConfigs.forEach((guan, subindex) => {
// line.points.push({
// x: guan.x + 1,
// y: guan.y + 30 + line.cha
// });
// });
// });
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function (key, value, next) {
if (typeof value === "function") {
value.call(this.Dict).then(function (res) {
selectList[key] = res;
next();
});
} else {
next();
}
});
this.getCanvasData();
// 新增:在图表初始化的 $nextTick 后初始化 Canvas(确保 DOM 已渲染)
this.$nextTick(() => {
// 初始化 Canvas
// setTimeout(() => {
// this.initCanvas();
// }, 1000);
});
},
methods: {
getCanvasData() {
const params = {};
request({
url: "tab/jrx/dissect/visual-xinHua",
method: "get",
params,
}).then((res) => {
const data = res.body;
console.log("接口数据", data);
this.handleCanvasData(data);
this.initCanvas();
});
},
handleCanvasData(list = []) {
// 新增:动态调整Canvas尺寸 目前支持7层。
const poumian = list[0];
const poCount = poumian.jrxStepsDtoList.length;
const lineCount = 5;
let canvasWidth = 1000; // 默认宽度
let canvasHeight = 600; // 默认高度
if (poCount > 4) {
canvasHeight = poCount * 150; // 高度 = 个数 × 150px
// canvasWidth = 1000 + (poCount - 4) * 150; // 宽度 = 原宽度 + (个数-4)×150px
}
// 更新Canvas元素属性和样式
const canvasEl = this.$refs.canvas;
if (canvasEl) {
// 实际绘图区域尺寸(关键属性)
canvasEl.width = canvasWidth;
canvasEl.height = canvasHeight;
// 显示尺寸(与绘图区域保持一致)
canvasEl.style.width = `${canvasWidth}px`;
canvasEl.style.height = `${canvasHeight}px`;
}
// 数据清洗
const po_pad_right = poCount > 4 ? 130 : 180; // 第一个台阶距离画布的距离
const po_pad_right = 180; // poCount > 4 ? 130 : 180; // 第一个台阶距离画布的距离
const poH = 150;
const line_color = ["red", "yellow", "green", "blue", "white"];
this.poConfigs = [];
this.guanConfigs = [];
this.lineConfigs = [];
const line_color = ["red", "orange", "yellow", "blue", "white"];
this.canvasDataReal.poConfigs = [];
this.canvasDataReal.guanConfigs = [];
this.canvasDataReal.lineConfigs = [];
//第一层台阶的开孔深度和设备图片相除的系数
const sbHeightModulus = poumian.equipmentDataList[0].jrxTrepanning // / 130;
for (let index = 0; index < poCount; index++) {
// 坡数据数据格式处理
this.poConfigs.push({
this.canvasDataReal.poConfigs.push({
x: 0,
y: canvasHeight - (index + 1) * poH,
width: canvasWidth - (index + 1) * po_pad_right,
height: poH
height: poH,
});
// 管孔数据数据格式处理
this.guanConfigs.push({
x: this.poConfigs[index].width * 0.75,
y: canvasHeight - this.poConfigs[index].height * (index + 1) + 30,
this.canvasDataReal.guanConfigs.push({
x: this.canvasDataReal.poConfigs[index].width * 0.75,
y: canvasHeight - this.canvasDataReal.poConfigs[index].height * (index + 1) + 30,
width: 6,
height: index == 0 ? 100 : 200,
image: "guanImage"
height:
poumian.equipmentDataList[index].jrxTrepanning * sbHeightModulus,
image: "guanImage",
});
}
// 警戒线逻辑- 初始化4条线
for (let index1 = 0; index1 < lineCount; index1++) {
this.lineConfigs.push({
this.canvasDataReal.lineConfigs.push({
// 设置
points: [],
color: line_color[index1],
lineWidth: 2,
cha: 20 * index1 // 每条线之间的差值
cha: 20 * index1, // 每条线之间的差值
});
}
// 警戒线种类下,根据管孔个数,设定对应的坐标点
this.lineConfigs.forEach((line, index) => {
this.canvasDataReal.lineConfigs.forEach((line, index) => {
let lineValKey = line.color == "white" ? "depth" : line.color + "Alarm";
// 几个管孔几个坐标点
this.guanConfigs.forEach((guan, subindex) => {
this.canvasDataReal.guanConfigs.forEach((guan, subindex) => {
line.points.push({
x: guan.x + 1,
y: guan.y + 30 + line.cha
x: guan.x+1,
y:
guan.y +
poumian.equipmentDataList[subindex][lineValKey] * sbHeightModulus,
});
});
});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next) {
if (typeof value === "function") {
value.call(this.Dict).then(function(res) {
selectList[key] = res;
next();
});
} else {
next();
}
});
console.log('this.canvasDataReal', this.canvasDataReal)
// 新增:在图表初始化的 $nextTick 后初始化 Canvas(确保 DOM 已渲染)
this.$nextTick(() => {
// 初始化 Canvas
setTimeout(() => {
this.initCanvas();
}, 1000);
});
},
methods: {
// 处理canvas数据
handleCanvasData(list = []) {
handleCanvasData1(list = []) {
const canvasData = { poConfigs: [], guanConfigs: [], lineConfigs: [] };
canvasData.lineConfigs = [
{ points: [], color: "red", lineWidth: 2 }, // 红色连接线配置
{ points: [], color: "yellow", lineWidth: 2 }, // 黄色连接线配置
{ points: [], color: "green", lineWidth: 2 }, // 绿色连接线配置
{ points: [], color: "blue", lineWidth: 2 }, // 蓝色连接线配置
{ points: [], color: "white", lineWidth: 2 } // 实际连接线配置
{ points: [], color: "white", lineWidth: 2 }, // 实际连接线配置
];
const tjNumber = list[0].jrxStepsDtoList.length;
//第一层台阶的开孔深度和设备图片相除的系数
......@@ -331,9 +435,9 @@ export default {
for (let index = 0; index < tjNumber; index++) {
canvasData.poConfigs.push({
x: 0,
y: 150 * index,
y: 600 - 150 * index,
width: 879 - 250 * index,
height: 150
height: 150,
});
canvasData.guanConfigs.push({
x: 820 - 250 * index,
......@@ -341,7 +445,7 @@ export default {
width: 6,
height:
list[0].equipmentDataList[index].jrxTrepanning * sbHeightModulus,
image: "guanImage"
image: "guanImage",
});
// 向红色连接线配置push数据
canvasData.lineConfigs[0].points.push({
......@@ -349,7 +453,7 @@ export default {
y:
600 -
150 * index +
list[0].equipmentDataList[index].redAlarm * sbHeightModulus // y坐标
list[0].equipmentDataList[index].redAlarm * sbHeightModulus, // y坐标
});
// 向黄色连接线配置push数据
canvasData.lineConfigs[1].points.push({
......@@ -357,7 +461,7 @@ export default {
y:
600 -
150 * index +
list[0].equipmentDataList[index].orangeAlarm * sbHeightModulus // y坐标
list[0].equipmentDataList[index].orangeAlarm * sbHeightModulus, // y坐标
});
// 向绿色连接线配置push数据
canvasData.lineConfigs[2].points.push({
......@@ -365,7 +469,7 @@ export default {
y:
600 -
150 * index +
list[0].equipmentDataList[index].yellowAlarm * sbHeightModulus // y坐标
list[0].equipmentDataList[index].yellowAlarm * sbHeightModulus, // y坐标
});
// 向蓝色连接线配置push数据
canvasData.lineConfigs[3].points.push({
......@@ -373,7 +477,7 @@ export default {
y:
600 -
150 * index +
list[0].equipmentDataList[index].blueAlarm * sbHeightModulus // y坐标
list[0].equipmentDataList[index].blueAlarm * sbHeightModulus, // y坐标
});
// 向实际连接线配置push数据
canvasData.lineConfigs[4].points.push({
......@@ -381,9 +485,11 @@ export default {
y:
600 -
150 * index +
list[0].equipmentDataList[index].depth * sbHeightModulus // y坐标
list[0].equipmentDataList[index].depth * sbHeightModulus, // y坐标
});
}
console.log("加工后的数据结构", canvasData);
this.canvasDataReal = canvasData;
},
/** 初始化 Canvas 画布及坐标系 */
initCanvas() {
......@@ -482,59 +588,23 @@ export default {
// 重构后的统一绘制入口(通过配置驱动)
drawAllImages() {
const canvasHeight = this.canvas.height;
// 1. 绘制背景图
this.drawBackground();
// 2. 绘制po.png(遍历配置数组)
console.log(this.poConfigs, "poConfigs");
this.poConfigs.forEach((config, index) => {
// // 第二张po.png的y坐标需要基于第一张计算(顶部对齐)
// if (index === 1) {
// const prevPo = this.poConfigs[0];
// config.y = (canvasHeight - prevPo.height) - config.height; // 第一张顶部位置 - 自身高度
// }
console.log(this.canvasDataReal.poConfigs, "poConfigs");
this.canvasDataReal.poConfigs.forEach((config, index) => {
this.drawPoImage(config);
});
// 3. 绘制guan.png(遍历配置数组)
console.log(this.guanConfigs, "guanConfigs");
this.guanConfigs.forEach((config, index) => {
// const firstPo = this.poConfigs[0];
// const secondPo = this.poConfigs[1];
// // 第一张guan.png坐标计算(基于第一张po.png)
// if (index === 0) {
// config.x = firstPo.width - 150; // 879 - 150
// config.y = canvasHeight - 135.5; // 原计算逻辑
// }
// // 第二张guan.png坐标计算(基于第二张po.png)
// if (index === 1) {
// config.x = secondPo.width - 150; // secondPoWidth - 150
// config.y = secondPo.y + 30; // secondPoY + 30
// }
console.log(this.canvasDataReal.guanConfigs, "guanConfigs");
this.canvasDataReal.guanConfigs.forEach((config, index) => {
this.drawGuanImage(config);
});
// 4. 绘制连接线(遍历配置数组)
this.lineConfigs.forEach((config, index) => {
// const firstGuan = this.guanConfigs[0];
// const secondGuan = this.guanConfigs[1];
// // 红色连接线坐标(原逻辑)
// if (index === 0) {
// config.points = [
// { x: firstGuan.x, y: firstGuan.y + 100 },
// { x: secondGuan.x, y: secondGuan.y + 50 },
// { x: secondGuan.x - 100, y: secondGuan.y - 10 } // 扩展第三点
// ];
// }
// // 黄色连接线坐标(原逻辑)
// if (index === 1) {
// config.points = [
// { x: firstGuan.x, y: firstGuan.y + 80 }, // 调整偏移量
// { x: secondGuan.x, y: secondGuan.y + 30 }
// ];
// }
this.canvasDataReal.lineConfigs.forEach((config, index) => {
this.drawLine(config);
});
......@@ -561,10 +631,10 @@ export default {
// 等待所有图片加载完成
Promise.all([
new Promise(resolve => (this.bgImage.onload = resolve)),
new Promise(resolve => (this.waterImage.onload = resolve)),
new Promise(resolve => (this.poImage.onload = resolve)),
new Promise(resolve => (this.guanImage.onload = resolve))
new Promise((resolve) => (this.bgImage.onload = resolve)),
new Promise((resolve) => (this.waterImage.onload = resolve)),
new Promise((resolve) => (this.poImage.onload = resolve)),
new Promise((resolve) => (this.guanImage.onload = resolve)),
])
.then(() => {
// 所有图片加载完成后绘制
......@@ -575,199 +645,10 @@ export default {
});
},
/** 绘制所有图片(背景图 + 新增图片) */
/**
* 实现:1.绘制背景图(原有逻辑)1
* 2.绘制 water.png(居中)1
* 3.动态绘制 po.png(根据后端返回数据数组个数遍历)
* 4.绘制 guan0.png(根据后端返回数据数组个数遍历)
* 5.绘制 警戒线(4条线,分别对应是个数组,每个坡都有对应的坐标点)
* 6.超过4个po,要动态变换画布高度。
*/
// drawAllImages() {
// const canvasWidth = this.canvas.width
// const canvasHeight = this.canvas.height
// // 1. 绘制背景图(原有逻辑)
// this.ctx.save(); // 保存当前变换状态
// this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认变换(不翻转)
// this.ctx.drawImage(
// this.bgImage,
// 0,
// 0,
// this.canvas.width,
// this.canvas.height
// );
// this.ctx.restore(); // 恢复之前的变换
// // 3. 绘制 po.png(同样临时恢复默认坐标系)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// this.ctx.drawImage(
// this.poImage,
// 0,
// this.canvas.height - 150, // Y坐标调整为画布高度 - 图片高度
// 879,
// 150 // 绘制尺寸(与原尺寸一致)
// );
// this.ctx.restore();
// // 新增:第二张po.png(在第一张上方叠加)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// const secondPoWidth = 879 - 250; // 宽度减少100px
// const secondPoHeight = 150; // 高度保持不变
// const secondPoY = (this.canvas.height - 150) - secondPoHeight; // Y坐标:第一张顶部位置(原Y坐标 - 自身高度)
// this.ctx.drawImage(
// this.poImage,
// 0, // X轴保持0
// secondPoY, // Y轴为第一张顶部位置
// secondPoWidth, // 新宽度
// secondPoHeight // 保持高度
// );
// this.ctx.restore();
// // 3. 绘制 guan0.png(po.png 右侧中间,上层)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// // 计算位置:
// // po.png 右侧 x 坐标 = po.png x + po.png 宽度 = 0 + 879 = 879
// // po.png 垂直中间 y 坐标 = po.png y + po.png 高度/2 = (canvas.height - 150) + 75 = canvas.height - 75
// // guan0.png 垂直居中需要 y = po.png中间y - guan0.png高度/2 = (canvas.height - 75) - (121/2) = canvas.height - 135.5
// const guanX = 879 - 150;
// const guanY = this.canvas.height - 135.5;
// this.ctx.drawImage(
// this.guanImage,
// guanX,
// guanY, // 目标位置(右侧中间)
// 6,
// 121 // 目标尺寸(宽6px,高121px)
// );
// this.ctx.restore();
// /**
// * canvas绘画原则。坐标轴从左上角开始画,y轴要从上往下找y轴的起始原点。
// * canvasWidth:this.canvas.height // 画布的宽度(目前为600)
// * poHeight:150px // 每个坡的高度
// * guanPaddingTop:30px // 每个管孔距离对应层级坡顶部的距离
// drawImage:(imgsrc, 起始x,起始y,绘画宽度距离, 绘画高度距离)
// */
// // 新增:第二张guanImage(在第一张基础上叠加)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0);
// const secondGuanX = secondPoWidth - 150; // x轴:原宽度值(6px)-250px
// const secondGuanY = this.canvas.height - 135.5; // y轴:原高度值(121px)
// this.ctx.drawImage(
// this.guanImage,
// secondGuanX, // 新x坐标
// secondPoY + 30, // 新y坐标
// 6, // 保持宽度6px
// 200 // secondPoY/1.5 // 保持高度121px
// );
// console.log((secondPoY/2), '(secondPoY/2) ')
// this.ctx.restore();
// // 新增:绘制红色连接线(关键修改)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认坐标系(原点在左上角)
// this.ctx.strokeStyle = "red"; // 设置线颜色为红色
// this.ctx.lineWidth = 2; // 设置线宽
// this.ctx.beginPath(); // 开始路径
// // 第一坐标点:第一个guanImage的x,y=guanY+30
// this.ctx.moveTo(guanX, (guanY + 100));
// // 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150
// this.ctx.lineTo(secondGuanX, secondGuanY+50);
// // 新增:第三坐标点(示例坐标,需根据实际业务调整)
// const thirdX = secondGuanX - 100; // 假设第三个点x坐标在第二个点基础上右移100px
// const thirdY = secondGuanY - 10; // 假设第三个点y坐标在第二个点基础上下移80px(根据实际需求调整)
// this.ctx.lineTo(thirdX, thirdY);
// this.ctx.stroke(); // 描边绘制
// this.ctx.restore();
// // 新增:绘制红色连接线(关键修改)
// this.ctx.save();
// this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认坐标系(原点在左上角)
// this.ctx.strokeStyle = "yellow"; // 设置线颜色为红色
// this.ctx.lineWidth = 2; // 设置线宽
// this.ctx.beginPath(); // 开始路径
// // 第一坐标点:第一个guanImage的x,y=guanY+30
// this.ctx.moveTo(guanX, (guanY + 100 - 20));
// // 第二坐标点:第二个guanImage的x,y=secondGuanY+30+150
// this.ctx.lineTo(secondGuanX, secondGuanY+50 -20);
// this.ctx.stroke(); // 描边绘制
// this.ctx.restore();
// // 2. 绘制 water.png(临时恢复默认坐标系,避免翻转)
// this.ctx.save(); // 保存当前变换状态
// this.ctx.setTransform(1, 0, 0, 1, 0, 0); // 恢复默认变换(不翻转)
// this.ctx.drawImage(
// this.waterImage,
// 0,
// this.canvas.height - 255, // Y坐标调整为画布高度 - 图片高度(原点在左下角)
// 485,
// 255 // 绘制尺寸(与原尺寸一致)
// );
// this.ctx.restore(); // 恢复之前的变换
// },
// /** 加载背景图并绘制 */
// loadBackgroundImage() {
// this.bgImage = new Image();
// this.bgImage.src = require("@/assets/images/jrx/bg.png"); // 路径根据项目实际结构调整
// // 图片加载完成后绘制
// this.bgImage.onload = () => {
// // 绘制背景图(注意:坐标系已变换,Y轴向上)
// // 原点在左下角,直接从 (0,0) 开始绘制,高度方向需适配翻转后的坐标系
// this.ctx.drawImage(
// this.bgImage,
// 0,
// 0, // 图片在画布上的起始坐标(左下角原点)
// this.canvas.width, // 绘制宽度
// this.canvas.height // 绘制高度
// );
// };
// // 处理图片加载错误
// this.bgImage.onerror = () => {
// console.error("背景图加载失败");
// this.ctx.fillStyle = "#f0f0f0";
// this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
// };
// },
/** 初始化图表(关键修改:调整图例位置) */
initChart() {
return;
const mockData = this.generateMockData();
console.log("shuju", mockData);
this.chartInstance = Highcharts.chart(this.$refs.chartContainer, {
title: { text: "监测数据趋势图" },
xAxis: { type: "datetime" },
yAxis: { title: { text: "监测值" } },
legend: {
// 新增图例配置
align: "right", // 水平右对齐
verticalAlign: "top", // 垂直顶部对齐
layout: "vertical", // 垂直排列
x: -20, // 微调水平位置
y: 10 // 微调垂直位置
},
series: [
{ name: "水位", data: [...mockData.waterLevel] },
{ name: "浸润线埋深", data: [...mockData.infiltration] }
]
});
},
initChart1() {
let params = {
sort: "date,desc"
sort: "date,desc",
};
if (this.form.query.daterange) {
params.daterange = this.form.query.daterange.join(",");
......@@ -778,8 +659,8 @@ export default {
request({
url: "data/st/imghistory",
method: "get",
params
}).then(res => {
params,
}).then((res) => {
const data = res.body;
// const data = this.getChartData().body
console.log("data", data);
......@@ -789,7 +670,7 @@ export default {
var option = {
valEnabled: true,
opacity: 1,
lineWidth: 3
lineWidth: 3,
};
var alarmData = this.discernValidAlarmValue(
data.alarm,
......@@ -803,11 +684,11 @@ export default {
console.log("chartCData", chartData);
Highcharts.setOptions({
global: {
useUTC: false
useUTC: false,
},
lang: {
resetZoom: "重置缩放比例"
}
resetZoom: "重置缩放比例",
},
});
this.chartInstance = new Highcharts.chart(this.$refs.chartContainer, {
......@@ -817,20 +698,20 @@ export default {
//marginTop:30,
//marginBottom:30,
//marginLeft:30,
zoomType: "x" // xy
zoomType: "x", // xy
},
valEnabled: true,
opacity: 1,
lineWidth: 3,
title: {
text: ""
text: "",
},
subtitle: {
text: ""
text: "",
},
tooltip: {
enabled: false,
borderWidth: 10
borderWidth: 10,
},
xAxis: {
type: "datetime",
......@@ -848,28 +729,28 @@ export default {
day: "%m-%d",
week: "%m-%d",
month: "%Y-%m",
year: "%Y"
}
year: "%Y",
},
},
yAxis: {
title: {
text: ""
text: "",
},
labels: {
x: -6
x: -6,
},
gridLineColor: "#aaa",
max: null
max: null,
},
plotOptions: {
column: {
borderWidth: 0
borderWidth: 0,
//y:50,
//itemMarginTop:50,
},
bar: {
borderWidth: 0
}
borderWidth: 0,
},
},
tooltip: {
// {point.y:.4f} // 保留4位小数
......@@ -890,8 +771,8 @@ export default {
day: "%m-%d %H时",
week: "%m-%d",
month: "%Y-%m",
year: "%Y"
}
year: "%Y",
},
},
legend: {
enabled: chartData.series.length > 1 ? true : false,
......@@ -914,12 +795,12 @@ export default {
y: -10,
itemMarginTop: 2,
itemStyle: {},
itemHoverStyle: {}
itemHoverStyle: {},
},
credits: {
enabled: false
enabled: false,
},
series: chartData.series
series: chartData.series,
});
});
},
......@@ -944,7 +825,7 @@ export default {
"#00ABBD",
"#ffd886",
"#9F2E61",
"#4D670C"
"#4D670C",
];
var len = names.length;
......@@ -955,7 +836,7 @@ export default {
data: [],
key: item.key,
type: data.chartType,
color: colors[i]
color: colors[i],
};
opts && serie.type && (serie.type = opts.type);
series.push(serie);
......@@ -989,10 +870,10 @@ export default {
{ color: "red", name: "红色报警线" },
{ color: "orange", name: "橙色报警线" },
{ color: "yellow", name: "黄色报警线" },
{ color: "blue", name: "蓝色报警线" }
{ color: "blue", name: "蓝色报警线" },
],
alarmLine = {},
setAlarmSerie = function(value, name, color) {
setAlarmSerie = function (value, name, color) {
// 修改蓝色色值
color === "blue" && (color = "#3BAFFB");
var sx = list[0].date,
......@@ -1000,7 +881,10 @@ export default {
var serie = {
name: name,
type: "spline",
data: [{ x: sx, y: value }, { x: ex, y: value }],
data: [
{ x: sx, y: value },
{ x: ex, y: value },
],
color: color,
enableMouseTracking: false,
legend: false,
......@@ -1009,8 +893,8 @@ export default {
lineWidth: opts.lineWidth || 1,
states: {
inactive: {
opacity: opts.opacity
}
opacity: opts.opacity,
},
},
dataLabels: {
enabled: opts.valEnabled || false, // 数据值, 2022/11/11(周五) 因多条报警线暂时关闭
......@@ -1021,19 +905,19 @@ export default {
allowOverlap: true,
color: color,
style: {
textOutline: "none"
}
textOutline: "none",
},
},
tooltip: {
//footerFormat:'',
//pointFormat:'',
headerFormat: ""
headerFormat: "",
//nullFormat:'',
},
marker: {
enabled: false
enabled: false,
},
zIndex: -10
zIndex: -10,
};
series.push(serie);
};
......@@ -1071,12 +955,12 @@ export default {
switchChartType(type) {
this.currentChartType = type;
if (this.chartInstance) {
this.chartInstance.series.forEach(series => {
this.chartInstance.series.forEach((series) => {
series.update({ type: this.currentChartType });
});
}
},
loadData: function() {
loadData: function () {
console.log(this.form, "form");
this.initChart1();
......@@ -1087,8 +971,8 @@ export default {
},
submitForm(form, item) {
reqApi.common.submitForm.call(this, form, item);
}
}
},
},
};
</script>
<style rel="stylesheet/scss" lang="scss" scope>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment