Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
V
V3-TailingPond
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xinzhedeai
V3-TailingPond
Commits
2c6f846b
Commit
2c6f846b
authored
Jun 27, 2025
by
xinzhedeai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add:浸润线绘制接口数据对接 处理
parent
30508fd6
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1237 additions
and
392 deletions
+1237
-392
index copy.vue
src/views/dataMonitor/jrx/history/index copy.vue
+961
-0
index.vue
src/views/dataMonitor/jrx/history/index.vue
+276
-392
No files found.
src/views/dataMonitor/jrx/history/index copy.vue
0 → 100644
View file @
2c6f846b
<
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
>
src/views/dataMonitor/jrx/history/index.vue
View file @
2c6f846b
...
...
@@ -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
=
[])
{
handleCanvasData
1
(
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
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment