初次提交
This commit is contained in:
BIN
components/.DS_Store
vendored
Normal file
BIN
components/.DS_Store
vendored
Normal file
Binary file not shown.
87
components/Search/index.vue
Normal file
87
components/Search/index.vue
Normal file
@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<view class="search">
|
||||
<u-icon name="search" color="#009C77!important" size="40"></u-icon>
|
||||
|
||||
<u-input
|
||||
v-model="dec"
|
||||
style="width: 100%"
|
||||
type="text"
|
||||
:placeholder="placeholder"
|
||||
:clearable="false"
|
||||
@blur="blur"
|
||||
/>
|
||||
<view class="shaixuan" @click="open" id="search">
|
||||
<text style="white-space: nowrap">{{$t('homePage.alarm.sift')}}</text>
|
||||
<u-icon name="arrow-right" color="#009C77!important" size="30"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "请输入告警内容筛选",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dec: "",
|
||||
value1: 1,
|
||||
value2: 2,
|
||||
show_: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.show_ = true;
|
||||
this.$emit("custom");
|
||||
},
|
||||
blur() {
|
||||
this.$emit("blur", this.dec);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search {
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border-radius: 10rpx;
|
||||
box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 20rpx;
|
||||
padding-right: 20rpx;
|
||||
position: relative;
|
||||
|
||||
.shaixuan {
|
||||
white-space: nowrap;
|
||||
|
||||
display: flex;
|
||||
// float: right;
|
||||
// display: flex;
|
||||
// flex:1;
|
||||
// justify-content:flex-end;
|
||||
align-items: center;
|
||||
color: #009c77;
|
||||
}
|
||||
|
||||
.proper {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 80rpx;
|
||||
height: 500rpx;
|
||||
background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-dropdown__content {
|
||||
position: fixed;
|
||||
}
|
||||
</style>
|
||||
213
components/charts/index.vue
Normal file
213
components/charts/index.vue
Normal file
@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<l-echart :ref="id"></l-echart>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "Echarts",
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: "chart",
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: "100%",
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: "100%",
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
gradient: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
labelFormatter: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
direction: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler(value) {
|
||||
const self = this
|
||||
const copy_options = Object.assign({}, value);
|
||||
if (this.gradient.length > 0 && value.series) {
|
||||
copy_options.series.map((item, index) => {
|
||||
if (this.gradient.length > index * 2 + 1) {
|
||||
item.areaStyle = {
|
||||
normal: {
|
||||
// 右,下,左,上
|
||||
color: this.$echarts.graphic.LinearGradient(
|
||||
this.direction[0],
|
||||
this.direction[1],
|
||||
this.direction[2],
|
||||
this.direction[3],
|
||||
[{
|
||||
offset: 0,
|
||||
color: this.gradient[index * 2],
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: this.gradient[index * 2 + 1],
|
||||
},
|
||||
],
|
||||
false
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
if (value.series) {
|
||||
setTimeout(() => {
|
||||
if (this.labelFormatter && copy_options?.series) {
|
||||
this.dataList.map((item,index) => {
|
||||
const middleIndexList = this.findMiddleIndex(item.list)
|
||||
copy_options.series[index].label = {
|
||||
show: true,
|
||||
formatter(params) {
|
||||
const isInclude = middleIndexList.findIndex(i => i === params.dataIndex)
|
||||
if (isInclude === -1) {
|
||||
return ''
|
||||
} else {
|
||||
return params.data
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
this.$refs[this.id].init(this.$echarts, (chart) => {
|
||||
chart.setOption(copy_options);
|
||||
});
|
||||
}, 100)
|
||||
}
|
||||
|
||||
},
|
||||
// deep:true
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initChart();
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
const self = this
|
||||
// 初始化echart
|
||||
const copy_value = Object.assign({}, this.options);
|
||||
if (this.gradient.length > 0 && this.options.series) {
|
||||
|
||||
copy_value.series.map((item, index) => {
|
||||
if (this.gradient.length > index * 2 + 1) {
|
||||
item.areaStyle = {
|
||||
normal: {
|
||||
// 右,下,左,上
|
||||
color: this.$echarts.graphic.LinearGradient(
|
||||
this.direction[0],
|
||||
this.direction[1],
|
||||
this.direction[2],
|
||||
this.direction[3],
|
||||
[{
|
||||
offset: 0,
|
||||
color: this.gradient[index * 2],
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: this.gradient[index * 2 + 1],
|
||||
},
|
||||
],
|
||||
false
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (this.options.series) {
|
||||
setTimeout(() => {
|
||||
if (this.labelFormatter && copy_value?.series) {
|
||||
this.dataList.map((item,index) => {
|
||||
const middleIndexList = this.findMiddleIndex(item.list)
|
||||
copy_value.series[index].label = {
|
||||
show: true,
|
||||
formatter(params) {
|
||||
const isInclude = middleIndexList.findIndex(i => i === params.dataIndex)
|
||||
if (isInclude === -1) {
|
||||
return ''
|
||||
} else {
|
||||
if (isInclude > 0) {
|
||||
return ''
|
||||
}
|
||||
return params.data
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// chart.clear()
|
||||
this.$refs[this.id].init(this.$echarts, (chart) => {
|
||||
chart.setOption(copy_value);
|
||||
});
|
||||
}, 100)
|
||||
// this.$nextTick(()=>{
|
||||
|
||||
// })
|
||||
}
|
||||
},
|
||||
findMiddleIndex(arr) {
|
||||
let firstIndex = -1 // 第一个不为null的
|
||||
|
||||
let prev = -1
|
||||
const result = []
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i] !== null) {
|
||||
if (firstIndex === -1) {
|
||||
firstIndex = i
|
||||
}
|
||||
if (i !== arr.length - 1) {
|
||||
if (arr[i + 1] === null) {
|
||||
prev = i
|
||||
result.push((prev + firstIndex) / 2)
|
||||
firstIndex = -1
|
||||
}
|
||||
} else if (i === arr.length - 1) {
|
||||
prev = i
|
||||
result.push((prev + firstIndex) / 2)
|
||||
firstIndex = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.echarts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
17
components/echarts/echarts.min.js
vendored
Normal file
17
components/echarts/echarts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
330
components/history-modal/index.vue
Normal file
330
components/history-modal/index.vue
Normal file
@ -0,0 +1,330 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-modal v-model="visible" :show-title="false" :show-confirm-button="false" :mask-close-able="true" width="90%">
|
||||
<view class="slot-content">
|
||||
<view class="model-item-box">
|
||||
<Section :title="title + '\xa0' + $t('homePage.device.historyData')" />
|
||||
<view class="time-box" @click="openHistoryTime">
|
||||
<view class="time">
|
||||
{{ time[0] }}
|
||||
</view>~
|
||||
<view class="time">
|
||||
{{ time[1] }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="chart-box">
|
||||
<zero-loading v-if="chartLoading"></zero-loading>
|
||||
<charts v-else-if="!chartLoading && valData.length" :id="'historyChart'" :options="history_option"></charts>
|
||||
<view v-else-if="!chartLoading && !valData.length" class="empty">{{this.$t('homePage.home.noData')}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-modal>
|
||||
<view style="position: fixed; z-index: 99999999">
|
||||
<uni-datetime-picker ref="hisTime" @change="selectHisTime" v-model="time" :clearIcon="false"
|
||||
type="datetimerange" :end="endTime" rangeSeparator="~" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
import Section from "@/components/section/index.vue";
|
||||
import charts from "@/components/charts/index.vue";
|
||||
import { beforeDayTime,dataConversion } from '@/common/common.js'
|
||||
export default {
|
||||
components: { Section, charts },
|
||||
props:{
|
||||
isShow: { // 弹窗是否展示
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title:{
|
||||
type:String,
|
||||
default:''
|
||||
},
|
||||
params:{
|
||||
type:Object,
|
||||
default:()=>{}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.isShow
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:isShow', false)
|
||||
}
|
||||
},
|
||||
currentStation() {
|
||||
return this.vuex_currentStation;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
currentStation: {
|
||||
handler(val) {
|
||||
if (val && val.id) {
|
||||
this.stationId = val.id
|
||||
this.time = beforeDayTime()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
visible: {
|
||||
handler(val) {
|
||||
if(val && this.stationId){
|
||||
this.time = beforeDayTime()
|
||||
this.getHistoryData()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
histroy_show: false,
|
||||
history_option: {},
|
||||
stationId:null,
|
||||
time:[],
|
||||
endTime: dataConversion(new Date()),
|
||||
chartLoading:false,
|
||||
valData:[]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectHisTime() {
|
||||
this.getHistoryData()
|
||||
},
|
||||
openHistoryTime() {
|
||||
this.$refs.hisTime.show();
|
||||
},
|
||||
getHistoryData() {
|
||||
const self = this;
|
||||
self.chartLoading = true
|
||||
return new Promise((resolve, reject) => {
|
||||
self.$u.api.homePageData
|
||||
.GetHistoryData({
|
||||
stationId: this.stationId,
|
||||
beginTime: this.time[0],
|
||||
endTime: this.time[1],
|
||||
modelCol: this.params.modelCol,
|
||||
deviceType: this.params.modelType,
|
||||
srcId:this.params.srcId
|
||||
})
|
||||
.then((res) => {
|
||||
setTimeout(() => {
|
||||
this.chartLoading = false
|
||||
self.initHistoryChart(res.data)
|
||||
}, 800);
|
||||
resolve();
|
||||
})
|
||||
.catch((err) => {
|
||||
reject("错误");
|
||||
});
|
||||
});
|
||||
},
|
||||
initHistoryChart(val){
|
||||
let dateArr = [];
|
||||
let nameArr = [];
|
||||
let valueArr = [];
|
||||
let serveArr = [];
|
||||
|
||||
if (val && val.length > 0) {
|
||||
if (val[0].staticCurveList) {
|
||||
this.valData = val[0].staticCurveList
|
||||
val[0].staticCurveList.forEach((item) => {
|
||||
dateArr.push(item.date);
|
||||
})
|
||||
}else{
|
||||
this.valData = []
|
||||
}
|
||||
val.forEach((item, index) => {
|
||||
nameArr.push(item.deviceName);
|
||||
const arr = [];
|
||||
valueArr[index] = []
|
||||
if (item.staticCurveList) {
|
||||
item.staticCurveList.forEach((item2) => {
|
||||
arr.push(item2.digital);
|
||||
valueArr[index] = arr;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
serveArr.push({
|
||||
name: nameArr[index],
|
||||
type: "line",
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
showSymbol: false,
|
||||
data: valueArr[index],
|
||||
});
|
||||
});
|
||||
|
||||
this.history_option = {
|
||||
animationDuration: 500,
|
||||
animationEasing: "cubicInOut",
|
||||
color: ["#009C77", "#BFE49F", "#00E6B0"],
|
||||
grid: {
|
||||
left: '10%',
|
||||
right: '8%',
|
||||
top: '12%',
|
||||
bottom: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {},
|
||||
textStyle: {
|
||||
textShadowBlur: 10, // 重点
|
||||
textShadowColor: "transparent", // 重点
|
||||
},
|
||||
confine: true,
|
||||
position: function (point, params, dom, rect, size) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var pointX = point[0];
|
||||
var pointY = point[1];
|
||||
var boxWidth = size.contentSize[0];
|
||||
var boxHeight = size.contentSize[1];
|
||||
if (boxWidth > pointX) {
|
||||
x = 5;
|
||||
y -= 15;
|
||||
} else {
|
||||
x = pointX - boxWidth - 15;
|
||||
}
|
||||
if (boxHeight + 20 > pointY) {
|
||||
y = pointY + 15;
|
||||
} else if (boxHeight > pointY) {
|
||||
y = 5;
|
||||
} else {
|
||||
y += pointY - boxHeight;
|
||||
}
|
||||
return [x, y];
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
data: dateArr,
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: "#4F5458",
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: "#A3A3A3",
|
||||
formatter: function (params) {
|
||||
let newParamsName = "";
|
||||
const paramsNameNumber = params.length; // 文字总长度
|
||||
const provideNumber = 11; //一行显示几个字
|
||||
const rowNumber = Math.ceil(paramsNameNumber / provideNumber);
|
||||
if (paramsNameNumber > provideNumber) {
|
||||
for (let p = 0; p < rowNumber; p++) {
|
||||
const start = p * provideNumber;
|
||||
const end = start + provideNumber;
|
||||
const tempStr =
|
||||
p === rowNumber - 1 ?
|
||||
params.substring(start, paramsNameNumber) :
|
||||
params.substring(start, end) + "\n";
|
||||
newParamsName += tempStr;
|
||||
}
|
||||
} else {
|
||||
newParamsName = params;
|
||||
}
|
||||
return newParamsName;
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: [{
|
||||
name: this.params.unit ? this.title + this.params.unit : this.title,
|
||||
type: "value",
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: "#4F5458",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: "#A3A3A3",
|
||||
},
|
||||
min: function (value) {
|
||||
return Math.floor(
|
||||
(Math.abs(value.min) < value.max ?
|
||||
-value.max * 1.05 :
|
||||
value.min * 1.05
|
||||
).toFixed(2)
|
||||
);
|
||||
},
|
||||
max: function (value) {
|
||||
return Math.ceil(
|
||||
(Math.abs(value.min) < value.max ?
|
||||
value.max * 1.05 :
|
||||
-value.min * 1.05
|
||||
).toFixed(2)
|
||||
);
|
||||
},
|
||||
}],
|
||||
|
||||
series: serveArr,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.slot-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
.chart-box {
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.time-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
margin-top: 20rpx;
|
||||
// border: 1px solid #a3a3a3;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 8rpx;
|
||||
padding: 10rpx;
|
||||
|
||||
.time {
|
||||
z-index: 9999999999;
|
||||
font-size: 28rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.empty{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// font-size: 24rpx;
|
||||
color: #2a2a2a;
|
||||
}
|
||||
|
||||
</style>
|
||||
361
components/new-canvas/index.vue
Normal file
361
components/new-canvas/index.vue
Normal file
@ -0,0 +1,361 @@
|
||||
<template>
|
||||
<view style="width: 100%;height: 100%;position: relative;">
|
||||
<zero-loading v-show="loading && !noloading" position="absolute" v-if="loading && !noloading"></zero-loading>
|
||||
<canvas :id="cId" type="2d" :style="{width:width,height:height}" :canvas-id="cId"></canvas>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
windowWidth: 0,
|
||||
type: 'app',
|
||||
ctx: null,
|
||||
textArr: [],
|
||||
imgArr: [],
|
||||
lineArr: [],
|
||||
circleArr: [],
|
||||
rectArr: [],
|
||||
loading: true,
|
||||
canvasWidth: null,
|
||||
canvasHeight: null
|
||||
}
|
||||
},
|
||||
props: {
|
||||
cId: {
|
||||
type: [String, Number],
|
||||
default: 'canvas'
|
||||
},
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: '100%'
|
||||
},
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: '100%'
|
||||
},
|
||||
canvasData: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
},
|
||||
noloading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
canvasData: {
|
||||
handler(val) {
|
||||
if (val && val.length) {
|
||||
this.getSystemInfo()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// this.getSystemInfo()
|
||||
},
|
||||
methods: {
|
||||
getSystemInfo() {
|
||||
const self = this
|
||||
// 获取屏幕尺寸
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
this.windowWidth = res.windowWidth
|
||||
},
|
||||
})
|
||||
uni.getSystemInfo({
|
||||
success: function(res) {
|
||||
// const platform = res.hostName.toLowerCase()
|
||||
if (res.uniPlatform || res.uniPlatform === 'app') {
|
||||
self.type = 'app'
|
||||
//获取app的canvas的dom
|
||||
self.getAppDom()
|
||||
} else {
|
||||
self.type = 'wx'
|
||||
//获取小程序的canvas的dom
|
||||
self.getWXDom()
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
clear() {
|
||||
if (this.type === 'wx') {
|
||||
this.ctx.globalCompositeOperation = 'destination-out';
|
||||
this.ctx.beginPath();
|
||||
this.ctx.fillStyle = 'red';
|
||||
this.ctx.fillRect(0, 0, 8000, 80000);
|
||||
this.ctx.fill();
|
||||
this.ctx.globalCompositeOperation = 'source-over';
|
||||
// this.ctx.draw();
|
||||
} else {
|
||||
// this.ctx.clearRect(2000, 2000, 2000, 2000);
|
||||
// this.ctx.fillStyle = '#ffffff'
|
||||
// this.ctx.draw(true);
|
||||
}
|
||||
|
||||
},
|
||||
//获取app的canvas DOM
|
||||
getAppDom() {
|
||||
var context = uni.createCanvasContext(`${this.cId}`)
|
||||
this.ctx = context
|
||||
this.draw(null)
|
||||
},
|
||||
//获取微信的canvas DOM
|
||||
getWXDom() {
|
||||
// const instance = getCurrentInstance()
|
||||
let query = wx.createSelectorQuery().in(this)
|
||||
query
|
||||
.select(`#${this.cId}`)
|
||||
.fields({
|
||||
node: true,
|
||||
size: true
|
||||
}, () => {})
|
||||
.exec(this.initCanvas.bind(this))
|
||||
},
|
||||
initCanvas(res) {
|
||||
|
||||
const width = res[0].width
|
||||
const height = res[0].height
|
||||
const canvas = res[0].node
|
||||
this.ctx = canvas.getContext('2d')
|
||||
|
||||
const dpr = wx.getSystemInfoSync().pixelRatio
|
||||
canvas.width = width * dpr
|
||||
canvas.height = height * dpr
|
||||
this.canvasWidth = canvas.width
|
||||
this.canvasHeight = canvas.height
|
||||
this.ctx.scale(dpr, dpr)
|
||||
this.draw(canvas)
|
||||
},
|
||||
draw(canvas) {
|
||||
this.textArr = []
|
||||
this.circleArr = []
|
||||
this.rectArr = []
|
||||
this.imgArr = []
|
||||
this.lineArr = []
|
||||
this.canvasData.forEach((item) => {
|
||||
if (item.type === 'text') {
|
||||
this.textArr.push(item)
|
||||
}
|
||||
if (item.type === 'image') {
|
||||
this.imgArr.push(item)
|
||||
}
|
||||
if (item.type === 'line') {
|
||||
this.lineArr.push(item)
|
||||
}
|
||||
if (item.type === 'circle') {
|
||||
this.circleArr.push(item)
|
||||
}
|
||||
if (item.type === 'rect') {
|
||||
this.rectArr.push(item)
|
||||
}
|
||||
})
|
||||
if (this.imgArr.length) {
|
||||
this.drawImages(this.imgArr, canvas ? canvas : null)
|
||||
}
|
||||
if (this.lineArr.length) {
|
||||
this.drawLine(this.lineArr)
|
||||
}
|
||||
if (this.circleArr.length) {
|
||||
this.drawCircle(this.circleArr)
|
||||
}
|
||||
if (this.rectArr.length) {
|
||||
this.drawRect(this.rectArr)
|
||||
}
|
||||
if (this.textArr.length) {
|
||||
this.drawText(this.textArr)
|
||||
}
|
||||
|
||||
// this.drawLine(this.lineArr)
|
||||
// this.drawCircle(this.circleArr)
|
||||
// this.drawRect(this.rectArr)
|
||||
// this.drawText(this.textArr)
|
||||
if (this.type === 'app') {
|
||||
this.ctx.draw()
|
||||
}
|
||||
this.loading = false
|
||||
|
||||
|
||||
},
|
||||
drawRect(draw) {
|
||||
draw.forEach((item, index) => {
|
||||
let x = this.fitSize(item.coord[0][0])
|
||||
let y = this.fitSize(item.coord[0][1])
|
||||
let w = this.fitSize(item.coord[1][0])
|
||||
let h = this.fitSize(item.coord[1][1])
|
||||
this.ctx.beginPath();
|
||||
if (this.type === 'app') {
|
||||
if (item.rectType === 'stroke') {
|
||||
this.ctx.setStrokeStyle(item.borderColor); // 设置边框颜色
|
||||
this.ctx.setLineWidth(item.width); // 设置边框宽度
|
||||
this.ctx.strokeRect(x, y, w, h); // 绘制无填充矩形
|
||||
} else {
|
||||
this.ctx.setFillStyle(item.background || 'transparent');
|
||||
this.ctx.fillRect(x, y, w, h);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (item.rectType === 'stroke') {
|
||||
this.ctx.strokeStyle = item.borderColor
|
||||
this.ctx.lineWidth = item.width
|
||||
this.ctx.strokeRect(x, y, w, h);
|
||||
} else {
|
||||
this.ctx.fillStyle = item.background || 'transparent'
|
||||
this.ctx.fillRect(x, y, w, h);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
countChineseAndEnglishCharacters(str, x) {
|
||||
var chineseCount = str.match(/[\u4e00-\u9fa5]/g)
|
||||
? str.match(/[\u4e00-\u9fa5]/g).length
|
||||
: 0;
|
||||
var englishCount = str.match(/[a-zA-Z]/g)
|
||||
? str.match(/[a-zA-Z]/g).length
|
||||
: 0;
|
||||
var otherCount = str.length - chineseCount - englishCount;
|
||||
const obj = {
|
||||
otherCount: otherCount,
|
||||
chineseCount: chineseCount,
|
||||
englishCount: englishCount,
|
||||
};
|
||||
return (
|
||||
obj.englishCount * 6 + obj.chineseCount * 12 + obj.otherCount * 7.5 + x
|
||||
);
|
||||
},
|
||||
|
||||
drawText(draw) {
|
||||
draw.forEach((item, index) => {
|
||||
if (item.font.length) {
|
||||
if (item.font.length > 1) {
|
||||
item.font.forEach((item2, index2) => {
|
||||
if (this.type === 'app') {
|
||||
this.ctx.setFontSize(item2.size)
|
||||
} else {
|
||||
this.ctx.fontSize = item2.size
|
||||
}
|
||||
this.ctx.fillStyle = item2.color
|
||||
const x = this.countChineseAndEnglishCharacters(item.font[0].text,item.coord[0][0])
|
||||
this.ctx.fillText(item2.text, this.fitSize( index2 === 1 ? x : item.coord[0][0]), this.fitSize(item.coord[0][1]))
|
||||
this.ctx.closePath()
|
||||
})
|
||||
} else {
|
||||
if (this.type === 'app') {
|
||||
this.ctx.setFontSize(item.font[0].size)
|
||||
} else {
|
||||
this.ctx.fontSize = item.font[0].size
|
||||
}
|
||||
this.ctx.fillStyle = item.font[0].color
|
||||
this.ctx.fillText(item.font[0].text, this.fitSize(item.coord[0][0]), this.fitSize(item
|
||||
.coord[0][1]))
|
||||
this.ctx.closePath()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
drawImages(draw, canvas) {
|
||||
let x,
|
||||
y,
|
||||
w,
|
||||
h = 0
|
||||
|
||||
draw.forEach((item) => {
|
||||
if (item.coord.length >= 2) x = item.coord[0][0]
|
||||
y = item.coord[0][1]
|
||||
w = item.coord[1][0]
|
||||
h = item.coord[1][1]
|
||||
if (this.type === 'wx') {
|
||||
let img = canvas.createImage()
|
||||
img.src = item.url
|
||||
img.onload = () => {
|
||||
this.ctx.drawImage(
|
||||
img,
|
||||
this.fitSize(item.coord[0][0]),
|
||||
this.fitSize(item.coord[0][1]),
|
||||
this.fitSize(item.coord[1][0]),
|
||||
this.fitSize(item.coord[1][1])
|
||||
)
|
||||
|
||||
this.drawLine(this.lineArr)
|
||||
this.drawCircle(this.circleArr)
|
||||
this.drawRect(this.rectArr)
|
||||
this.drawText(this.textArr)
|
||||
if (this.type === 'app') {
|
||||
this.ctx.draw()
|
||||
}
|
||||
this.loading = false
|
||||
}
|
||||
} else {
|
||||
this.ctx.drawImage(item.url, this.fitSize(x), this.fitSize(y), this.fitSize(w),
|
||||
this
|
||||
.fitSize(h))
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
drawLine(draw) {
|
||||
draw.forEach((item) => {
|
||||
let x1 = this.fitSize(item.coord[0][0])
|
||||
let y1 = this.fitSize(item.coord[0][1])
|
||||
let x2 = this.fitSize(item.coord[1][0])
|
||||
let y2 = this.fitSize(item.coord[1][1])
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo(x1, y1)
|
||||
this.ctx.lineTo(x2, y2)
|
||||
if (this.type === 'app') {
|
||||
this.ctx.setStrokeStyle(item.color)
|
||||
this.ctx.setLineWidth(item.width)
|
||||
} else {
|
||||
this.ctx.strokeStyle = item.color
|
||||
this.ctx.lineWidth = item.width
|
||||
}
|
||||
|
||||
if (item.dash && item.dash.length > 0) {
|
||||
//虚线
|
||||
this.ctx.setLineDash(item.dash)
|
||||
}
|
||||
|
||||
this.ctx.stroke()
|
||||
this.ctx.closePath()
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
drawCircle(draw) {
|
||||
draw.forEach((item) => {
|
||||
let x = this.fitSize(item.coord[0][0])
|
||||
let y = this.fitSize(item.coord[0][1])
|
||||
let r = this.fitSize(item.r)
|
||||
this.ctx.beginPath()
|
||||
this.ctx.arc(x, y, r, 0, Math.PI * 2, false)
|
||||
this.ctx.fillStyle = item.color
|
||||
this.ctx.fill()
|
||||
this.ctx.closePath()
|
||||
})
|
||||
},
|
||||
fitSize(coordinate) {
|
||||
let newWindowWidth = this.windowWidth //这个windowWidth指的是该设备宽度,可以onLoad监听页面加载中获取
|
||||
let v = 375 / newWindowWidth //375是设计稿的大小,得到的v值是:设计稿和设备宽度的比例关系,也可理解成在设计稿的大小基础上放大或缩小的倍数
|
||||
return coordinate / v //返回的是当前坐标值或者大小与v的比例
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
79
components/new-search/index.vue
Normal file
79
components/new-search/index.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view class="search" >
|
||||
<u-icon name="search" color="#009C77" size="40"></u-icon>
|
||||
|
||||
<u-input v-model="dec" style="width:100%;" type="text" :placeholder="this.$t('homePage.device.inputNameQuery')" :clearable='false'/>
|
||||
<view class="shaixuan" id="search">
|
||||
<u-button @click="search" size="mini" shape="circle" :custom-style="{backgroundColor:'#009C77',color:'#FFFFFF'}">{{this.$t('homePage.device.query')}}</u-button>
|
||||
</view>
|
||||
<!-- <input type="text" :value="dec" :input-align="right" placeholder="请输入告警内容筛选"/> -->
|
||||
<!-- <view class="proper" v-if="show_" id="popup">
|
||||
123123
|
||||
|
||||
</view> -->
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dec: '',
|
||||
value1: 1,
|
||||
value2: 2,
|
||||
show_: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.show_ = true
|
||||
this.$emit('custom')
|
||||
},
|
||||
search(){
|
||||
this.$emit('search',this.dec)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search {
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border-radius: 57rpx;
|
||||
// box-shadow: 0px 4rpx 16rpx rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 20rpx;
|
||||
padding-right: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
|
||||
.shaixuan {
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
padding-top: 10rpx;
|
||||
padding-bottom: 10rpx;
|
||||
align-items: center;
|
||||
color: #009C77
|
||||
}
|
||||
|
||||
.proper {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 80rpx;
|
||||
height: 500rpx;
|
||||
background-color: red;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-dropdown__content {
|
||||
position: fixed;
|
||||
}
|
||||
</style>
|
||||
52
components/section/index.vue
Normal file
52
components/section/index.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<view class="warp">
|
||||
<image src="/static/aidex/images/item.png"></image>
|
||||
<view class="title">
|
||||
{{ title }}
|
||||
</view>
|
||||
<slot name="right" class="slot-right"></slot>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.warp {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
.title{
|
||||
// width: 40%;
|
||||
// white-space: nowrap;
|
||||
// overflow: hidden;
|
||||
// text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 15rpx
|
||||
}
|
||||
|
||||
.slot-right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
133
components/station-dropdow/index.vue
Normal file
133
components/station-dropdow/index.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<view class="home-navbar-warp" :class="disabled ? 'nocolor' : 'color'">
|
||||
<view class="search">
|
||||
<u-input v-model="stationName" :disabled='disabled' :type="disabled? 'text' : 'select'" :select-open="selectStaion" input-align="center" @click="openSelectStation" class="input-box" color="#fff" />
|
||||
</view>
|
||||
|
||||
<u-select v-model="selectStaion" mode="mutil-column-auto" :key="selectKey" :list="stationList" :value-name="'id'" :label-name="'name'" :child-name="'list'" @confirm="confirmStation" @cancel="cancelSelect" :mask-close-able="false" :default-value="StationShow" confirm-color="#009C77"></u-select>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
stationName: '所有电站',
|
||||
selectStaion: false,
|
||||
StationShow: [],
|
||||
defaultArr: [],
|
||||
selectKey:0
|
||||
// stationList: []
|
||||
// activeSelectLabel:'所有电站',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stationList () {
|
||||
return this.vuex_provinceStation
|
||||
},
|
||||
currentStation () {
|
||||
return this.vuex_currentStation
|
||||
}
|
||||
},
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentStation: {
|
||||
handler (val) {
|
||||
this.stationName = val.name
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
},
|
||||
stationList:{
|
||||
handler (val) {
|
||||
this.selectKey++
|
||||
// setTimeout(() =>{
|
||||
this.StationShow = [0,0,0]
|
||||
// },2000)
|
||||
// this.StationShow = this.vuex_StationShow
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// this.StationShow = this.vuex_StationShow
|
||||
|
||||
},
|
||||
created () {
|
||||
|
||||
},
|
||||
methods: {
|
||||
openSelectStation () {
|
||||
if (!this.disabled) {
|
||||
this.$emit('openPop', true)
|
||||
this.selectStaion = true
|
||||
}
|
||||
|
||||
},
|
||||
cancelSelect () {
|
||||
this.$emit('openPop', false)
|
||||
this.selectStaion = false
|
||||
},
|
||||
confirmStation (val) {
|
||||
val[2].name = val[2].label
|
||||
val[2].id = val[2].value
|
||||
this.stationName = val[2].label
|
||||
|
||||
const cityIndex = this.stationList.findIndex((item) => {
|
||||
return item.name === val[0].label
|
||||
})
|
||||
|
||||
|
||||
const value = this.stationList.find((item) => {
|
||||
return item.name === val[0].label
|
||||
})
|
||||
|
||||
const valIndex = value.list.findIndex((item) => {
|
||||
return item.name === val[1].label
|
||||
})
|
||||
|
||||
const newValIndex = value.list[valIndex].list.findIndex((item) => {
|
||||
return +item.id === +val[2].value
|
||||
})
|
||||
this.StationShow = [cityIndex, valIndex, newValIndex]
|
||||
val[2].topologyType = value.list[valIndex].list[newValIndex].topologyType
|
||||
// val[2].StationShow = this.StationShow
|
||||
this.$u.vuex("vuex_currentStation", val[2])
|
||||
this.$u.vuex("vuex_StationShow", this.StationShow)
|
||||
this.$emit('openPop', false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.color {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.nocolor {
|
||||
background-color: transparent;
|
||||
}
|
||||
.home-navbar-warp {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
border-radius: 8rpx;
|
||||
// background-color: rgba(255, 255, 255, 0.7);
|
||||
.search {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
/deep/ .input-box {
|
||||
color: #fff !important;
|
||||
.uicon-arrow-down-fill {
|
||||
color: #fff !important;
|
||||
}
|
||||
.u-input__input {
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user