Compare commits

..

10 Commits

Author SHA1 Message Date
2f3ceaee8f style(components): 调整小边框图表的样式 提高 .right-select 的 z-index 以确保正确的层级关系 2025-09-08 17:54:23 +08:00
f9e910ed88 refactor(charts): 调整图表组件的默认尺寸
- 修改了多个图表组件的宽度和高度属性
- 优化了部分组件的样式,如移除背景色
2025-09-08 17:53:35 +08:00
b01d276440 style(components): 调整小边框图表标题位置 2025-09-08 17:26:07 +08:00
6160ec4d6d refactor(Charts): 重构报警列表、设备状态和折线图组件
- 更新报警列表和设备状态组件的配置结构
- 优化报警列表和设备状态组件的模板和样式
- 重构折线图组件的配置结构
- 更新折线图组件的设置项
2025-09-08 17:25:49 +08:00
85b6f78163 refactor(Charts/HazardousChemicalsSpace): 优化 AlarmList 和 LineGraph 组件,移除未使用的 Select 组件
- 修复 AlarmListHazC 组件中的数据解析逻辑
- 调整 LineGraph01Haz 组件的样式
- 删除 PieCenterHaz 中未使用的 select 组件
2025-09-08 17:25:20 +08:00
4635366147 refactor(Charts): 重构有限空间组件并删除旧折线图
- 重构了 AlarmNowList 和 FiniteSpatialDistribution 组件的结构
- 更新了组件样式和布局
- 删除了未使用的 LineDropdownConfined 组件相关文件
2025-09-08 17:24:40 +08:00
67950643db chore:规范名字 2025-09-08 15:05:16 +08:00
417d458775 refactor(Charts): 重构报警列表组件配置和数据获取
- 更新配置文件,使用深拷贝初始化配置选项
- 添加默认属性设置,包括位置和尺寸
- 优化模板结构,移除冗余空行
- 修改数据获取 API,添加场景码参数
2025-09-08 15:04:00 +08:00
bdeac87abd refactor(Charts): 重构折线图组件
- 移除自定义标题和边框样式,使用公共组件 PublicSmallBorder
- 添加 titleText 配置项
2025-09-08 13:57:40 +08:00
0cad8a2b2c feat(components): 添加 Public_SmallBorder 组件 2025-09-08 13:57:19 +08:00
69 changed files with 1921 additions and 4484 deletions

View File

@ -6,16 +6,9 @@ import dataJson from './data.json'
import { chartInitConfig } from '@/settings/designSetting'
export const styleConfig = {
titleText: '实时报警',
titleOption: {
},
headerOption: {
paddingLeft: 0,
paddingRight: 0,
paddingTop: 0,
paddingBottom: 0
}
}
export const option = {
...styleConfig,
sceneCode: 'T01',
dataset: dataJson,
rowNum: 4,
@ -27,5 +20,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key = AlarmNowListConfig.key
public chartConfig = cloneDeep(AlarmNowListConfig)
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 430, h: 300, zIndex: 1 }
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,11 +1,10 @@
<template>
<SmallBorder :titleText="styleConfig.titleText" :title-option="styleConfig.titleOption"
:headerOption="styleConfig.headerOption">
<PublicSmallBorder :title-text="chartConfig.option.titleText">
<div class="content_box">
<vue3-seamless-scroll v-if="option.dataset && option.dataset.length > 0" class="seamless" :list="option.dataset"
:limitScrollNum="rowNum" :hover="true" :step="waitTime" :wheel="true" :isWatch="true">
<div v-for="(item, index) in option.dataset" class="detail flex_column" :key="index">
<div class="flex_v cursor" :style="!showRankNum ? { paddingLeft: 0 } : { paddingLeft: '24px' }"
<div class="flex_v cursor" :style="!showRankNum ? { paddingLeft: 0 } : { paddingLeft: '12px' }"
@click="handleOpenDialog(item)">
<div v-if="index === 0 && showRankNum" class="levelOneIcon flex_c">{{ index + 1 }}</div>
<div v-else-if="index === 1 && showRankNum" class="levelTwoIcon flex_c">{{ index + 1 }}</div>
@ -121,7 +120,8 @@
</n-grid>
</n-modal>
</div>
</SmallBorder>
</PublicSmallBorder>
</template>
<script setup lang="ts">
@ -137,9 +137,10 @@ import PlayBack from '@/components/Pages/yushiVideo/playback.vue'
import PlayLive from '@/components/Pages/yushiVideo/playLive.vue'
import axiosInstance from '@/api/axios'
import VChart from 'vue-echarts'
import SmallBorder from '../SmallBorder01Co/index.vue'
// import SmallBorder from '../SmallBorder01Co/index.vue'
import { height } from 'dom-helpers'
import axios from 'axios'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType & typeof option>,
@ -315,7 +316,9 @@ onUnmounted(() => {
<style lang="scss" scoped>
.content_box {
z-index: -1;
z-index: 20;
width: 100%;
height: 100%;
}
@ -353,7 +356,7 @@ onUnmounted(() => {
align-items: center;
// background-color: #0a0c1260;
border-bottom: 1.5px solid #123E54;
margin: 3px;
margin: 1px;
}
.item_level_text {

View File

@ -10,7 +10,8 @@ export const includes = ['legend']
// 其它配置
const otherConfig = {
sceneCode: 'T01',
componentIndexKey:"",
componentIndexKey: "",
titleText: '各企业有限空间总数及各等级有限空间的数量',
dateTime: {
selectValue: 'day',
dataset: [
@ -126,5 +127,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key: string = FiniteSpatialDistributionConfig.key
public chartConfig = cloneDeep(FiniteSpatialDistributionConfig)
public option = echartOptionProfixHandle(option, includes)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 420, h: 280, zIndex: 1 }
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,8 +1,11 @@
<template>
<div class="go-border-box">
<img src="./assets/title.svg" class="svg" />
<div class="header-title">各企业有限空间总数及各等级有限空间的数量 </div>
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor" :option="option"></v-chart>
<PublicSmallBorder :title-text="props.chartConfig.option.titleText">
<div class="content">
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor"
:option="option"></v-chart>
</div>
</PublicSmallBorder>
</div>
</template>
@ -24,7 +27,7 @@ import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent, Tit
import dataJson from './data.json'
import { getPie3D } from './3dPie'
import axiosInstance from '@/api/axios';
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
themeSetting: {
type: Object,
@ -113,63 +116,15 @@ onMounted(async () => {
</script>
<style lang="scss" scoped>
@include go(border-box) {
position: relative;
border-radius: 5px;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
.go-border-box {
width: 100%;
height: 100%;
padding: 0;
//
// background-color: #0E121B;
//
background: linear-gradient(to top,
rgba(14, 18, 27, 1) 0%,
rgba(14, 18, 27, 0.6) 100%);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 5px;
padding: 2px;
/* 边框宽度 */
background: linear-gradient(to top,
rgba(128, 128, 128, 0.3),
rgba(128, 128, 128, 0));
-webkit-mask:
linear-gradient(#fff, #fff) content-box,
linear-gradient(#fff, #fff);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
.content {
width: 100%;
height: 100%;
}
}
.header-title {
position: absolute;
top: 0;
height: 45px;
line-height: 45px;
left: 70px;
white-space: nowrap;
font-family: 'CustomFont';
font-style: italic;
letter-spacing: 0.5px;
color: #eee;
text-shadow: 1px 3px 10px #000000;
font-size: 16px;
}
.svg {
width: 100%;
height: 45px;
}
</style>

View File

@ -1,114 +0,0 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { LineDropdownConfinedConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['xAxis', 'yAxis', 'grid']
const option = {
backgroundColor: 'rgba(13, 16, 22, 1)',
grid: {
left: '8%',
right: '8%',
top: '15%',
bottom: '15%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: 'rgba(255, 255, 255, 0.6)',
fontSize: 12
},
},
yAxis: {
type: 'value',
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: 'rgba(255, 255, 255, 0.6)',
fontSize: 12
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255, 255, 255, 0.1)',
type: 'solid'
}
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
lineStyle: {
color: 'rgba(58, 160, 255, 1)',
type: 'solid'
}
}
},
dataset: { ...dataJson },
series: [
{
type: 'line',
smooth: true,
symbol: 'none', // 默认不显示点
symbolSize: 8,
lineStyle: {
width: 2,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{ offset: 0, color: 'rgba(58, 160, 255, 1)' },
{ offset: 1, color: 'rgba(127, 216, 255, 1)' }
]
}
},
emphasis: {
focus: 'series',
symbol: 'circle', // 鼠标悬停时显示圆点
symbolSize: 8,
itemStyle: {
color: 'rgba(58, 160, 255, 1)',
borderColor: 'rgba(255, 255, 255, 0.8)',
borderWidth: 2
}
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(58, 160, 255, 0.5)' },
{ offset: 1, color: 'rgba(58, 160, 255, 0.05)' }
]
}
}
}
]
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = LineDropdownConfinedConfig.key
public chartConfig = cloneDeep(LineDropdownConfinedConfig)
public option = echartOptionProfixHandle(option, includes)
}

View File

@ -1,16 +0,0 @@
<template>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { NSpace, NCard, NFormItem, NInput } from 'naive-ui'
import config from './config'
defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
</script>

View File

@ -1,81 +0,0 @@
{
"dimensions": ["time", "value"],
"source": [
{
"time": "13:00",
"value": 50
},
{
"time": "13:05",
"value": 45
},
{
"time": "13:10",
"value": 55
},
{
"time": "13:15",
"value": 48
},
{
"time": "13:20",
"value": 42
},
{
"time": "13:25",
"value": 38
},
{
"time": "13:30",
"value": 35
},
{
"time": "13:35",
"value": 40
},
{
"time": "13:40",
"value": 50
},
{
"time": "13:45",
"value": 65
},
{
"time": "13:50",
"value": 78
},
{
"time": "13:55",
"value": 80
},
{
"time": "14:00",
"value": 75
},
{
"time": "14:05",
"value": 68
},
{
"time": "14:10",
"value": 60
},
{
"time": "14:15",
"value": 55
},
{
"time": "14:20",
"value": 52
},
{
"time": "14:25",
"value": 58
},
{
"time": "14:30",
"value": 62
}
]
}

View File

@ -1,14 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
// import { ChatCategoryEnum, ChatCategoryEnumName } from '../..'
export const LineDropdownConfinedConfig: ConfigType = {
key: 'LineDropdownConfined',
chartKey: 'VLineDropdownConfined',
conKey: 'VCLineDropdownConfined',
title: '下拉折线图',
category: 'ConfinedSpace',
categoryName: '有限空间组件',
package: PackagesCategoryEnum.CHARTS,
chartFrame: ChartFrameEnum.ECHARTS,
image: 'line_warn.png'
}

File diff suppressed because one or more lines are too long

View File

@ -19,7 +19,6 @@ const otherConfig = {
isCarousel: false,
color: ['#3B72E8', '#45B5E3', '#50D4A8', '#F8B55B'],
selectOption: {
show: true,
selectValue: 'month',
dataset: [
{
@ -45,15 +44,8 @@ const otherConfig = {
]
},
titleText: '报警统计',
titleOption: {
},
headerOption: {
paddingLeft: 0,
paddingRight: 0,
paddingTop: 0,
paddingBottom: 0
}, selectStyleOption: {
selectStyleOption: {
...selectStyleOption
}
}
// ECharts配置
@ -139,7 +131,7 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key: string = PieCircleCommenConfig.key
public chartConfig = cloneDeep(PieCircleCommenConfig)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 430, h: 300, zIndex: 1 }
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@ -1,12 +1,10 @@
<template>
<div class="go-border-box">
<SmallBaorder01 :titleText="option.titleText" :title-option="option.titleOption"
:select-option="option.selectOption" :header-option="option.headerOption" @change="handleBorderSelectChange"
:selectStyleConfig="selectStyleOption
">
<PublicSmallBorder :title-text="option.titleText" :select-option="option.selectOption"
:selectStyleConfig="option.selectStyleOption" @change="handleBorderSelectChange">
<v-chart class=" chart" ref="vChartRef" :theme="themeColor" :init-options="initOptions" :option="option"
autoresize> </v-chart>
</SmallBaorder01>
</PublicSmallBorder>
</div>
</template>
@ -21,7 +19,8 @@ import { mergeTheme } from '@/packages/public/chart'
import config, { includes, selectStyleOption } from './config'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import SmallBaorder01 from '../SmallBorder01Co/index.vue'
// import SmallBaorder01 from '../SmallBorder01Co/index.vue'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
import {
DatasetComponent,
GridComponent,

View File

@ -43,5 +43,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key = videoCheckConfig.key
public chartConfig = cloneDeep(videoCheckConfig)
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 430, h: 300, zIndex: 1 }
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,8 +1,7 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<div>
<SmallBaorder01 :titleText="option.titleText" :title-option="option.titleOption"
:headerOption="option.headerOption">
<PublicSmallBorder :titleText="option.titleText">
<div :class="option.isOldStyle ? 'video_title' : 'video_title video_title_new'" v-if="option.showBtn">
<div class="title_text" v-if="option.showTree && option.showBtn">{{ option.videoTitle }}</div>
<n-select v-if="!option.showTree" class="video_select" placement="top-end"
@ -25,9 +24,7 @@
</n-modal>
</div>
<div ref="vYushiVideoRef" class="go-video" :id="uuid"></div>
</SmallBaorder01>
</PublicSmallBorder>
</div>
</template>
@ -44,9 +41,9 @@ import { PageEnum } from '@/enums/pageEnum'
import axios from 'axios'
import { getUUID, isPreview } from '@/utils'
import { useYushiVideoStore } from '@/store/modules/yushiVideoStore/yushiVideoStore'
import SmallBaorder01 from '../SmallBorder01Co/index.vue'
// import SmallBaorder01 from '../SmallBorder01Co/index.vue'
import axiosInstance from '@/api/axios'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const yushiStore = useYushiVideoStore()
let selectedList = []

View File

@ -2,6 +2,8 @@ import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { AlarmListHazCConfig } from './index'
import dataJson from './data.json'
import { chartInitConfig } from '@/settings/designSetting'
import { cloneDeep } from 'lodash'
export enum FontWeightEnum {
NORMAL = '常规',
BOLD = '加粗',
@ -38,20 +40,12 @@ export const option = {
itemHeight: 28,
fontSize: 12,
titleText: '近60分钟报警信息',
titleSize: 16,
titleColor: '#eee',
fontWeight: 'normal',
fontStyle: 'italic',
paddingX: 45,
paddingY: -25,
letterSpacing: 0.5,
isShowButton: false
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = AlarmListHazCConfig.key
public chartConfig = AlarmListHazCConfig
public option = option
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -34,17 +34,13 @@
</PublicSmallBorder>
</div>
</template>
<script setup lang="ts">
import { PropType, computed, ref, onMounted, onUnmounted } from 'vue'
import { option as configOption } from './config'
import SmallBorder from '../SmallBorder/index.vue'
import axiosInstance from '@/api/axios'
import PublicSmallBorder from '../../Public_SmallBorder/index.vue'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
chartConfig: {
type: Object as PropType<{ option: typeof configOption }>,
@ -73,7 +69,7 @@ const convertTimestampToDateTime = (timestamp: number | string) => {
const fetchRecentAlarms = async () => {
try {
const res: any = await axiosInstance.get(
`/awjt/space/getRecentAlarms`,
`/awjt/space/getRecentAlarms/${option.value.sceneCode}`,
{
responseType: 'json',
baseURL: ''
@ -84,7 +80,7 @@ const fetchRecentAlarms = async () => {
if (res.state === true) {
let rawData = [];
if (Array.isArray(res.value.items)) {
rawData = res.data.value.items;
rawData = res.value.items;
} else if (Array.isArray(res.value)) {
rawData = res.value;
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 174 KiB

View File

@ -3,42 +3,43 @@ import { LineDropdownConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
import { chartInitConfig } from '@/settings/designSetting'
export const includes = ['xAxis', 'yAxis', 'grid']
// 其它配置
const otherConfig = {
dateTime: {
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
},
sceneCode: '',
dateTime: {
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
},
sceneCode: '',
titleText: "报警趋势"
}
export const option = {
...otherConfig,
backgroundColor: 'rgba(13, 16, 22, 1)',
// backgroundColor: 'rgba(13, 16, 22, 1)',
grid: {
left: '8%',
right: '8%',
@ -142,4 +143,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key: string = LineDropdownConfig.key
public chartConfig = cloneDeep(LineDropdownConfig)
public option = echartOptionProfixHandle(option, includes)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,28 +1,24 @@
<template>
<div class="go-border-box">
<img src="./assets/title.svg" class="svg" />
<div class="header-title">报警趋势</div>
<CustomSelect
:options="option.dateTime.dataset"
:selectedValue="option.dateTime.selectValue"
@change="handleSelectChange"
/>
<PublicSmallBorder :title-text="option.titleText" :select-option="option.dateTime" @change="handleSelectChange">
<!-- <CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
@change="handleSelectChange" /> -->
<div class="line-dropdown-container">
<!-- 新增的风险级别下拉框 -->
<div class="risk-level-select">
<CustomSelect
:options="riskLevelOptions"
:selectedValue="selectedRiskLevel"
@change="handleRiskLevelChange"
/>
</div>
<div class="line-dropdown-container">
<!-- 新增的风险级别下拉框 -->
<div class="risk-level-select">
<CustomSelect :options="riskLevelOptions" :selectedValue="selectedRiskLevel"
@change="handleRiskLevelChange" />
</div>
<!-- 折线图 -->
<div class="chart-container">
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor" :option="option"></v-chart>
<!-- 折线图 -->
<div class="chart-container">
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor"
:option="option"></v-chart>
</div>
</div>
</div>
</PublicSmallBorder>
</div>
</template>
@ -39,6 +35,7 @@ import config, { includes } from './config'
import { DatasetComponent, GridComponent, TooltipComponent } from 'echarts/components'
import CustomSelect from './select.vue'
import axiosInstance from '@/api/axios'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
themeSetting: {
@ -96,7 +93,7 @@ const processChartData = async (timeType: string, riskLevel: number) => {
const rawData = await fetchChartData(timeType, riskLevel)
//
let processedData: Array<{time: string, value: number}> = []
let processedData: Array<{ time: string, value: number }> = []
switch (timeType) {
case 'day':
@ -152,15 +149,15 @@ const handleDropdownChange = () => {
//
const handleSelectChange = (value: any) => {
props.chartConfig.option.dateTime.selectValue = value
updateChartData()
props.chartConfig.option.dateTime.selectValue = value
updateChartData()
}
//
const handleRiskLevelChange = (value: any) => {
selectedRiskLevel.value = value
updateChartData()
console.log('Selected risk level:', value)
selectedRiskLevel.value = value
updateChartData()
console.log('Selected risk level:', value)
}
//
@ -172,9 +169,9 @@ onMounted(() => {
<style scoped>
.line-dropdown-container {
width: 100%;
height: 100%;
background: rgba(13, 16, 22, 1);
position: relative;
height: calc(100% - 40px);
/* background: rgba(13, 16, 22, 1); */
/* position: relative; */
}
.dropdown-container {
@ -183,45 +180,45 @@ onMounted(() => {
left: 7%;
width: 86%;
z-index: 10;
position: relative;
/* position: relative; */
/* 添加边框样式到父容器 */
border-radius: 8px;
padding: 1px;
background: linear-gradient(to bottom,
rgba(255, 255, 255, 0.8) 0%,
rgba(200, 200, 200, 0.6) 25%,
rgba(150, 150, 150, 0.5) 50%,
rgba(100, 100, 100, 0.4) 75%,
rgba(60, 60, 60, 0.3) 100%);
rgba(255, 255, 255, 0.8) 0%,
rgba(200, 200, 200, 0.6) 25%,
rgba(150, 150, 150, 0.5) 50%,
rgba(100, 100, 100, 0.4) 75%,
rgba(60, 60, 60, 0.3) 100%);
transition: all 0.3s ease;
}
/* hover状态的彩色渐变边框 */
.dropdown-container:hover {
background: linear-gradient(to bottom,
rgba(58, 160, 255, 1) 0%,
rgba(98, 255, 198, 0.8) 25%,
rgba(54, 110, 255, 1) 50%,
rgba(28, 234, 160, 0.8) 75%,
rgba(58, 160, 255, 1) 100%);
rgba(58, 160, 255, 1) 0%,
rgba(98, 255, 198, 0.8) 25%,
rgba(54, 110, 255, 1) 50%,
rgba(28, 234, 160, 0.8) 75%,
rgba(58, 160, 255, 1) 100%);
}
/* focus状态的增强彩色渐变边框 */
.dropdown-container:focus-within {
background: linear-gradient(to bottom,
rgba(58, 160, 255, 1) 0%,
rgba(98, 255, 198, 1) 25%,
rgba(54, 110, 255, 1) 50%,
rgba(28, 234, 160, 1) 75%,
rgba(58, 160, 255, 1) 100%);
rgba(58, 160, 255, 1) 0%,
rgba(98, 255, 198, 1) 25%,
rgba(54, 110, 255, 1) 50%,
rgba(28, 234, 160, 1) 75%,
rgba(58, 160, 255, 1) 100%);
}
.custom-dropdown1 {
/* 渐变背景 */
background: linear-gradient(135deg,
rgba(25, 35, 45, 0.95) 0%,
rgba(15, 25, 35, 0.95) 50%,
rgba(35, 45, 55, 0.95) 100%);
rgba(25, 35, 45, 0.95) 0%,
rgba(15, 25, 35, 0.95) 50%,
rgba(35, 45, 55, 0.95) 100%);
/* 移除边框,因为已经移到父容器 */
border: none;
@ -247,9 +244,9 @@ onMounted(() => {
transform: translateY(-1px);
/* 增强背景渐变 */
background: linear-gradient(135deg,
rgba(35, 45, 55, 0.95) 0%,
rgba(25, 35, 45, 0.95) 50%,
rgba(45, 55, 65, 0.95) 100%);
rgba(35, 45, 55, 0.95) 0%,
rgba(25, 35, 45, 0.95) 50%,
rgba(45, 55, 65, 0.95) 100%);
}
.custom-dropdown1:focus {
@ -319,7 +316,7 @@ onMounted(() => {
transform: translateY(-50%) rotate(180deg);
}
.custom-dropdown1:focus + .dropdown-arrow {
.custom-dropdown1:focus+.dropdown-arrow {
transform: translateY(-50%) rotate(180deg);
color: rgba(58, 160, 255, 1);
text-shadow: 0 0 8px rgba(58, 160, 255, 0.5);
@ -329,69 +326,20 @@ onMounted(() => {
padding-top: 0px;
box-sizing: border-box;
width: 100%;
height: 100%;
flex: 1;
height: 99%;
/* min-height: 0; */
/* height: 100%; */
}
</style>
<style lang="scss" scoped>
@include go(border-box) {
position: relative;
border-radius: 5px;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
padding: 0;
//
// background-color: #0E121B;
//
background: linear-gradient(to top,
rgba(14, 18, 27, 1) 0%,
rgba(14, 18, 27, 0.6) 100%);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 5px;
padding: 2px;
/* 边框宽度 */
background: linear-gradient(to top,
rgba(128, 128, 128, 0.3),
rgba(128, 128, 128, 0));
-webkit-mask:
linear-gradient(#fff, #fff) content-box,
linear-gradient(#fff, #fff);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
}
.header-title {
position: absolute;
height: 45px;
line-height: 45px;
left: 80px;
white-space: nowrap;
font-family: 'CustomFont';
font-style: italic;
letter-spacing: 0.5px;
color: #eee;
text-shadow: 1px 3px 10px #000000;
font-size: 16px;
}
//
.risk-level-select {
position: relative;
width: 90%;
margin: 10px auto 0;
flex-shrink: 0;
:deep(.custom-select) {
z-index: 999;
@ -429,9 +377,4 @@ onMounted(() => {
}
}
}
.svg {
width: 100%;
height: 45px;
}
</style>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 174 KiB

View File

@ -4,6 +4,7 @@ import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import { chartInitConfig } from '@/settings/designSetting'
import dataJson from './data.json'
export interface DataSourceItem {
dataname: string;
values: number[];
@ -17,7 +18,9 @@ export interface DatasType {
dataSource: DataSourceItem[];
}
const otherOption = {
titleText: '报警处置情况'
}
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
export const seriesItem = {
type: 'line',
@ -57,31 +60,32 @@ export const seriesItem = {
}
}
export const option = {
...otherOption,
sceneCode: 'T04',
dateTime: {
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
},
dataset: {
@ -136,6 +140,6 @@ export default class Config extends PublicConfigClass implements CreateComponent
public mockData = dataJson
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 450, h: 300, zIndex: 1 }
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,38 +1,38 @@
<template>
<div class="go-border-box">
<img src="./assets/title.svg" class="svg" />
<div class="buttonContent">
<span class="title">报警处置情况</span>
</div>
<!-- 使用新的下拉选择器组件 -->
<CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
@change="handleSelectChange" />
<!-- <CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
@change="handleSelectChange" /> -->
<PublicSmallBorder :title-text="option.titleText" :select-option="option.dateTime" @change="handleSelectChange">
<div class="content">
<div class="textContent">
<div class="textInContent">
<span class="smallText">报警总数 </span>
<span class="bigText">{{ currentData.alertTotal?.toLocaleString('en-US') || '0' }}</span>
</div>
<div class="textInContent">
<span class="smallText">未处置报警数</span>
<span class="bigText">{{ currentData.unprocessedAlert?.toLocaleString('en-US') || '0' }}</span>
</div>
<div class="textInContent">
<span class="smallText">平均处置时长</span>
<span class="bigText">{{ currentData.averageResolutionTime?.toLocaleString('en-US') || '0' }}</span>
</div>
</div>
<div class="chartsContent">
<span class="smallText Tips">
<img class="icon" src="./icon01.png" alt="">
数据统计图表</span>
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="chartOption"
:update-options="{
replaceMerge: replaceMergeArr
}" autoresize>
</v-chart>
</div>
</div>
</PublicSmallBorder>
<div class="textContent">
<div class="textInContent">
<span class="smallText">报警总数 </span>
<span class="bigText">{{ currentData.alertTotal?.toLocaleString('en-US') || '0' }}</span>
</div>
<div class="textInContent">
<span class="smallText">未处置报警数</span>
<span class="bigText">{{ currentData.unprocessedAlert?.toLocaleString('en-US') || '0' }}</span>
</div>
<div class="textInContent">
<span class="smallText">平均处置时长</span>
<span class="bigText">{{ currentData.averageResolutionTime?.toLocaleString('en-US') || '0' }}</span>
</div>
</div>
<div class="chartsContent">
<span class="smallText Tips">
<img class="icon" src="./icon01.png" alt="">
数据统计图表</span>
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="chartOption" :update-options="{
replaceMerge: replaceMergeArr
}" autoresize>
</v-chart>
</div>
</div>
</template>
<script setup lang="ts">
@ -50,7 +50,7 @@ import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } fr
import isObject from 'lodash/isObject'
import CustomSelect from './select.vue'
import axiosInstance from '@/api/axios'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
themeSetting: {
type: Object,
@ -82,7 +82,7 @@ const selectedTimeRange = ref('day')
// API
const fetchChartData = async (option: string) => {
try {
const response:any = await axiosInstance.get(`/awjt/screen/handleByOption/${option}/${props.chartConfig.option.sceneCode}`,{baseURL:''})
const response: any = await axiosInstance.get(`/awjt/screen/handleByOption/${option}/${props.chartConfig.option.sceneCode}`, { baseURL: '' })
if (response.state === true) {
return response.value || []
} else {
@ -251,48 +251,20 @@ onMounted(() => {
</script>
<style lang="scss" scoped>
@include go(border-box) {
position: relative;
border-radius: 5px;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
padding: 0;
//
// background-color: #0E121B;
//
background: linear-gradient(to top,
rgba(14, 18, 27, 1) 0%,
rgba(14, 18, 27, 0.6) 100%);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 10px;
padding: 2px;
/* 边框宽度 */
background: linear-gradient(to top,
rgba(128, 128, 128, 0.3),
rgba(128, 128, 128, 0));
-webkit-mask:
linear-gradient(#fff, #fff) content-box,
linear-gradient(#fff, #fff);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
.content {
width: 100%;
height: 100%;
position: relative;
}
}
.textContent {
padding-top: 20px;
// padding-top: 20px;
/* background-color: brown; */
display: flex;
justify-content: space-around;

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 174 KiB

View File

@ -3,12 +3,13 @@ import { PieCenterConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
import { chartInitConfig } from '@/settings/designSetting'
export const includes = ['legend']
// 其它配置
const otherConfig = {
sceneCode:'T04',
titleText: "报警统计",
sceneCode: 'T04',
dateTime: {
selectValue: 'day',
dataset: [
@ -236,4 +237,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key: string = PieCenterConfig.key
public chartConfig = cloneDeep(PieCenterConfig)
public option = echartOptionProfixHandle(option, includes)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,11 +1,11 @@
<template>
<div class="go-border-box">
<img src="./assets/title.svg" class="svg" />
<div class="header-title">报警统计</div>
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor" :option="option"></v-chart>
<!-- 使用新的下拉选择器组件 -->
<CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
@change="handleSelectChange" />
<PublicSmallBorder :title-text="option.titleText" :select-option="option.dateTime" @change="handleSelectChange">
<!-- <div class="content"> -->
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor"
:option="option"></v-chart>
</PublicSmallBorder>
</div>
</template>
@ -25,6 +25,7 @@ import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent, Gra
import CustomSelect from './select.vue'
import dataJson from './data.json'
import axiosInstance from '@/api/axios'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
themeSetting: {
@ -285,64 +286,4 @@ const handleSelectChange = async (value: string) => {
};
</script>
<style lang="scss" scoped>
@include go(border-box) {
position: relative;
border-radius: 5px;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
padding: 0;
//
// background-color: #0E121B;
//
background: linear-gradient(to top,
rgba(14, 18, 27, 1) 0%,
rgba(14, 18, 27, 0.6) 100%);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 5px;
padding: 2px;
/* 边框宽度 */
background: linear-gradient(to top,
rgba(128, 128, 128, 0.3),
rgba(128, 128, 128, 0));
-webkit-mask:
linear-gradient(#fff, #fff) content-box,
linear-gradient(#fff, #fff);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
}
.header-title {
position: absolute;
top: 0;
height: 45px;
line-height: 45px;
left: 80px;
white-space: nowrap;
font-family: 'CustomFont';
font-style: italic;
letter-spacing: 0.5px;
color: #eee;
text-shadow: 1px 3px 10px #000000;
font-size: 16px;
}
.svg {
width: 100%;
height: 45px;
}
</style>
<style lang="scss" scoped></style>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 174 KiB

View File

@ -1,17 +0,0 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { SmallBorderConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export const option = {
colors: ['#1089ff', '#0000ff'],
backgroundColor: '#00000000'
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = SmallBorderConfig.key
public chartConfig = cloneDeep(SmallBorderConfig)
public option = cloneDeep(option)
}

View File

@ -1,54 +0,0 @@
<template>
<CollapseItem name="边框" :expanded="true">
<SettingItemBox
:name="`颜色-${index + 1}`"
v-for="(item, index) in optionData.colors"
:key="index"
>
<SettingItem name="颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.colors[index]"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.colors[index] = option.colors[index]"
>
恢复默认
</n-button>
</SettingItem>
</SettingItemBox>
</CollapseItem>
<CollapseItem name="背景" :expanded="true">
<SettingItemBox name="颜色">
<SettingItem>
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.backgroundColor"
></n-color-picker>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import {
CollapseItem,
SettingItemBox,
SettingItem
} from '@/components/Pages/ChartItemSetting'
import { option } from './config'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@ -1,17 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
// import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
// 曲线图
export const SmallBorderConfig: ConfigType = {
key: 'SmallBorder',
chartKey: 'VSmallBorder',
conKey: 'VCSmallBorder',
title: '带标题小边框',
category: 'MyComponents',
categoryName: '自定义组件',
package: 'Charts',
chartFrame: ChartFrameEnum.COMMON,
image: "SmallBorder.png",
}
// 默认导出配置对象
export default SmallBorderConfig

View File

@ -1,83 +0,0 @@
<template>
<div class="go-small-border">
<div class="border-content">
<div class="svg-content">
<img src="./assets/title.svg" class="svg" />
</div>
<div class="content">
<slot></slot>
</div>
</div>
</div>
</template>
<script lang="ts">export default { name: "SmallBorder" }</script>
<style lang="scss" scoped>
$border-radius: 10px;
$border-width: 2px;
$bg-color-start: rgba(14, 18, 27, 1);
$bg-color-end: rgba(14, 18, 27, 0.6);
$border-gradient-start: rgba(128, 128, 128, 0.3);
$border-gradient-end: rgba(128, 128, 128, 0);
@include go(small-border) {
position: relative;
width: 100%;
height: 100%;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
& .border-content {
width: 100%;
height: 100%;
padding: 0;
border-radius: $border-radius;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
background: linear-gradient(to top, $bg-color-start, $bg-color-end);
&::before {
content: '';
position: absolute;
inset: 0;
border-radius: $border-radius;
padding: $border-width;
background: linear-gradient(to top, $border-gradient-start, $border-gradient-end);
//
-webkit-mask:
linear-gradient(#fff, #fff) content-box,
linear-gradient(#fff, #fff);
-webkit-mask-composite: xor;
mask:
linear-gradient(#fff, #fff) content-box,
linear-gradient(#fff, #fff);
mask-composite: exclude;
pointer-events: none; // 穿
}
}
& .svg-content {
// z-index: 2;
width: 100%;
height: 12%;
.svg {
width: 100%;
}
// background-color: antiquewhite;
& .svg {
width: 100%;
}
}
}
</style>

View File

@ -3,8 +3,9 @@ import { CreateComponentType } from '@/packages/index.d'
import { TopAlarmsConfig } from './index'
import dataJson from './data.json'
import { cloneDeep } from 'lodash'
import { chartInitConfig } from '@/settings/designSetting'
export const option = {
sceneCode: 'T04',
sceneCode: 'T05',
componentIndexKey: "a",
dateTime: {
selectValue: 'day',
@ -34,24 +35,16 @@ export const option = {
dataset: dataJson.source,
titleText: '未处置报警数TOP5',
titleColor: '#eee',
titleSize: 16,
rankColor: '#5AA1AD',
nameColor: '#eeeeee',
valueColor: '#eeeeee',
barColorStart: '#2f72b5',
barColorEnd: '#99C6E6',
dropdownOptions: ['当日', '当月', '当年'],
dropdownDefault: '当日',
iconColor: '#00E5FF',
letterSpacing: 0.5,
paddingX: 45,
paddingY: -5,
isShowButton: false
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = TopAlarmsConfig.key
public chartConfig = TopAlarmsConfig
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,40 +1,8 @@
<template>
<SmallBorder class="SmallBorder">
<div class="go-top-alarms">
<CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
@change="handleSelectChange" class="top-select" />
<div class="header">
<div class="title">
<div class="title-text">
<span :style="{
color: option.titleColor,
fontSize: option.titleSize + 'px',
marginTop: option.paddingY + 'px',
marginLeft: option.paddingX + 'px',
letterSpacing: option.letterSpacing + 'px'
}">{{ option.titleText }}</span>
</div>
</div>
<n-dropdown v-if='option.isShowButton' trigger="hover" :options="dropdownOptions" @select="handleSelect">
<div class="dropdown-button">
{{ selectedOption }}
<div class="arrow-down-icon">
<svg viewBox="0 0 1024 1024" width="14" height="14">
<path
d="M512 768c-6.3 0-12.6-2.4-17.4-7.3L285.3 551.4c-9.8-9.8-9.8-25.6 0-35.4s25.6-9.8 35.4 0L512 707.3l191.3-191.3c9.8-9.8 25.6-9.8 35.4 0s9.8 25.6 0 35.4L529.4 760.7c-4.8 4.9-11.1 7.3-17.4 7.3z"
fill="currentColor"></path>
</svg>
</div>
</div>
</n-dropdown>
<!-- <n-dropdown v-if='option.isShowButton' trigger="hover" :options="dropdownOptions" @select="handleSelect">
<div class="dropdown-button">
{{ selectedOption }}
<svg-icon icon-class="arrow-down" class="arrow-down-icon" />
</div>
</n-dropdown> -->
</div>
<div class="go-top-alarms">
<!-- <CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
@change="handleSelectChange" class="top-select" /> -->
<PublicSmallBorder :title-text="option.titleText" :select-option="option.dateTime" @change="handleSelectChange">
<div class="content">
<ul>
<li v-for="(item, index) in displayData" :key="index" class="alarm-item">
@ -59,8 +27,8 @@
</li>
</ul>
</div>
</div>
</SmallBorder>
</PublicSmallBorder>
</div>
</template>
<script setup lang="ts">
@ -71,6 +39,7 @@ import CustomSelect from './select.vue'
import axiosInstance from '@/api/axios'
import { TopAlarmsConfig } from './index'
import axios from 'axios'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
chartConfig: {
type: Object as PropType<{ option: typeof configOption }>,
@ -79,18 +48,10 @@ const props = defineProps({
})
const option = computed(() => props.chartConfig.option)
const selectedOption = ref(props.chartConfig.option.dropdownDefault)
// API
const displayData: any = ref([])
const dropdownOptions = computed(() => {
return props.chartConfig.option.dropdownOptions.map(opt => ({
label: opt,
key: opt
}))
})
// API
const calculateWidth = (value: number) => {
if (displayData.value.length === 0 || displayData.value[0].value === 0) {
@ -157,9 +118,6 @@ const fetchCorpsData = async (option: string) => {
}
}
const handleSelect = (key: string) => {
selectedOption.value = key
}
// API
const handleSelectChange = async (value: any) => {
@ -191,26 +149,19 @@ onMounted(async () => {
</script>
<style lang="scss" scoped>
.SmallBorder {
position: relative;
}
.go-top-alarms {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
margin-top: -10px;
// background-color: #0a162b;
padding: 15px;
box-sizing: border-box;
display: flex;
flex-direction: column;
color: #fff;
.top-select {
top: 20px;
.content {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
z-index: 10;
// background-color: #00e5ff;
}
.header {
@ -260,16 +211,12 @@ onMounted(async () => {
}
.content {
flex: 1;
margin-top: -15px;
padding-right: 10px;
font-size: 12.5px;
ul {
list-style: none;
padding: 0;
margin: 0;
height: 100%;
height: 90%;
display: flex;
flex-direction: column;
justify-content: space-around;

View File

@ -2,8 +2,9 @@ import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { yushiVideoConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import { chartInitConfig } from '@/settings/designSetting'
export const option = {
titleText: '实时视频',
sceneCode: 'T04',
// 摄像头id
dataset: {
@ -33,4 +34,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key = yushiVideoConfig.key
public chartConfig = cloneDeep(yushiVideoConfig)
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,30 +1,32 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<div class="go-border-box">
<img src="./assets/title.svg" class="svg" />
<div class="header-title">实时视频</div>
<div :class="option.isOldStyle ? 'video_title' : 'video_title video_title_new'" v-if="option.showBtn">
<div class="title_text" v-if="option.showTree && option.showBtn">{{ option.videoTitle }}</div>
<n-select v-if="!option.showTree" class="video_select" placement="top-end"
v-model:value="option.selectedDataSource" :options="option.dataSource" :style="`width:${w / 2}px;`"
@update:value="handleSelectDataSource" />
<n-button tertiary v-else-if="option.showTree && option.showBtn && option.isOldStyle"
:class="option.isOldStyle ? 'videoChangBtn' : 'videoChangBtn videoChangBtn_new'"
@click="handleClick">切换</n-button>
<n-button tertiary v-else-if="option.showTree && option.showBtn && !option.isOldStyle"
:class="option.isOldStyle ? 'videoChangBtn' : 'videoChangBtn videoChangBtn_new'"
@click="handleClick"></n-button>
<PublicSmallBorder :title-text="option.titleText">
<div :class="option.isOldStyle ? 'video_title' : 'video_title video_title_new'" v-if="option.showBtn">
<div class="title_text" v-if="option.showTree && option.showBtn">{{ option.videoTitle }}</div>
<n-select v-if="!option.showTree" class="video_select" placement="top-end"
v-model:value="option.selectedDataSource" :options="option.dataSource" :style="`width:${w / 2}px;`"
@update:value="handleSelectDataSource" />
<n-button tertiary v-else-if="option.showTree && option.showBtn && option.isOldStyle"
:class="option.isOldStyle ? 'videoChangBtn' : 'videoChangBtn videoChangBtn_new'"
@click="handleClick">切换</n-button>
<n-button tertiary v-else-if="option.showTree && option.showBtn && !option.isOldStyle"
:class="option.isOldStyle ? 'videoChangBtn' : 'videoChangBtn videoChangBtn_new'"
@click="handleClick"></n-button>
<n-modal v-model:show="showDialog" :mask-closable="false" preset="card" title="选择摄像头"
:class="['custom-tab-modal']" :draggable="{ bounds: 'none' }" :style="{ width: '644px', height: '420px' }">
<n-tree-select ref="cameraTree" class="cameraTree" :menu-props="{
class: 'custom-dropdown'
}" v-model:value="option.selectedDataSource" :options="option.dataset.list" clearable
:default-expanded-keys="option.expandedKeys" style="width: 615px; margin-top: 16px" :show="isDropdownOpen"
@update:show="handleShowChange" @update:value="handleSelectDataSource" />
</n-modal>
</div>
<div ref="vYushiVideoRef" class="go-video" :id="uuid"></div>
</PublicSmallBorder>
<n-modal v-model:show="showDialog" :mask-closable="false" preset="card" title="选择摄像头"
:class="['custom-tab-modal']" :draggable="{ bounds: 'none' }" :style="{ width: '644px', height: '420px' }">
<n-tree-select ref="cameraTree" class="cameraTree" :menu-props="{
class: 'custom-dropdown'
}" v-model:value="option.selectedDataSource" :options="option.dataset.list" clearable
:default-expanded-keys="option.expandedKeys" style="width: 615px; margin-top: 16px" :show="isDropdownOpen"
@update:show="handleShowChange" @update:value="handleSelectDataSource" />
</n-modal>
</div>
<div ref="vYushiVideoRef" class="go-video" :id="uuid"></div>
</div>
</template>
@ -41,7 +43,7 @@ import { PageEnum } from '@/enums/pageEnum'
import axios from 'axios'
import { getUUID, isPreview } from '@/utils'
import { useYushiVideoStore } from '@/store/modules/yushiVideoStore/yushiVideoStore'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const yushiStore = useYushiVideoStore()
let selectedList = []
@ -704,63 +706,3 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (n
transform: translateX(7px) translateY(104px) !important;
}
</style>
<style lang="scss" scoped>
@include go(border-box) {
position: relative;
border-radius: 5px;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
padding: 0;
//
// background-color: #0E121B;
//
background: linear-gradient(to top,
rgba(14, 18, 27, 1) 0%,
rgba(14, 18, 27, 0.6) 100%);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 5px;
padding: 2px;
/* 边框宽度 */
background: linear-gradient(to top,
rgba(128, 128, 128, 0.3),
rgba(128, 128, 128, 0));
-webkit-mask:
linear-gradient(#fff, #fff) content-box,
linear-gradient(#fff, #fff);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
}
.header-title {
position: absolute;
top: 3px;
height: 45px;
line-height: 45px;
left: 80px;
white-space: nowrap;
font-family: 'CustomFont';
font-style: italic;
letter-spacing: 0.5px;
color: #eee;
text-shadow: 1px 3px 10px #000000;
font-size: 16px;
}
.svg {
width: 100%;
height: 45px;
}
</style>

View File

@ -2,6 +2,8 @@ import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { AlarmListConfig } from './index'
import dataJson from './data.json'
import { cloneDeep } from 'lodash'
import { chartInitConfig } from '@/settings/designSetting'
export enum FontWeightEnum {
NORMAL = '常规',
BOLD = '加粗',
@ -22,7 +24,7 @@ export const FontStyleObject = {
[FontStyleEnum.ITALIC]: 'italic',
}
export const option = {
sceneCode:"",
sceneCode: "",
dataset: dataJson,
header: ['报警事件', '时间', '所属企业', '状态'],
headerTextColor: '#B4B4B4',
@ -37,21 +39,15 @@ export const option = {
headerHeight: 28,
itemHeight: 28,
fontSize: 12,
title: '近60分钟报警信息',
titleSize: 16,
titleColor: '#eee',
titleText: '近60分钟报警信息',
fontWeight: 'normal',
fontStyle: 'italc',
paddingX: 50,
paddingY: -25,
letterSpacing: 0.5,
isShowButton: false
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = AlarmListConfig.key
public chartConfig = AlarmListConfig
public option = option
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,66 +1,46 @@
<template>
<SmallBorder class="SmallBorder">
<div class="go-alarm-list">
<div class="header">
<div class="title">
<div class="title-text">
<span :style="{
color: option.titleColor,
fontSize: option.titleSize + 'px',
fontWeight: option.fontWeight,
fontStyle: option.fontStyle,
marginLeft: option.paddingX + 'px',
marginTop: option.paddingY + 'px',
letterSpacing: option.letterSpacing + 'px'
}">{{ option.title }}</span>
<div class="go-alarm-list">
<PublicSmallBorder :title-text="option.titleText">
<div class="content">
<div class="table-header" :style="{
height: option.headerHeight + 'px'
}">
<div v-for="header in option.header" :key="header" class="header-item"
:style="{ color: option.headerTextColor, fontSize: option.fontSize + 'px' }">
{{ header }}
</div>
</div>
<div v-if="option.isShowButton" class="header-right-squares">
<div class="square" style="background-color: #2e69e0"></div>
<div class="square" style="background-color: #2e9bf0"></div>
<div class="square" style="background-color: #2ef0b3"></div>
</div>
</div>
<div class="table-header" :style="{
height: option.headerHeight + 'px'
}">
<div v-for="header in option.header" :key="header" class="header-item"
:style="{ color: option.headerTextColor, fontSize: option.fontSize + 'px' }">
{{ header }}
</div>
</div>
<div class="table-body">
<div v-if="isLoading" style="display: flex; width: 100%; justify-content: center; margin-top: 16px">
<n-spin size="large" />
</div>
<div v-for="(item, index) in option.dataset" :key="index" class="table-row"
:style="{ backgroundColor: option.itemBackgroundColor, height: option.itemHeight + 'px' }">
<div class="row-item" :style="{ color: option.textColor, fontSize: option.fontSize + 'px' }">
{{ item.alarmDescname }}
<div class="table-body">
<div v-if="isLoading" style="display: flex; width: 100%; justify-content: center; margin-top: 16px">
<n-spin size="large" />
</div>
<div class="row-item" :style="{ color: option.textColor, fontSize: option.fontSize + 'px' }">
{{ item.alarmTime }}
</div>
<div class="row-item" :style="{ color: option.textColor, fontSize: option.fontSize + 'px' }">
{{ item.compName }}
</div>
<div class="row-item" :style="{ color: getStatusColor(item.alarmLevel), fontSize: option.fontSize + 'px' }">
{{ item.alarmLevel }}
<div v-for="(item, index) in option.dataset" :key="index" class="table-row"
:style="{ backgroundColor: option.itemBackgroundColor, height: option.itemHeight + 'px' }">
<div class="row-item" :style="{ color: option.textColor, fontSize: option.fontSize + 'px' }">
{{ item.alarmDescname }}
</div>
<div class="row-item" :style="{ color: option.textColor, fontSize: option.fontSize + 'px' }">
{{ item.alarmTime }}
</div>
<div class="row-item" :style="{ color: option.textColor, fontSize: option.fontSize + 'px' }">
{{ item.compName }}
</div>
<div class="row-item" :style="{ color: getStatusColor(item.alarmLevel), fontSize: option.fontSize + 'px' }">
{{ item.alarmLevel }}
</div>
</div>
</div>
</div>
</div>
</SmallBorder>
</PublicSmallBorder>
</div>
</template>
<script setup lang="ts">
import { PropType, computed, ref, onMounted, onUnmounted } from 'vue'
import { option as configOption } from './config'
import SmallBorder from '../SmallBorder/index.vue'
import axiosInstance from '@/api/axios'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
chartConfig: {
type: Object as PropType<{ option: typeof configOption }>,
@ -145,22 +125,17 @@ onUnmounted(() => {
</script>
<style lang="scss" scoped>
.SmallBorder {
position: relative;
// background-color: #ffffff;
.go-alarm-list {
width: 100%;
height: 100%;
}
.go-alarm-list {
position: absolute;
top: 0;
right: 0;
.content {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
color: #ffffff;
padding: 12px;
margin-top: 5px;
box-sizing: border-box;
// background-color: #4da6ff;
z-index: 10;

View File

@ -2,6 +2,8 @@ import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { DeviceStatusConfig } from './index'
import dataJson from './data.json'
import { cloneDeep } from 'lodash'
import { chartInitConfig } from '@/settings/designSetting'
export const option = {
dataset: dataJson.source,
header: ['所属企业', '设备类型', '设备名称'],
@ -13,9 +15,7 @@ export const option = {
headerHeight: 30,
itemHeight: 28,
fontSize: 11,
title: '设备实时在线概况',
titleSize: 16,
titleColor: '#eee',
titleText: '设备实时在线概况',
iconColor: '#00E5FF',
onlineRate: 75,
onlineDevice: 23,
@ -26,13 +26,11 @@ export const option = {
progressColor: '#00E5FF',
progressBgColor: 'rgba(0, 0, 0, 0.1)',
progressTextColor: '#DDE3E9',
paddingX: 60,
paddingY: -1,
letterSpacing: 0.5
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = DeviceStatusConfig.key
public chartConfig = DeviceStatusConfig
public option = option
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,27 +1,6 @@
<template>
<SmallBorder>
<PublicSmallBorder :title-text="option.titleText">
<div class="go-device-status">
<div class="header">
<div class="header-left" :style="{
marginLeft:
option.paddingX
+ 'px',
marginTop:
option.paddingY
+ 'px'
}
">
<div class="title-text-bg" :style="{
}">
<span class="title-text" :style="{
letterSpacing: option.letterSpacing + 'px',
color: option.titleColor, fontSize: option.titleSize + 'px'
}">{{
option.title }}</span>
</div>
</div>
</div>
<div class="status-section">
<div class="rate-circle-bg">
<div class="rate-circle"
@ -79,15 +58,15 @@
</div>
</div>
</div>
</SmallBorder>
</PublicSmallBorder>
</template>
<script setup lang="ts">
import SmallBorder from '../SmallBorder/index.vue'
import { PropType, computed } from 'vue'
import { option as configOption } from './config'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
chartConfig: {
type: Object as PropType<{ option: typeof configOption }>,
@ -99,23 +78,13 @@ const option = computed(() => props.chartConfig.option)
</script>
<style lang="scss" scoped>
SmallBorder {
position: relative;
}
.go-device-status {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
// background-color: #041126;
color: #ffffff;
padding: 10px 15px;
// padding-bottom: 3px;
box-sizing: border-box;
z-index: 10;
.header {
display: flex;

View File

@ -3,11 +3,43 @@ import { LineDropdownConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
import { chartInitConfig } from '@/settings/designSetting'
export const includes = ['xAxis', 'yAxis', 'grid']
const option = {
backgroundColor: 'rgba(13, 16, 22, 1)',
// 其它配置
const otherConfig = {
dateTime: {
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
},
sceneCode: '',
titleText: "报警趋势"
}
export const option = {
...otherConfig,
// backgroundColor: 'rgba(13, 16, 22, 1)',
grid: {
left: '8%',
right: '8%',
@ -111,4 +143,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key: string = LineDropdownConfig.key
public chartConfig = cloneDeep(LineDropdownConfig)
public option = echartOptionProfixHandle(option, includes)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,15 +1,22 @@
<template>
<collapse-item name="信息" :expanded="true">
<setting-item-box name="场景 Code " :alone="true">
<setting-item>
<n-input v-model:value="optionData.sceneCode" ></n-input>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { NSpace, NCard, NFormItem, NInput } from 'naive-ui'
import config from './config'
import { option } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
chartConfig: {
type: Object as PropType<config>,
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,104 @@
{
"day": [
{
"alarm_count": 1,
"hour": 6
},
{
"alarm_count": 1,
"hour": 7
},
{
"alarm_count": 59,
"hour": 12
},
{
"alarm_count": 71,
"hour": 13
}
],
"week": [
{
"dayOfWeek": 1,
"alarm_count": 14
},
{
"dayOfWeek": 2,
"alarm_count": 15
},
{
"dayOfWeek": 3,
"alarm_count": 132
}
],
"month": [
{
"alarm_count": 13,
"day": 17
},
{
"alarm_count": 75,
"day": 18
},
{
"alarm_count": 94,
"day": 19
},
{
"alarm_count": 34,
"day": 20
},
{
"alarm_count": 23,
"day": 21
},
{
"alarm_count": 6,
"day": 22
},
{
"alarm_count": 14,
"day": 25
},
{
"alarm_count": 15,
"day": 26
},
{
"alarm_count": 132,
"day": 27
}
],
"quarter": [
{
"alarm_count": 18,
"month": 7
},
{
"alarm_count": 406,
"month": 8
}
],
"year": [
{
"alarm_count": 10,
"month": 4
},
{
"alarm_count": 10,
"month": 5
},
{
"alarm_count": 10,
"month": 6
},
{
"alarm_count": 18,
"month": 7
},
{
"alarm_count": 406,
"month": 8
}
]
}

View File

@ -4,6 +4,7 @@ import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import { chartInitConfig } from '@/settings/designSetting'
import dataJson from './data.json'
export interface DataSourceItem {
dataname: string;
values: number[];
@ -17,7 +18,9 @@ export interface DatasType {
dataSource: DataSourceItem[];
}
const otherOption = {
titleText: '报警处置情况'
}
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
export const seriesItem = {
type: 'line',
@ -57,6 +60,34 @@ export const seriesItem = {
}
}
export const option = {
...otherOption,
sceneCode: 'T04',
dateTime: {
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
},
dataset: {
source: dataJson.dataSource[0].datavalues
},
@ -109,6 +140,6 @@ export default class Config extends PublicConfigClass implements CreateComponent
public mockData = dataJson
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 450, h: 300, zIndex: 1 }
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,6 +1,5 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`折线图-${index + 1}`" :expanded="true">
<SettingItemBox name="线条">
<SettingItem name="宽度">

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,197 @@
{
"day": {
"alertTotal": 2623,
"unprocessedAlert ": 2624,
"averageResolutionTime": 2625,
"datavalues": [
[
"时间",
"数值"
],
[
"13:00",
99
],
[
"14:00",
19
],
[
"15:00",
75
],
[
"16:00",
26
],
[
"17:00",
35
],
[
"18:00",
20
],
[
"19:00",
10
]
]
},
"week": {
"alertTotal": 12623,
"unprocessedAlert ": 12624,
"averageResolutionTime": 12625,
"datavalues": [
[
"时间",
"数值"
],
[
"13:00",
93
],
[
"14:00",
20
],
[
"15:00",
88
],
[
"16:00",
23
],
[
"17:00",
90
],
[
"18:00",
1
],
[
"19:00",
29
]
]
},
"month": {
"alertTotal": 112623,
"unprocessedAlert ": 112624,
"averageResolutionTime": 625,
"datavalues": [
[
"时间",
"数值"
],
[
"13:00",
73
],
[
"14:00",
12
],
[
"15:00",
32
],
[
"16:00",
44
],
[
"17:00",
33
],
[
"18:00",
89
],
[
"19:00",
83
]
]
},
"quarter": {
"alertTotal": 312623,
"unprocessedAlert ": 312624,
"averageResolutionTime": 312625,
"datavalues": [
[
"时间",
"数值"
],
[
"13:00",
93
],
[
"14:00",
33
],
[
"15:00",
22
],
[
"16:00",
88
],
[
"17:00",
78
],
[
"18:00",
42
],
[
"19:00",
77
]
]
},
"year": {
"alertTotal": 1112623,
"unprocessedAlert ": 1112624,
"averageResolutionTime": 3625,
"datavalues": [
[
"时间",
"数值"
],
[
"13:00",
33
],
[
"14:00",
22
],
[
"15:00",
54
],
[
"16:00",
99
],
[
"17:00",
44
],
[
"18:00",
32
],
[
"19:00",
54
]
]
}
}

View File

@ -0,0 +1,101 @@
{
"day": [
{
"alarm_count": 79,
"un_alarm_count": 45,
"alarm_hour": 12,
"avg_handle_time_seconds": 9307.5949
},
{
"alarm_count": 71,
"un_alarm_count": 45,
"alarm_hour": 13,
"avg_handle_time_seconds": 5568.1831
}
],
"week": [
{
"a": 4,
"alarm_count": 10,
"avg_handle_time_seconds": 6360,
"alarm_time_": "2025-08-25T13:31:00",
"day_of_week": 25
},
{
"a": 4,
"alarm_count": 10,
"avg_handle_time_seconds": 12300,
"alarm_time_": "2025-08-26T12:02:00",
"day_of_week": 26
},
{
"a": 4,
"alarm_count": 100,
"avg_handle_time_seconds": 6801.01,
"alarm_time_": "2025-08-27T13:00:00",
"day_of_week": 27
},
{
"a": 4,
"alarm_count": 20,
"avg_handle_time_seconds": 8760,
"alarm_time_": "2025-08-28T12:16:00",
"day_of_week": 28
}
],
"month": [
{
"alarm_count": 10,
"un_alarm_count": 45,
"alarm_date": "2025-08-25",
"avg_handle_time_seconds": 6360,
"day_of_month": 25
},
{
"alarm_count": 15,
"un_alarm_count": 45,
"alarm_date": "2025-08-26",
"avg_handle_time_seconds": 11996,
"day_of_month": 26
},
{
"alarm_count": 150,
"un_alarm_count": 45,
"alarm_date": "2025-08-27",
"avg_handle_time_seconds": 7537.6067,
"day_of_month": 27
}
],
"quarter": [
{
"alarm_count": 175,
"un_alarm_count": 45,
"month": 7,
"avg_handle_time_seconds": 7852.4629,
"quarter": 3
},
{
"alarm_count": 175,
"un_alarm_count": 45,
"month": 8,
"avg_handle_time_seconds": 7852.4629,
"quarter": 3
}
],
"year": [
{
"alarm_count": 175,
"un_alarm_count": 45,
"month": 7,
"year": 2025,
"avg_handle_time_seconds": 7852.4629
},
{
"alarm_count": 175,
"un_alarm_count": 45,
"month": 8,
"year": 2025,
"avg_handle_time_seconds": 7852.4629
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

View File

@ -1,123 +0,0 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { LineGraph02Config } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export interface DataSourceItem {
dataname: string;
values: number[];
datavalues: (string | number)[][];
}
export interface DatasType {
title: string;
names: string[];
tip: string;
dataIndex: number;
dataSource: DataSourceItem[];
}
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
export const seriesItem = {
type: 'line',
smooth: true,
symbol: 'none',
label: {
show: false,
position: 'top',
color: '#fff',
fontSize: 12
},
itemStyle: {
color: null,
borderRadius: 0
},
lineStyle: {
type: 'solid',
width: 2,
color: '#50BB9A'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(80,187,154,0.6)'
}, {
offset: 1,
color: 'rgba(80,187,154,0.3)'
}]
}
}
}
export const option = {
dataset: {
source: dataJson.dataSource[0].datavalues
},
grid: {
left: '15%',
right: '12%',
top: 9,
bottom: '25%'
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#B7BFC6'
}
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value}s',
color: "#4C535B"
},
axisLine: {
show: false
},
axisTick: {
show: false
}
},
legend: {
show: false
},
series: [seriesItem]
};
const configSet = {
titlefontWeight: 'normal',
titlefontSize: 16,
titlefontStyle: 'italic',
titlecolor: '#eee',
titlePaddingX: 0,
titlePaddingY: 0,
isShowButton: true
}
export { configSet }
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = LineGraph02Config.key
public chartConfig = cloneDeep(LineGraph02Config)
public mockData = dataJson
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@ -1,61 +0,0 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`折线图-${index + 1}`" :expanded="true">
<SettingItemBox name="线条">
<SettingItem name="宽度">
<n-input-number v-model:value="item.lineStyle.width" :min="1" :max="100" size="small"
placeholder="自动计算"></n-input-number>
</SettingItem>
<SettingItem name="类型">
<n-select v-model:value="item.lineStyle.type" size="small" :options="lineConf.lineStyle.type"></n-select>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="实心点">
<SettingItem name="大小">
<n-input-number v-model:value="item.symbolSize" :min="1" :max="100" size="small"
placeholder="自动计算"></n-input-number>
</SettingItem>
</SettingItemBox>
<setting-item-box name="标签">
<setting-item>
<n-space>
<n-switch v-model:value="item.label.show" size="small" />
<n-text>展示标签</n-text>
</n-space>
</setting-item>
<setting-item name="大小">
<n-input-number v-model:value="item.label.fontSize" size="small" :min="1"></n-input-number>
</setting-item>
<setting-item name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="item.label.color"></n-color-picker>
</setting-item>
<setting-item name="位置">
<n-select v-model:value="item.label.position" :options="[
{ label: 'top', value: 'top' },
{ label: 'left', value: 'left' },
{ label: 'right', value: 'right' },
{ label: 'bottom', value: 'bottom' }
]" />
</setting-item>
</setting-item-box>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType, computed } from 'vue'
import { lineConf } from '@/packages/chartConfiguration/echarts/index'
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<GlobalThemeJsonType>,
required: true
}
})
const seriesList = computed(() => {
return props.optionData.series
})
</script>

View File

@ -1,96 +0,0 @@
{
"title": "报警处置情况",
"names": [
"报警总数",
"未处置报警数",
"平均处置时长"
],
"tip": "报警处置效率",
"dataIndex": 0,
"dataSource": [
{
"dataname": "当日",
"values": [
2623,
2623,
2623
],
"datavalues": [
[
"时间",
"数值"
],
[
"13:00",
99
],
[
"14:00",
19
],
[
"15:00",
75
],
[
"16:00",
26
],
[
"17:00",
35
],
[
"18:00",
20
],
[
"19:00",
10
]
]
},
{
"dataname": "昨日",
"values": [
2734,
2829,
2232
],
"datavalues": [
[
"时间",
"数值"
],
[
"13:00",
12
],
[
"14:00",
22
],
[
"15:00",
23
],
[
"16:00",
3
],
[
"17:00",
68
],
[
"18:00",
56
],
[
"19:00",
45
]
]
}
]
}

View File

@ -1,17 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
// import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
// 曲线图
export const LineGraph02Config: ConfigType = {
key: 'LineGraph02',
chartKey: 'VLineGraph02',
conKey: 'VCLineGraph02',
title: '曲线图(无边框和标题)',
category: 'MyComponents',
categoryName: '自定义组件',
package: 'Charts',
chartFrame: ChartFrameEnum.ECHARTS,
image: "LineGraph02.png",
}
// 默认导出配置对象
export default LineGraph02Config

View File

@ -1,430 +0,0 @@
<template>
<div class="go-border-box">
<!-- timeshow 按钮添加点击事件和 ref -->
<div class="buttonContent">
<span class="title" :style="{
color: configSet.titlecolor,
fontSize: configSet.titlefontSize + 'px',
fontStyle: configSet.titlefontStyle,
fontWeight: configSet.titlefontWeight,
marginTop: configSet.titlePaddingY + 'px',
marginLeft: configSet.titlePaddingX + 'px'
}">{{ configData.title }}</span>
<button v-if="configSet.isShowButton" class="timeShow" @click="toggleDropdown" ref="buttonRef">
{{ configData.dataSource[selectedIndex]?.dataname || '选择数据' }}
</button>
</div>
<div v-if="showDropdown" class="dropdown-list" ref="dropdownRef">
<div v-for="(item, index) in configData.dataSource" :key="index" class="dropdown-item"
:class="{ 'is-active': index === selectedIndex }" @click="selectDataSource(index)">
{{ item.dataname }}
</div>
</div>
<div class="textContent">
<div class="textInContent">
<span class="smallText">{{ configData.names[0] }} </span>
<span class="bigText">{{ configData.dataSource[selectedIndex].values[0]?.toLocaleString('en-US')
}}</span>
</div>
<div class="textInContent">
<span class="smallText">{{ configData.names[1] }}</span>
<span class="bigText">{{ configData.dataSource[selectedIndex].values[1]?.toLocaleString('en-US')
}}</span>
</div>
<div class="textInContent">
<span class="smallText">{{ configData.names[2] }}</span>
<span class="bigText">{{ configData.dataSource[selectedIndex].values[2]?.toLocaleString('en-US')
}}</span>
</div>
</div>
<div class="chartsContent">
<span class="smallText Tips">
<img class="icon" src="./assets/icon01.png" alt="">
{{ configData.tip }}</span>
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="chartOption" :update-options="{
replaceMerge: replaceMergeArr
}" autoresize>
</v-chart>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType, computed, watch, ref, nextTick, onMounted, onUnmounted } from 'vue'
import VChart from 'vue-echarts'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart } from 'echarts/charts'
import Config, { DatasType, includes, seriesItem, configSet } from './config'
import { mergeTheme } from '@/packages/public/chart'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartDataFetch } from '@/hooks'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import isObject from 'lodash/isObject'
const props = defineProps({
themeSetting: {
type: Object,
required: true
},
themeColor: {
type: Object,
required: true
},
chartConfig: {
type: Object as PropType<Config>,
required: true
}
})
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent])
const replaceMergeArr = ref<string[]>()
const showDropdown = ref(false); // /
const selectedIndex = ref(0); //
const buttonRef = ref<HTMLElement | null>(null);
const dropdownRef = ref<HTMLElement | null>(null);
// mockData
const parseMockData = (mockData: any): DatasType => {
const DEFAULT_MOCK_DATA: DatasType = {
title: '默认标题',
names: ['项1', '项2', '项3'],
tip: "默认提示",
dataIndex: 0,
dataSource: [{
dataname: '默认数据',
values: [0, 0, 0],
datavalues: [
['维度', '数值'],
['0', 0],
['1', 0],
['2', 0]
]
}]
};
let parsedData: DatasType;
if (typeof mockData === 'string') {
try {
const tempParsed = JSON.parse(mockData);
parsedData = (typeof tempParsed === 'object' && tempParsed !== null) ? tempParsed : DEFAULT_MOCK_DATA;
} catch (e) {
console.error('解析 mockData 字符串失败:', e);
parsedData = DEFAULT_MOCK_DATA;
}
} else if (typeof mockData === 'object' && mockData !== null) {
parsedData = mockData;
} else {
parsedData = DEFAULT_MOCK_DATA;
}
if (parsedData.dataIndex === undefined || parsedData.dataIndex < 0 || parsedData.dataIndex >= parsedData.dataSource.length) {
parsedData.dataIndex = 0;
}
if (!parsedData.dataSource || parsedData.dataSource.length === 0) {
parsedData.dataSource = DEFAULT_MOCK_DATA.dataSource;
}
if (!parsedData.names || parsedData.names.length === 0) parsedData.names = DEFAULT_MOCK_DATA.names;
return parsedData;
};
const configData = computed<DatasType>(() => {
return parseMockData(props.chartConfig.mockData);
});
// mockData selectedIndex
watch(
() => props.chartConfig.mockData,
(newMockData) => {
const parsedData = parseMockData(newMockData);
selectedIndex.value = parsedData.dataIndex;
},
{ immediate: true, deep: false }
);
const chartOption = computed(() => {
const mergedOption = mergeTheme(props.chartConfig.option, props.themeSetting, includes);
const currentDataSourceItem = configData.value.dataSource[selectedIndex.value];
const currentDatavalues = currentDataSourceItem ? currentDataSourceItem.datavalues : [];
if (!mergedOption.dataset) {
mergedOption.dataset = {};
}
mergedOption.dataset.source = currentDatavalues;
return mergedOption;
});
const wrapperStyle = computed(() => ({
width: props.chartConfig.attr.w + 'px',
height: "16%"
}))
// dataset ()
watch(
() => props.chartConfig.option.dataset,
(newData: { dimensions: any }, oldData) => {
try {
if (!isObject(newData) || !('dimensions' in newData)) return
if (Array.isArray(newData?.dimensions)) {
const seriesArr = []
for (let i = 0; i < newData.dimensions.length - 1; i++) {
seriesArr.push(seriesItem)
}
replaceMergeArr.value = ['series']
props.chartConfig.option.series = seriesArr
nextTick(() => {
replaceMergeArr.value = []
})
}
} catch (error) {
console.log(error)
}
},
{
deep: false
}
)
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
});
const toggleDropdown = () => {
showDropdown.value = !showDropdown.value;
};
const selectDataSource = (index: number) => {
selectedIndex.value = index;
showDropdown.value = false;
};
const handleClickOutside = (event: MouseEvent) => {
if (showDropdown.value && dropdownRef.value && buttonRef.value &&
!dropdownRef.value.contains(event.target as Node) &&
!buttonRef.value.contains(event.target as Node)) {
showDropdown.value = false;
}
};
onMounted(() => {
document.addEventListener('click', handleClickOutside);
});
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
});
</script>
<style lang="scss" scoped>
@include go(border-box) {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
padding: 0;
}
.textContent {
padding-top: 20px;
/* background-color: brown; */
display: flex;
justify-content: space-around;
align-items: center;
width: 100%;
height: 30%;
box-sizing: border-box;
}
.textInContent {
display: flex;
flex-direction: column;
align-items: center;
}
.chartsContent {
width: 100%;
height: 80%;
/* background-color: blue; */
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
}
.textInContent .smallText {
font-size: 11px;
color: #a9a9a9;
}
.textInContent .bigText {
font-size: 18px;
font-weight: 800;
letter-spacing: 0.08em;
color: transparent;
margin-top: 0.3em;
}
.textContent :nth-child(1) .bigText {
background: linear-gradient(to right, #ffdc92, #F7BDA7);
-webkit-background-clip: text;
background-clip: text;
}
.textContent :nth-child(2) .bigText {
background: linear-gradient(to right, #86D8F3, #6CDEDF);
-webkit-background-clip: text;
background-clip: text;
}
.textContent :nth-child(3) .bigText {
background: linear-gradient(to right, #6CDFBE, #A2E9D9);
-webkit-background-clip: text;
background-clip: text;
}
.Tips {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-size: 10px;
margin-top: 9px;
margin-bottom: 8px;
margin-left: 10px;
height: 1.6em;
/* width: 8em; */
width: fit-content;
padding: 0.23em 0.4em;
color: rgb(210, 210, 210);
background-color: #273F40;
border-radius: 7px;
letter-spacing: 0.1em;
}
.icon {
margin-right: 0.5em;
}
.border {
position: relative;
}
.timeShow {
background-color: #086C67;
border-radius: 10px;
// position: absolute;
// right: 6px;
// top: 12px;
color: white;
display: inline-flex;
height: 1.5em;
align-items: center;
padding-right: 5px;
border: 0;
cursor: pointer;
z-index: 10;
white-space: nowrap;
}
.timeShow::after {
content: "";
display: inline-block;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid white;
margin-left: 5px;
}
.dropdown-list {
position: absolute;
top: 45px;
right: 6px;
background-color: #1a2a3a;
border: 1px solid #086C67;
border-radius: 5px;
z-index: 999;
min-width: 100px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
padding: 5px 0;
max-height: 200px;
overflow-y: auto;
white-space: nowrap;
}
.dropdown-item {
padding: 8px 12px;
color: white;
cursor: pointer;
font-size: 14px;
transition: background-color 0.2s ease;
&:hover {
background-color: #0d4a46;
}
&.is-active {
background-color: #086C67; //
font-weight: bold;
}
}
.buttonContent {
margin-top: 5px;
padding-right: 10px;
padding-left: 5.2em;
box-sizing: border-box;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
// background-color: #6CDEDF;
}
.buttonContent span {
font-family: 'CustomFont';
font-style: italic;
letter-spacing: 0.5px;
color: #eee;
text-shadow: 1px 3px 10px #000000;
font-size: 16px;
}
</style>

View File

@ -3,14 +3,12 @@ import { CreateComponentType } from '@/packages/index.d'
import { ParkingSceneConfig } from './index'
import dataJson from './data.json'
import { cloneDeep } from 'lodash'
import { chartInitConfig } from '@/settings/designSetting'
export const option = {
sceneCode: "",
componentIndexKey: "",
dataset: dataJson.source,
titleText: '场景分布概况',
titleColor: '#eee',
titleSize: 16,
linkColor: '#00E5FF',
linkText: '查看更多>>',
sceneNameColor: '#ccc',
@ -19,7 +17,7 @@ export const option = {
labelSize: 14,
valueColor: '#DFAB0F',
valueColor2: '#00E5FF',
valueSize: 20,
valueSize: 18,
borderColor: '#4A90E2'
}
@ -27,4 +25,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key = ParkingSceneConfig.key
public chartConfig = ParkingSceneConfig
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

File diff suppressed because one or more lines are too long

View File

@ -3,16 +3,42 @@ import { PieCenterConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
import { chartInitConfig } from '@/settings/designSetting'
export const includes = ['legend']
// 其它配置
const otherConfig = {
// 轮播动画
isCarousel: false,
titleText: "报警统计",
sceneCode: 'T04',
dateTime: {
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
},
}
const option = {
export const option = {
...otherConfig,
backgroundColor: 'transparent',
legend: {
@ -21,7 +47,7 @@ const option = {
left: '60%', // 默认更靠左一点,避免截断
top: 'center',
icon: 'rect',
showEmpty:false,
showEmpty: false,
// itemWidth: 10,
itemHeight: 8,
itemGap: 5,
@ -45,8 +71,9 @@ const option = {
center: ['30%', '48%'],
silent: true,
z: 1,
data: [{ value: 1, name: '', itemStyle: {
color: {
data: [{
value: 1, name: '', itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
@ -58,7 +85,8 @@ const option = {
{ offset: 1, color: 'rgba(200, 200, 200, 0.01)' },
]
}
} }],
}
}],
label: { show: false },
labelLine: { show: false }
},
@ -136,8 +164,7 @@ const option = {
show: false,
},
itemStyle: { shadowBlur: 12, shadowColor: 'rgba(0, 0, 0, 0.35)' }
},
data: dataJson.source
}
},
// 内部渐变装饰环(在空洞边缘,提升质感)
{
@ -210,4 +237,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key: string = PieCenterConfig.key
public chartConfig = cloneDeep(PieCenterConfig)
public option = echartOptionProfixHandle(option, includes)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,5 +1,12 @@
<template>
<div>
<collapse-item name="信息" :expanded="true">
<setting-item-box name="场景 Code " :alone="true">
<setting-item>
<n-input v-model:value="optionData.sceneCode" type="textarea" size="small"></n-input>
</setting-item>
</setting-item-box>
</collapse-item>
<!-- 基础配置可以复用PieCommon的配置面板 -->
<CollapseItem name="基础配置" :expanded="true">
<SettingItemBox name="图例">

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,7 @@ import { CreateComponentType } from '@/packages/index.d'
import { SceneDistributionConfig } from './index'
import dataJson from './data.json'
import { cloneDeep } from 'lodash'
import { chartInitConfig } from '@/settings/designSetting'
export const option = {
sceneCode: 'T06',
componentIndexKey: "a",
@ -24,4 +24,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key = SceneDistributionConfig.key
public chartConfig = SceneDistributionConfig
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

File diff suppressed because one or more lines are too long

View File

@ -2,27 +2,49 @@ import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { TopAlarmsConfig } from './index'
import dataJson from './data.json'
import { cloneDeep } from 'lodash'
import { chartInitConfig } from '@/settings/designSetting'
export const option = {
dataset: dataJson.source,
title: '未处置报警数TOP5',
titleColor: '#eee',
titleSize: 16,
rankColor: '#5AA1AD',
nameColor: '#eeeeee',
valueColor: '#eeeeee',
barColorStart: '#2f72b5',
barColorEnd: '#99C6E6',
dropdownOptions: ['当日', '当月', '当年'],
dropdownDefault: '当日',
iconColor: '#00E5FF',
letterSpacing: 0.5,
paddingX: 40,
paddingY: -5,
isShowButton: false
sceneCode: 'T05',
componentIndexKey: "a",
dateTime: {
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
},
dataset: dataJson.source,
titleText: '未处置报警数TOP5',
rankColor: '#5AA1AD',
nameColor: '#eeeeee',
valueColor: '#eeeeee',
barColorStart: '#2f72b5',
barColorEnd: '#99C6E6',
isShowButton: false
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = TopAlarmsConfig.key
public chartConfig = TopAlarmsConfig
public option = option
public key = TopAlarmsConfig.key
public chartConfig = TopAlarmsConfig
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -1,26 +1,25 @@
<template>
<div class="go-top-alarms-config">
<n-form-item label="标题">
<n-input v-model:value="option.title" />
</n-form-item>
<n-form-item label="标题大小">
<n-input-number v-model:value="option.titleSize" />
</n-form-item>
<n-form-item label="下拉选项">
<n-dynamic-input v-model:value="option.dropdownOptions" placeholder="请输入选项" />
</n-form-item>
<n-form-item label="默认选项">
<n-input v-model:value="option.dropdownDefault" />
</n-form-item>
</div>
<collapse-item name="信息" :expanded="true">
<setting-item-box name="场景 Code " :alone="true">
<setting-item>
<n-input v-model:value="optionData.sceneCode" ></n-input>
</setting-item>
</setting-item-box>
<setting-item-box name="组件 key " :alone="true">
<setting-item>
<n-input v-model:value="optionData.componentIndexKey"></n-input>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { option } from './config'
defineProps({
option: {
optionData: {
type: Object as PropType<typeof option>,
required: true
}

View File

@ -1,40 +1,21 @@
<template>
<SmallBorder class="SmallBorder">
<div class="go-top-alarms">
<div class="header">
<div class="title">
<div class="title-text">
<span :style="{
color: option.titleColor,
fontSize: option.titleSize + 'px',
marginTop: option.paddingY + 'px',
marginLeft: option.paddingX + 'px',
letterSpacing: option.letterSpacing + 'px'
}">{{ option.title }}</span>
</div>
</div>
<n-dropdown v-if='option.isShowButton' trigger="hover" :options="dropdownOptions" @select="handleSelect">
<div class="dropdown-button">
{{ selectedOption }}
<svg-icon icon-class="arrow-down" class="arrow-down-icon" />
</div>
</n-dropdown>
</div>
<div class="go-top-alarms">
<!-- <CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
@change="handleSelectChange" class="top-select" /> -->
<PublicSmallBorder :title-text="option.titleText" :select-option="option.dateTime" @change="handleSelectChange">
<div class="content">
<ul>
<li v-for="(item, index) in option.dataset" :key="index" class="alarm-item">
<li v-for="(item, index) in displayData" :key="index" class="alarm-item">
<div class="item-info">
<span class="rank" :style="{ color: option.rankColor }">
<span class="rank-icon"></span>
{{ item.rank }}
{{ index + 1 }}
</span>
<span class="name" :style="{ color: option.nameColor }">{{ item.name }}</span>
</div>
<div class="item-value">
<span class="value" :style="{ color: option.valueColor }">{{ item.value }}</span>
</div>
<div class="progress-bar-wrapper">
<div class="progress-bar">
<div class="progress" :style="{
@ -46,17 +27,19 @@
</li>
</ul>
</div>
</div>
</SmallBorder>
</PublicSmallBorder>
</div>
</template>
<script setup lang="ts">
import { ref, computed, PropType } from 'vue'
import { ref, computed, PropType, onMounted, watch } from 'vue'
import { option as configOption } from './config'
import SmallBorder from '../SmallBorder/index.vue'
import CustomSelect from './select.vue'
import axiosInstance from '@/api/axios'
import { TopAlarmsConfig } from './index'
import axios from 'axios'
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
const props = defineProps({
chartConfig: {
type: Object as PropType<{ option: typeof configOption }>,
@ -66,48 +49,120 @@ const props = defineProps({
const option = computed(() => props.chartConfig.option)
const selectedOption = ref(props.chartConfig.option.dropdownDefault)
const dropdownOptions = computed(() => {
return props.chartConfig.option.dropdownOptions.map(opt => ({
label: opt,
key: opt
}))
})
const maxValue = computed(() => {
const values = props.chartConfig.option.dataset.map(item => item.value)
return Math.max(...values, 1) // Avoid division by zero
})
// API
const displayData: any = ref([])
// API
const calculateWidth = (value: number) => {
if (maxValue.value === 0) return '0%'
return `${(value / maxValue.value) * 80}%` // Max width 80% to leave space for value
if (displayData.value.length === 0 || displayData.value[0].value === 0) {
return '0%'
}
const firstRowValue = displayData.value[0].value
return `${(value / firstRowValue) * 100}%` // value/value
}
const key = TopAlarmsConfig.key;
const getStaticData = async (key: string, componentIndexKey: string, sceneCode: string) => {
let dataTemp = option.value.dataset
try {
const response = await axios.get('/staticData/static.json');
if (response.data) {
console.log('静态数据:', response.data);
dataTemp = response.data[sceneCode]?.[key]?.[componentIndexKey];
if (!dataTemp) {
console.warn(`Data not found for sceneCode: ${sceneCode}, key: ${key}, componentIndexKey: ${componentIndexKey}`);
}
}
console.log("datatemp:", dataTemp)
} catch (err) {
console.error('获取static.json失败:', err);
}
return dataTemp
}
const handleSelect = (key: string) => {
selectedOption.value = key
// API
const fetchCorpsData = async (option: string) => {
try {
const response: any =
// await axiosInstance.get(`/awjt/screen/corpsFive/${option}/${props.chartConfig.option.sceneCode}`, { baseURL: '' })
// if (response.state === true) {
// displayData.value = response.value || []
// } else {
// console.error('API:', response)
// displayData.value = []
// }
// 使
await getStaticData(key, props.chartConfig.option.componentIndexKey, props.chartConfig.option.sceneCode);
//
if (response && response['source'] && Array.isArray(response['source']) && response['source'].length > 0) {
//
const isNewDataDifferent =
!displayData.value ||
displayData.value.length !== response['source'].length ||
JSON.stringify(displayData.value) !== JSON.stringify(response['source']);
//
if (isNewDataDifferent) {
displayData.value = response['source'];
}
}
// 使
if (response && response['titleText']) {
props.chartConfig.option.titleText = response['titleText'];
}
} catch (error) {
console.error('获取企业数据失败:', error)
displayData.value = []
}
}
// API
const handleSelectChange = async (value: any) => {
props.chartConfig.option.dateTime.selectValue = value
await fetchCorpsData(value)
}
watch(
() => [
props.chartConfig.option.sceneCode,
props.chartConfig.option.componentIndexKey,
props.chartConfig.option.dataset
],
async () => {
await fetchCorpsData('day');
},
{
immediate: true,
deep: true
}
)
//
onMounted(async () => {
const initialValue = props.chartConfig.option.dateTime.selectValue || 'day'
await fetchCorpsData(initialValue)
})
</script>
<style lang="scss" scoped>
.SmallBorder {
position: relative;
}
.go-top-alarms {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
margin-top: -10px;
// background-color: #0a162b;
padding: 15px;
box-sizing: border-box;
display: flex;
flex-direction: column;
color: #fff;
.content {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
z-index: 10;
// background-color: #00e5ff;
}
.header {
display: flex;
@ -124,11 +179,10 @@ const handleSelect = (key: string) => {
height: 35px;
display: flex;
align-items: center;
padding: 0 20px 0 20px;
padding: 2px 20px 0 20px;
margin-left: 0px;
clip-path: polygon(10% 0, 100% 0, 100% 100%, 0% 100%);
font-family: 'CustomFont';
font-style: italic;
letter-spacing: 0.5px;
@ -157,16 +211,12 @@ const handleSelect = (key: string) => {
}
.content {
flex: 1;
margin-top: -15px;
padding-right: 10px;
font-size: 12.5px;
ul {
list-style: none;
padding: 0;
margin: 0;
height: 100%;
height: 90%;
display: flex;
flex-direction: column;
justify-content: space-around;

View File

@ -3,7 +3,9 @@ import { CreateComponentType } from '@/packages/index.d'
import { WorkshopSceneConfig } from './index'
import dataJson from './data.json'
import { cloneDeep } from 'lodash'
import { chartInitConfig } from '@/settings/designSetting'
export enum FontWeightEnum {
NORMAL = '常规',
BOLD = '加粗',
}
@ -52,4 +54,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public key = WorkshopSceneConfig.key
public chartConfig = WorkshopSceneConfig
public option = cloneDeep(option)
public attr = { ...chartInitConfig, x: 0, y: 0, w: 500, h: 325, zIndex: 1 }
}

View File

@ -7,7 +7,6 @@ import { DeviceStatusConfig } from './DeviceStatus/index'
import { LineDropdownConfig } from './LineDropdown/index'
import { PieCenterConfig } from './PieCenter/index'
import { LineGraph01 } from './LineGraph01/index'
import { LineGraph02Config } from './LineGraph02/index'
import { MaxTrimConfig } from './MaxTrim/index'
import { SmallBorderConfig } from './SmallBorder/index'
@ -24,6 +23,5 @@ export default [
PieCenterConfig,
MaxTrimConfig,
LineGraph01,
LineGraph02Config,
SmallBorderConfig
]

View File

@ -0,0 +1,10 @@
<svg class="svg-background" viewBox="0 0 400 262" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect id="&#231;&#159;&#169;&#229;&#189;&#162;" opacity="0.7" x="1" y="1" width="398" height="260" rx="4"
fill="#0F121A" stroke="url(#paint0_linear_22_88)" />
<defs>
<linearGradient id="paint0_linear_22_88" x1="200" y1="1" x2="200" y2="261" gradientUnits="userSpaceOnUse">
<stop stop-color="#536D80" stop-opacity="0" />
<stop offset="1" stop-color="#485A66" />
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 581 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 176 KiB

View File

@ -0,0 +1,139 @@
<template>
<div class="go-small-border">
<div class="header flex">
<img src="./assets/Header.svg" alt="标题" class="svg ih">
<span class="title">
{{ titleText }}
</span>
<span class="right-select">
<ConsumSelect v-if="shouldShowSelect" :options="selectOption?.dataset || []"
:selectedValue="selectOption?.selectValue" @change="handleSelectChange"
:select-style-config="selectStyleConfig" />
</span>
</div>
<div class="content flex">
<img src="./assets/Background.svg" alt="" class="svg ic">
<slot></slot>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, PropType } from 'vue'
import ConsumSelect from './select.vue'
interface SelectOption {
selectValue: string
dataset: Array<{
label: string
value: string
}>
}
const props = defineProps({
titleText: {
type: String,
required: true
},
selectOption: {
type: Object as PropType<SelectOption | null>,
default: null
},
selectStyleConfig: {
default: () => ({
showAngle: true
}),
required: false
}
})
const emits = defineEmits(['change'])
const shouldShowSelect = computed(() => {
return props.selectOption !== null &&
props.selectOption !== undefined &&
Array.isArray(props.selectOption.dataset) &&
props.selectOption.dataset.length > 0
})
const handleSelectChange = (value: any) => {
emits('change', value)
}
</script>
<style scoped>
.go-small-border {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.flex {
display: flex;
}
.header {
position: relative;
height: 35px;
width: 90%;
/* background-color: antiquewhite; */
align-items: center;
padding-bottom: 2px;
justify-content: space-between;
.ih {
top: 2px;
}
.title {
margin-left: 70px;
margin-top: 9px;
z-index: 10;
white-space: nowrap;
font-family: 'CustomFont';
font-style: italic;
letter-spacing: 0.5px;
color: #eee;
text-shadow: 1px 3px 10px #000000;
font-size: 16px;
/* background-color: #eee; */
max-width: 16em;
overflow: hidden;
text-overflow: ellipsis;
/* background-color: aliceblue; */
}
.right-select {
margin-left: 70px;
margin-top: 8px;
z-index: 1001;
}
}
.content {
height: calc(100% - 30px);
/* min-height: calc(100% - 15px); */
margin-top: 2px;
width: 90%;
padding: 5px 15px;
box-sizing: border-box;
position: relative;
/* background-color: aquamarine; */
.ic {
height: 100%;
}
}
.svg {
position: absolute;
height: 99%;
width: 100%;
top: 0;
left: 0;
}
}
</style>

View File

@ -1,17 +1,15 @@
<template>
<div class="custom-select" @click="toggleDropdown">
<div class="select-display">
<div class="select-display" :style="selectStyleConfig">
<span class="select-text">{{ getSelectedLabel() }}</span>
<span class="select-arrow" :class="{ 'arrow-up': isDropdownOpen }"></span>
<span v-if="selectStyleConfig.showAngle" class="select-arrow"
:class="{ 'arrow-up': isDropdownOpen }"></span>
</div>
<div class="select-dropdown" v-show="isDropdownOpen">
<div
v-for="item in options"
:key="item.value"
class="select-option"
:class="{ 'selected': item.value === selectedValue }"
@click.stop="selectOption(item)"
>
<div class="select-dropdown" v-show="isDropdownOpen"
:style="{ backgroundColor: selectStyleConfig.backgroundColor }">
<div v-for="item in options" :key="item.value"
:style="{ backgroundColor: selectStyleConfig.backgroundColor }" class="select-option"
:class="{ 'selected': item.value === selectedValue }" @click.stop="selectOption(item)">
{{ item.label }}
</div>
</div>
@ -24,7 +22,8 @@ import { ref, onMounted, onUnmounted } from 'vue'
// props
const props = defineProps<{
options: Array<{ label: string; value: any }>
selectedValue: any
selectedValue: any,
selectStyleConfig: any
}>()
// emits
@ -89,7 +88,7 @@ onUnmounted(() => {
justify-content: space-between;
height: 22px;
padding: 0 10px;
background-color: #086C67;
background-color: rgb(48, 110, 100);
color: #fff;
border-radius: 10px;
cursor: pointer;
@ -118,7 +117,7 @@ onUnmounted(() => {
top: 100%;
left: 0;
right: 0;
background-color: #086C67;
background-color: rgb(48, 110, 100);
border-radius: 6px;
margin-top: 2px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
@ -127,10 +126,14 @@ onUnmounted(() => {
}
.select-option {
padding: 10px 12px;
padding: 10px 0px;
color: #fff;
cursor: pointer;
transition: background-color 0.2s ease;
text-align: center;
width: 100%;
text-wrap: nowrap;
background-color: #8e8e8e;
&:hover {
background-color: rgba(255, 255, 255, 0.1);
@ -151,6 +154,7 @@ onUnmounted(() => {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);