物管理前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

627 lines
41 KiB

const e="c4c1eab4-b5b7-40f3-8ed9-4f84a96a0a99",t="custom-horizontal-barchart",a="双y轴柱状图",n='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1697419854399" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8090" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M480 192H160a32 32 0 0 1 0-64h320a32 32 0 0 1 0 64z" fill="#4A8BFE" p-id="8091"></path><path d="M608 288H160a32 32 0 0 1 0-64h448a32 32 0 0 1 0 64z" fill="#3BD5B3" p-id="8092"></path><path d="M608 496H160a32 32 0 0 1 0-64h448a32 32 0 0 1 0 64z" fill="#4A8BFE" p-id="8093"></path><path d="M736 592H160a32 32 0 0 1 0-64h576a32 32 0 0 1 0 64zM864 896H160a32 32 0 0 1 0-64h704a32 32 0 0 1 0 64z" fill="#3BD5B3" p-id="8094"></path><path d="M736 800H160a32 32 0 0 1 0-64h576a32 32 0 0 1 0 64z" fill="#4A8BFE" p-id="8095"></path></svg>',o="svg",i="动态",r="图表组件",c=!1,p=!0,l="时间",s=`{"type":"page","id":"u:270584784ce1","name":"page1","asideResizor":false,"style":{"boxShadow":" 0px 0px 0px 0px transparent"},"pullRefresh":{"disabled":true},"body":[{"type":"tabs","name":"tab","tabs":[{"title":"样式","icon":"fa fa-th-large","body":[{"type":"form","title":"","name":"basicPropForm","body":[{"type":"input-text","label":"名称","name":"nodeAlias","id":"u:6b126f0520cb","size":"full","mode":"horizontal","inputControlClassName":"w-100","className":"m-b"},{"type":"input-text","label":"ID&nbsp;&nbsp;&nbsp;&nbsp;","name":"id","id":"u:6232710ac003","size":"full","mode":"horizontal","inputControlClassName":"w-100","className":"m-b"},{"type":"grid","id":"u:c605398a724c","className":"m-b","columns":[{"body":[{"type":"input-number","label":"宽度","name":"width","keyboard":true,"id":"u:dcc0c21d16f6","step":1,"suffix":"px","placeholder":"组件左边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:14cc19d6ffb0","md":6},{"body":[{"type":"input-number","label":"高度","name":"height","keyboard":true,"id":"u:cd6fdff9ca88","step":1,"suffix":"px","placeholder":"组件上边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:4931801ca9b8","md":6}]},{"type":"grid","id":"u:da449a94908a","className":"m-b","columns":[{"body":[{"type":"input-number","label":"X 轴","name":"x","keyboard":true,"id":"u:29852d093d9d","step":1,"suffix":"px","placeholder":"组件左边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:1b561d652acc","md":6},{"body":[{"type":"input-number","label":"Y 轴","name":"y","keyboard":true,"id":"u:dc8c1daed8ed","step":1,"suffix":"px","placeholder":"组件上边距","size":"full","mode":"horizontal","className":"m-b","value":200,"labelAlign":"left","precision":2,"inputClassName":"w-full","labelClassName":"w-8"}],"id":"u:9672575193ac","md":6}]},{"type":"grid","id":"u:a332a7bf83c1","className":"m-b","columns":[{"body":[{"type":"input-number","label":"旋转","name":"rotation","id":"u:f6a2dbb518f9","placeholder":"组件旋转角度","mode":"horizontal","size":"full","className":"","keyboard":true,"step":1,"suffix":"deg","value":0,"labelAlign":"left","inputClassName":"w-full"}],"id":"u:646cd98b7955","md":6},{"body":[{"type":"input-number","label":"透明","name":"opacity","id":"u:cf80f59d8d42","placeholder":"组件透明度","mode":"horizontal","size":"full","className":"m-b","keyboard":true,"step":0,"suffix":"","value":1,"inputClassName":"w-full","precision":2}],"id":"u:51ddf54ac749","md":6}],"gap":""},{"type":"grid","columns":[],"id":"u:235f153e5ad5","className":"m-b"},{"type":"grid","columns":[{"body":[{"type":"input-color","label":"名称颜色","name":"nameColor","id":"u:10e95c495126","format":"hex","mode":"horizontal","inputClassName":"w-full myColorPick"}],"id":"u:1149609dc255"},{"body":[{"type":"input-color","label":"值颜色","name":"valueColor","id":"u:d70b22d36777","format":"hex","mode":"horizontal","body":[{"type":"input-color","label":"值文字颜色","name":"valueColor","id":"u:c1672ee149ab","format":"hex"}],"inputClassName":"w-full"}],"id":"u:27e615487cc8"}],"id":"u:5d2e79771eae","className":"m-b"},{"type":"grid","columns":[{"body":[{"type":"input-color","label":"背景","name":"maxValueBg","id":"u:2b74adce8f1e","format":"hex","mode":"horizontal","inputClassName":"w-full"}],"id":"u:d54c95f52bc9"},{"id":"u:05cb60c9ebc4"}],"id":"u:7acfd75cca7f","className":"m-b"},{"type":"input-text","label":"前景色","name":"valueFrontBg","id":"u:849403a159e9","editorState":"default","mode":"horizontal"},{"type":"fieldset","title":"提示框","collapsable":true,"body":[{"type":"grid","columns":[{"body":[{"type":"input-color","label":"颜色","name":"tooltipColor","id":"u:eb88b98c9221","format":"hex","mode":"horizontal","inputClassName":"w-full"}],"id":"u:dd569956cbc9"},{"body":[{"type":"input-color","label":"背景","name":"tooltipBack","id":"u:ed476d20f943","format":"hex","mode":"horizontal","inputClassName":"w-full"}],"id":"u:a2e7e7647912"}],"id":"u:61aac71ef739","className":"m-b"}],"id":"u:014e1f53b401"},{"type":"input-color","label":"边框颜色","name":"tooltipBorderColor","id":"u:d10b428af8a4","format":"hex","mode":"horizontal","inputClassName":"w-full"}],"id":"u:a5ebe5f02407","submitText":"","onEvent":{"change":{"weight":0,"actions":[]}},"debug":false,"mode":"normal","panelClassName":"p","labelAlign":"left","className":"","wrapWithPanel":true}],"id":"u:c309ae58472c","className":"p-none no-border"},{"title":"交互","icon":"fa fa-calendar-minus-o","body":[{"type":"service","body":[{"type":"collapse","key":"1","active":true,"header":"常规","body":[{"type":"service","id":"u:6cb6d200ede2","data":{"dataPoint":"","compareType":"","conditionVariables":[],"defaultValue":"","unit":""},"body":[{"type":"input-text","label":"数据点","name":"dataPoint","id":"normalDataPoint","multiple":false,"mode":"horizontal","size":"full","onEvent":{"focus":{"weight":0,"actions":[{"actionType":"dialog","dialog":{"type":"dialog","title":"请配置需要绑定的数据点","body":[{"type":"tabs","tabs":[{"title":"常规数据点","body":[{"type":"form","title":"","body":[{"type":"select","label":"数据源","name":"dataSource","id":"u:c273f087b8ed","mode":"horizontal","multiple":false,"size":"md","horizontal":{"leftFixed":"sm"},"source":"\${apiDtoList || thingApiDTOList}","labelField":"name","valueField":"id","onEvent":{"change":{"actions":[{"actionType":"reload","componentId":"u:1cdb908c23a8"},{"actionType":"custom","script":"if (!event.data.value) { doAction({'actionType': 'setValue', 'componentId': 'u:1cdb908c23a8', 'args': {'value': ''} });\\r\\n doAction({'actionType': 'setValue', 'componentId': 'u:8147daea685d', 'args': {'value': ''} }); }"}]}},"clearable":true,"actionType":"change","target":"u:1cdb908c23a8"},{"type":"combo","label":"设备属性","name":"deviceAttrs","id":"u:98559a2dd514","multiple":false,"mode":"horizontal","size":"full","horizontal":{"leftFixed":"sm"},"items":[{"type":"input-table","label":false,"id":"u:41dfc35c368c","name":"table","strictMode":false,"needConfirm":false,"addable":true,"removable":true,"columns":[{"type":"input-text","label":"序号","id":"u:434e22030bc6","name":"num","size":"sm","mode":"horizontal","quickEdit":{"mode":"popOver","id":"u:c6a294f5c93a"},"horizontal":{"left":2,"right":10},"placeholder":"例:A/B/C/AA/BB","width":200},{"type":"select","name":"devices","id":"u:1cdb908c23a8","label":"设备","multiple":false,"mode":"horizontal","quickEdit":true,"size":"sm","source":{"url":"/thing/v2/api/telemetryById?id=\${dataSource}","method":"get","messages":{},"headers":{"token":"\${myToken}","tenantCode":"\${myTenantCode}","companyId":"\${myCompanyId}"},"adaptor":"if (payload && payload.data && payload.data.result) {console.log('payload.data.result', payload.data.result); \\r\\n const list = []\\r\\n const devices = payload.data.result.info \\r\\n for (const key in devices) {\\r\\n const device_info = devices[key] \\r\\n list.push({\\r\\n label: device_info.entityName,\\r\\n value: device_info.entityId,\\r\\n deviceCode: device_info.entityCode,\\r\\n deviceInfo: device_info,\\r\\n attrs: device_info.attrs })\\r\\n }\\r\\n payload.data = list;\\r\\n return payload\\r\\n}","sendOn":"this.dataSource"},"onEvent":{"change":{"actions":[{"actionType":"custom","script":"if (!event.data.value) { doAction({'actionType': 'setValue', 'componentId': 'u:8147daea685d', 'args': {'value': ''} }); }"}]}},"responseData":{"&":"$$","list":"\${items}"},"clearable":true,"horizontal":{"left":2,"right":10},"checkAll":false},{"type":"select","name":"dataPoint","id":"u:8147daea685d","label":"数据点","multiple":false,"quickEdit":true,"mode":"horizontal","size":"sm","source":{"url":"/thing/v2/api/callDict?id=\${dataSource}&entityId=\${devices}","method":"get","messages":{},"headers":{"token":"\${myToken}","tenantCode":"\${myTenantCode}","companyId":"\${myCompanyId}"},"sendOn":"this.dataSource && this.devices","adaptor":"const list = payload.data.map(item => {\\r\\n item.dictName = item.dictName + ' - ' + item.dictCode\\r\\n return item\\r\\n})\\r\\npayload.data = list;\\r\\nreturn payload"},"labelField":"dictName","valueField":"dictCode","checkAll":false,"horizontal":{"left":2,"right":10},"overlay":{"width":"350px"},"searchable":true}]}],"strictMode":true,"syncFields":[],"tabsMode":false,"canAccessSuperData":true,"inputClassName":"w-full","className":"m-b-sm"},{"type":"checkbox","label":"数据处理","name":"enableDataHandle","id":"u:034ca60f2135","mode":"horizontal","horizontal":{"leftFixed":"normal"},"option":""},{"type":"combo","id":"u:a06125153fa6","name":"calcRules","label":"计算规则","mode":"horizontal","visibleOn":"this.enableDataHandle","multiple":true,"items":[{"name":"formular","label":"计算公式","type":"input-text","id":"u:318a7f0c6449","placeholder":"例: (A + B) / C","width":"50%","size":"full"},{"name":"resultAttr","label":"计算结果属性","type":"input-text","id":"u:1e6e491ccbaa","placeholder":"例:A8、B、C...","width":"50%"}],"strictMode":true,"syncFields":[],"hidden":false,"inputClassName":"w-full","multiLine":false,"className":"calcRules"},{"type":"input-text","label":"唯一数据点","name":"uniquePoint","id":"u:3b257b599c19","mode":"horizontal","visibleOn":"this.enableDataHandle","labelRemark":{"icon":"fa fa-question-circle","trigger":["hover"],"className":"Remark--warning","placement":"top","title":"场景:","content":"当有数据处理,并且只需绑定一个数据点作为 【实时/立即/最新数据】时,请填写所需数据点的序号或计算结果属性。"},"inputControlClassName":"m-b"}],"id":"u:51f0e51abd7c","data":{"attrs":[],"deviceCode":"\${deviceCode || ''}","devices":"\${devices || ''}","dataPoint":"\${dataPoint || ''}","dataSource":"\${dataSource || ''}","deviceAttrs":"\${deviceAttrs || []}"},"submitText":"","onEvent":{"inited":{"actions":{"actionType":"custom","script":"if(event.data.devices && event.data.dataPoint && event.data.deviceAttrs.length === 0) { const dataPoints = event.data.dataPoint.split(','); const newDeviceAttrs = dataPoints.map((point, idx) => ({ num: String.fromCharCode(65+idx), devices: event.data.devices, dataPoint: point }) ); doAction({ 'actionType': 'setValue', 'componentId': 'u:51f0e51abd7c', 'args': { value: {deviceAttrs: { table: newDeviceAttrs } }} }); }"}}}}],"id":"u:5505e7ef7cab"},{"title":"虚拟变量","body":[{"type":"tpl","tpl":"暂时无虚拟变量可配置","wrapperComponent":"","inline":false,"id":"u:722592249b31"}],"id":"u:b739cc6a6ed7"}],"id":"u:3b446450d643"}],"showCloseButton":true,"showErrorMsg":true,"showLoading":true,"id":"u:f46c2439c983","data":{"&":"\${dataPoint | toJson}","apiDtoList":"\${thingApiDTOList}","myToken":"\${myToken}","myTenantCode":"\${myTenantCode}","myCompanyId":"\${myCompanyId}"},"onEvent":{"confirm":{"actions":[{"actionType":"custom","script":"const tableData = event.data.deviceAttrs.table; let devices = ''; let dataPoint = ''; if(tableData) { tableData.forEach(item => { devices += (item.devices + ',');dataPoint += (item.dataPoint + ','); });}; if(tableData && tableData.length > 0) { devices = devices.substring(0, devices.length - 1); dataPoint = dataPoint.substring(0, dataPoint.length - 1); const newValue = {...event.data, devices: devices, dataPoint: dataPoint, dataSource: event.data.dataSource} ; doAction({ 'componentId': 'normalDataPoint', 'actionType': 'setValue', 'args': { value: JSON.stringify(newValue) } }) } else {doAction({ 'componentId': 'normalDataPoint', 'actionType': 'setValue', 'args': { value: JSON.stringify(event.data) } }) };"}]}},"closeOnEsc":false,"size":"lg"}}]}},"className":"w-full m-b-sm","inputClassName":"w-full","clearable":true},{"type":"input-text","label":"默认值","clearable":true,"name":"defaultValue","id":"u:13ccbc565f5e","mode":"horizontal","size":"full","inputControlClassName":"mb-sm","labelClassName":"mb-sm","className":"m-b-sm"},{"type":"input-text","label":"单位 &nbsp&nbsp","name":"unit","id":"u:0f606558e8c7","mode":"horizontal","size":"full","className":"m-b-sm"},{"type":"input-number","label":"渲染间隔","name":"renderInterval","keyboard":true,"id":"u:3f7cb08b0e2b","step":1,"mode":"horizontal","unitOptions":["ms"],"min":30000,"labelRemark":{"icon":"fa fa-question-circle","trigger":["hover"],"className":"Remark--warning","placement":"top","content":"最低渲染间隔为30秒","title":"提示:"}},{"type":"switch","label":"开启渲染间隔","option":"","name":"renderIntervalEnabled","falseValue":false,"trueValue":true,"id":"u:457aaa1b64ed","value":true,"mode":"horizontal","labelRemark":{"icon":"fa fa-question-circle","trigger":["hover"],"className":"Remark--warning","placement":"top","title":"提示:","content":"关闭渲染间隔,将会渲染socket 推送的实时数据,意味着此时配置的数据源api如果不是 “最新” 值,将不会渲染。并且关闭渲染间隔后,需保存并刷新看板,才能看到效果。"}},{"type":"radios","label":"数据展示","name":"dataShowTypes","options":[{"label":"单个物单个属性","value":"oneThingOneAttr"},{"label":"单个物多个属性","value":"oneThingManyAttr"},{"label":"多个物多个属性","value":"manyThingManyAttr"},{"label":"多个物一个属性","value":"manyThingOneAttr"}],"id":"u:b8aeecd9e52f","mode":"horizontal","inputClassName":"w-full","itemClassName":"w-full","labelRemark":{"icon":"fa fa-question-circle","trigger":["hover"],"className":"Remark--warning","placement":"top","content":"请确保数据点的选择与数据展示方式一致"},"onEvent":{"change":{"actions":[{"componentId":"u:0fc48eacd2a4","actionType":"setValue","args":{"value":""}}]}}},{"type":"select","label":"y轴名称展示","name":"yAxisNameType","options":[{"label":"物名称","value":"thingName","disabledOn":"this.dataShowTypes === 'oneThingManyAttr' || this.dataShowTypes === 'manyThingManyAttr' "},{"label":"物编码","value":"thingCode","disabledOn":"this.dataShowTypes === 'oneThingManyAttr' || this.dataShowTypes === 'manyThingManyAttr'"},{"label":"属性名称","value":"attrName","disabledOn":"this.dataShowTypes === 'manyThingManyAttr' || this.dataShowTypes === 'manyThingOneAttr'"},{"label":"属性编码","value":"attrCode","disabledOn":"this.dataShowTypes === 'manyThingManyAttr' || this.dataShowTypes === 'manyThingOneAttr'"},{"label":"物名称 + 属性名称","value":"thingNameAttrName"},{"label":"物编码 + 属性编码","value":"thingCodeAttrCode"}],"id":"u:0fc48eacd2a4","multiple":false,"mode":"horizontal","inputClassName":"w-full","value":"attrName"}],"name":"normalService","className":"p-none"}],"id":"u:7b021709614e","headingClassName":"p-sm bg-white b-b b-light","className":"m-b r-3x","bodyClassName":"p-none"}],"id":"u:3eb6b9a42dcb","name":"dynamicService"}],"id":"u:043251c106af","className":"p-sm"},{"title":"脚本解析","icon":"fa fa-star","body":[{"type":"flex","id":"u:edef8e21c1e3","justify":"flex-end","items":[{"type":"button","id":"u:f6d8d837a48d","label":"导入","onEvent":{"click":{"actions":[]}},"icon":"fa fa-download","level":"primary","className":"mr-2"},{"type":"button","id":"u:23f988f98a28","label":"保存","onEvent":{"click":{"actions":[{"actionType":"setValue","componentId":"u:6dc2a126004a","args":{"value":{"save":true}}}]}},"icon":"fa fa-save"}]},{"type":"service","id":"u:6dc2a126004a","body":[{"type":"tpl","id":"u:c77724a2f3b3","tpl":"function (context, service, nodeId) {","inline":true,"wrapperComponent":"","style":{"fontFamily":"","fontSize":16}},{"type":"editor","label":"","name":"script","id":"u:55ceb80e58a7","language":"javascript","size":"xxl","className":"m-b-none","onEvent":{"focus":{"actions":[{"actionType":"setValue","componentId":"u:6dc2a126004a","args":{"value":{"save":false}}}]}},"description":"参数提示:\\n1. context 是整个看板上下文,可以获取看板所有元素节点和连线节点,也可以访问 context.globalDatas 获取全局socket 数据。 \\n2. service 是 Ajax 请求服务。\\n3. nodeId 是节点 id . \\n4. 如果返回一个函数,则可以当socket 数据更新时,调用此函数,此函数入参分别是 context, service, nodeId, globalDatas ;,以满足多样化的业务需求。"},{"type":"tpl","tpl":"}","inline":true,"wrapperComponent":"","id":"u:fa21aebb859b","style":{"fontFamily":"","fontSize":16}}],"name":"scriptService","data":{"script":"","save":false},"className":"text-left"}],"id":"u:dc8d331cbe5e"}],"id":"u:178107498966","tabsMode":"radio","className":"p-none w-full","contentClassName":"p-none"}],"className":""}`,d={jsPlugin:'[{"url":"./logicflow/core.umd.js","isModule":false,"disabled":true},{"url":"./logicflow/extensionLib/NodeResize.js","isModule":false,"disabled":true},{"url":"./plugins/echarts.min.js","isModule":false,"disabled":false}]',json:`{
"nodes": [
{
"id": "26f2607a-db35-4f34-8653-a4fc11fafc7f",
"type": "custom-horizontal-barchart",
"x": 200,
"y": 200,
"text": {
"value": "",
"x": 200,
"y": 200
},
"properties": {
"id": "26f2607a-db35-4f34-8653-a4fc11fafc7f",
"width": 500,
"height": 200,
"x": 200,
"y": 200,
"rotation": 0,
"opacity": 1,
"codeConfig": "return option",
"nodeAlias": "双轴柱图",
"showDefaultValue": false,
"showUnit": false,
"valueColor": "#000000",
"fontSize": 12,
"maxValueBg": "#181f44",
"valueFrontBg": "linear-gradient(to right, rgb(57,89,255,1), rgb(46,200,207,1))",
"nameColor": "#000000",
"itemColor": "#000000",
"tooltipColor": "#ffffff",
"tooltipBack": "#3d2fd7",
"tooltipBorderColor": "#3d2fd7",
"dynamic": {
"normalData": {
"dataPoint": "",
"compareType": "",
"conditionVariables": [],
"defaultValue": "",
"unit": "",
"renderIntervalEnabled": true,
"yAxisNameType": "",
"dataShowTypes": "oneThingManyAttr",
"radios": "oneThingManyAttr"
}
}
}
}
]
}`,javascript:`const { createApp, createVNode, render } = Vue;
const app = createApp({})
const timeArr = new Array(24).fill('');
const totals = [];
timeArr.forEach((i, index) => { const t = window.dayjs().hour(index).valueOf(); totals.push({ val: Math.random(1000) * 100, ts: t, attrKey: "A29" }) });
const defaultSocketValue = []
const HoriBarChart = {
template: \`<div :id="chartId" :style="getStyle" class="horibar-chart-box">
<div v-for="item in totalDatas" class="horibar-item-row" :style="getRowStyle(totalDatas.length)" @mouseenter="mouseEnterHandler" @mousemove="(e) => hoverTooltipDebounced(e, item)" @mouseleave="mouseLeaveHandler">
<div class="horibar-name" :style="{color: nameColor}">{{item.name}}</div>
<div class="horibar-value-wrapper">
<div class="horibar-value" :style="getValueStyle(item.value, item.maxVal, valueFrontBg)"></div>
<div class="horibar-bg" :style="getBgStyle"></div>
</div>
<div class="horibar-value-show" :style="{color: valueColor}">{{item.formatVal}}</div>
</div>
<div v-show="showTooltip" :style="getTooltipStyle" class="hori-tooltip">
<span>{{currentRow.name}} :</span>
<span>&nbsp;{{currentRow.value}}</span>
<span>&nbsp;&nbsp;{{ unit }}</span>
</div>
</div>\`,
props: {
chartId: {
type: String,
default: ''
},
historyDatas: {
type: Array,
default: () => []
},
width: {
type: Number,
default: 350
},
height: {
type: Number,
default: 150
},
codeConfig: {
type: String,
default: ''
},
nameColor: {
type: String,
default: ''
},
valueColor: {
type: String,
default: ''
},
valueFrontBg: {
type: String,
default: ''
},
maxValueBg: {
type: String,
default: ''
},
tooltipColor: {
type: String,
default: ''
},
tooltipBack: {
type: String,
default: ''
},
tooltipBorderColor: {
type: String,
default: ''
},
unit: {
type: String,
default: ''
},
dataShowTypes: {
type: String,
default: ''
},
yAxisNameType: {
type: String,
default: ''
},
apiid: {
type: String,
default: ''
}
},
computed: {
getStyle() {
return {
width: \`\${this.width}px\`,
height: \`\${this.height}px\`
}
},
getRowStyle: () => (len) => {
const ratio = 1 / (len + 3) * len / len * 100 + '%'
return {
flex: \`0 0 \${ratio}\`,
}
},
getValueStyle: () => (val, maxVal, valueFrontBg) => {
return {
width: val / maxVal * 100 + '%',
background: valueFrontBg
}
},
getBgStyle() {
return {
'background-color': this.maxValueBg
}
},
},
setup(props) {
const { onMounted, computed, nextTick, ref, toRefs, watch, reactive } = Vue;
const { historyDatas, codeConfig, dataShowTypes, yAxisNameType, apiid } = toRefs(props)
const filterDatas = (api, yAxisName, dataArr, datas) => {
if (api) {
const infos = window.totalDeviceInfos[api];
const thing = infos[datas[0].thingCode];
const attrName = thing.attrs[datas[0].attrKey].name
if (dataShowTypes.value === 'oneThingOneAttr') {
switch (yAxisNameType.value) {
case "thingName":
yAxisName.push(thing.entityName);
dataArr.push(datas[0].val);
return;
case "thingCode":
yAxisName.push(datas[0].thingCode);
dataArr.push(datas[0].val);
return;
case "attrName":
yAxisName.push(attrName);
dataArr.push(datas[0].val);
return;
case "attrCode":
yAxisName.push(datas[0].attrKey);
dataArr.push(datas[0].val);
return;
case "thingNameAttrName":
const thingName = thing.entityName;
yAxisName.push(thingName + ' ' + attrName);
dataArr.push(datas[0].val);
return;
case "thingCodeAttrCode":
const thingCode = datas[0].thingCode;
const attrCode = datas[0].attrKey;
yAxisName.push(thingCode + ' ' + attrCode);
dataArr.push(datas[0].val);
return;
}
} else if (dataShowTypes.value === 'oneThingManyAttr') {
const datasGrouped = window._.groupBy(datas, 'attrKey');
switch (yAxisNameType.value) {
case "attrName":
for (const key in datasGrouped) {
const serieData = datasGrouped[key];
const thing = infos[serieData[0].thingCode];
const attrName = thing.attrs[serieData[0].attrKey].name
yAxisName.push(attrName);
dataArr.push(serieData[0].val);
}
return;
case "attrCode":
for (const key in datasGrouped) {
const serieData = datasGrouped[key];
yAxisName.push(serieData[0].attrKey);
dataArr.push(serieData[0].val);
}
return;
case "thingNameAttrName":
for (const key in datasGrouped) {
const serieData = datasGrouped[key];
const thing = infos[serieData[0].thingCode];
const thingName = thing.entityName;
const attrName = thing.attrs[serieData[0].attrKey].name
yAxisName.push(thingName + ' ' + attrName);
dataArr.push(serieData[0].val);
}
return;
case "thingCodeAttrCode":
for (const key in datasGrouped) {
const serieData = datasGrouped[key];
const thingCode = serieData[0].thingCode;
const attrCode = serieData[0].attrKey;
yAxisName.push(thingCode + ' ' + attrCode);
dataArr.push(serieData[0].val);
}
return;
}
} else if (dataShowTypes.value === 'manyThingManyAttr') {
switch (yAxisNameType.value) {
case "thingNameAttrName":
datas.forEach((val) => {
const thing = infos[val.thingCode];
const thingName = thing.entityName;
const attrName = thing.attrs[val.attrKey].name
yAxisName.push(thingName + ' ' + attrName);
dataArr.push(val.val);
})
return;
case "thingCodeAttrCode":
datas.forEach((val) => {
yAxisName.push(val.thingCode + ' ' + val.attrKey);
dataArr.push(val.val);
})
return;
}
} else if (dataShowTypes.value === 'manyThingOneAttr') {
const datasGrouped = window._.groupBy(datas, 'thingCode');
switch (yAxisNameType.value) {
case "thingName":
for (const key in datasGrouped) {
const serieData = datasGrouped[key];
const thing = infos[serieData[0].thingCode];
yAxisName.push(thing.entityName);
dataArr.push(serieData[0].val);
}
return;
case "thingCode":
for (const key in datasGrouped) {
const serieData = datasGrouped[key];
yAxisName.push(key);
dataArr.push(serieData[0].val);
}
return;
case "thingNameAttrName":
for (const key in datasGrouped) {
const serieData = datasGrouped[key];
const thing = infos[serieData[0].thingCode];
const thingName = thing.entityName;
const attrName = thing.attrs[serieData[0].attrKey].name
yAxisName.push(thingName + ' ' + attrName);
dataArr.push(serieData[0].val);
}
return;
case "thingCodeAttrCode":
for (const key in datasGrouped) {
const serieData = datasGrouped[key];
const thingCode = serieData[0].thingCode;
const attrCode = serieData[0].attrKey;
yAxisName.push(thingCode + ' ' + attrCode);
dataArr.push(serieData[0].val);
}
return;
}
}
}
}
const totalDatas = ref([]);
const totalBackground = ref([]);
const initChart = (datas) => {
// 基于准备好的dom,初始化echarts实例
if (datas) {
let dataArr = [];
let databackground = [];
let yAxisName = [];
if (datas.length > 0) {
filterDatas(apiid.value, yAxisName, dataArr, datas);
const maxVal = Math.max(...dataArr);
databackground = dataArr.map(() => maxVal);
} else {
dataArr = [50000000, 22000000, 10000000, 5000000, 1];
databackground = [50000000, 50000000, 50000000, 50000000, 50000000];
yAxisName = ['大米', '玉米', '蔬菜', '鸡蛋', '坚果'];
}
totalDatas.value = dataArr.map((item, index) => {
const formatVal = dataArr[index] > 10000 ? (dataArr[index] / 10000).toFixed(2) + '万' : dataArr[index];
return {
name: yAxisName[index],
value: dataArr[index],
formatVal,
maxVal: databackground[index]
}
})
totalBackground.value = databackground;
setTimeout(() => {
const bgs = document.getElementById(props.chartId).querySelectorAll('.horibar-bg');
bgs.forEach((bg) => {
bg.style.transform = 'scaleX(1)';
})
const vals = document.getElementById(props.chartId).querySelectorAll('.horibar-value');
vals.forEach((val) => {
val.style.transform = 'scaleX(1)';
})
}, 100)
}
}
watch(historyDatas, (val) => {
if (val) {
nextTick(() => {
initChart(val);
})
}
}, {
immediate: true
})
const currentRow = ref({});
const showTooltip = ref(false);
const tooltipPos = ref({
top: -1000,
left: -1000,
})
let parentX = 0;
let parentY = 0;
onMounted(() => {
nextTick(() => {
const parentDom = document.getElementById(props.chartId);
const { x, y } = parentDom.getBoundingClientRect();
parentX = x;
parentY = y;
})
})
const hoverTooltip = (e, row) => {
if (!showTooltip.value) {
showTooltip.value = true;
};
const parentDom = document.getElementById(props.chartId);
const { height } = parentDom.querySelector('.hori-tooltip').getBoundingClientRect();
let hovertipHeight = height;
currentRow.value = row;
const isCloseBottom = Math.abs(props.height - (e.y - parentY)) < hovertipHeight;
tooltipPos.value = {
left: e.x - parentX,
top: isCloseBottom ? e.y - parentY - hovertipHeight : e.y - parentY,
}
}
const hoverTooltipDebounced = window._.throttle(hoverTooltip, 500);
const getTooltipStyle = computed(() => {
const pos = tooltipPos.value;
return {
position: 'absolute',
top: pos.top + 'px',
left: pos.left + 'px',
padding: '15px 15px',
color: props.tooltipColor,
'background-color': props.tooltipBack,
border: \`1px solid \${props.tooltipBorderColor}\`,
'border-radius': '5px',
'z-index': 9999,
transition: 'all 0.25s ease-in-out'
}
})
const mouseEnterHandler = window._.throttle(() => {
showTooltip.value = true;
}, 200)
const mouseLeaveHandler = window._.throttle(() => {
showTooltip.value = false;
}, 200)
return reactive({
totalDatas,
totalBackground,
hoverTooltipDebounced,
currentRow,
tooltipPos,
showTooltip,
getTooltipStyle,
mouseEnterHandler,
mouseLeaveHandler,
})
}
}
class CustomHoriBarChartNode extends HtmlResize.view {
chartRendered = false
historyDatas = []
oldProperties = {}
setHtml(rootEl) {
if (!rootEl) return;
const { properties, width, height, } = this.props.model;
const { nodeAlias, codeConfig, nameColor, valueColor, valueFrontBg, maxValueBg, tooltipColor, tooltipBack, tooltipBorderColor } = properties;
const { normalData } = properties.dynamic || {};
const { unit, dataShowTypes, yAxisNameType } = normalData || {};
const el = document.createElement('div');
rootEl.innerHTML = '';
const instance = createVNode(HoriBarChart, {
name: nodeAlias,
chartId: \`horibar-\${properties.id}\`,
historyDatas: this.historyDatas,
width,
height,
codeConfig,
nameColor, valueColor, valueFrontBg, maxValueBg,
tooltipColor, tooltipBack, tooltipBorderColor, unit,
dataShowTypes, yAxisNameType,
apiid: properties.apiid
})
instance.appContext = app._context
render(instance, el)
rootEl.appendChild(el);
}
sameProps(properties) {
const isSame = window._.isEqual(this.oldProperties, properties);
if (isSame) return true;
this.oldProperties = properties;
return false
}
filterHistoryData(thingCodeArr, dataPointArr, apiid, renderIntervalEnabled) {
if (dataPointArr && dataPointArr.length > 0) {
let datas = []
if (renderIntervalEnabled) {
datas = window.totalHistoryDatas[apiid];
} else {
if (window.globalDashboardDatas[apiid]) {
datas = window.globalDashboardDatas[apiid].values;
}
}
if (datas && datas.length > 0) {
const gotValues = datas.filter((val) => thingCodeArr.includes(val.thingCode) && dataPointArr.includes(val.attrKey))
this.historyDatas = gotValues
this.chartRendered = true;
}
}
}
// 生命周期 支持重写内容, 但格式需一致
shouldUpdate() {
const { properties } = this.props.model;
const { apiid } = properties;
const { normalData } = properties.dynamic || {};
const { thingCodeArr, dataPointArr, defaultValue } = normalData || {}
if (normalData && !normalData.dataPoint && !normalData.defaultValue) {
this.historyDatas = defaultSocketValue;
return true
} else if (normalData && !normalData.dataPoint && normalData.defaultValue) {
this.historyDatas = JSON.parse(defaultValue);
return true
}
const propertiesBack = window._.cloneDeep(properties);
if (propertiesBack.dynamic.normalData) {
propertiesBack.dynamic.normalData.defaultValue = '';
if (this.sameProps(propertiesBack) && this.chartRendered) {
return false
}
if (dataPointArr && apiid && !this.chartRendered) {
this.filterHistoryData(thingCodeArr, dataPointArr, apiid, normalData.renderIntervalEnabled);
return true;
}
}
return true;
}
updateHtml() {
this.setHtml(this.rootEl);
}
componentDidMount() {
// 防止拖动时候频繁渲染图表
this.updateHtmlDebounced = window._.debounce(this.updateHtml.bind(this), 500);
const { properties } = this.props.model;
const { normalData } = properties.dynamic || {};
const { renderInterval, dataPointArr, thingCodeArr } = normalData || {};
if (this.shouldUpdate()) {
this.setHtml(this.rootEl);
}
let inters = parseInt(renderInterval || '30000')
if (normalData && !normalData.renderIntervalEnabled) {
inters = 1000
}
setInterval(() => {
if (window.totalHistoryDatas[properties.apiid]) {
this.filterHistoryData(thingCodeArr, dataPointArr, properties.apiid, normalData.renderIntervalEnabled);
this.setHtml(this.rootEl);
}
}, inters)
}
componentDidUpdate() {
if (this.shouldUpdate()) {
this.updateHtmlDebounced();
}
}
}
class CustomHoriBarChartModel extends HtmlResize.model {
initNodeData(data) {
// 自定义组件,需最开始重置一下text 。
data.text = {
value: "",
x: data.x,
y: data.y,
};
super.initNodeData(data);
const { properties } = this;
this.width = properties.width || 80;
this.height = properties.height || 35;
this.text.editable = false; // 不允许文本被编辑
}
setAttributes() {
// 自定义组件需重置 text
const { x, y, properties } = this;
const { textHorizontalMove = 0, textVerticalMove = 0 } = properties;
this.text = {
...this.text,
x: x + textHorizontalMove,
y: y + textVerticalMove,
value: "",
}
}
}
lf.register({
type: 'custom-horizontal-barchart',
view: CustomHoriBarChartNode,
model: CustomHoriBarChartModel,
})`,css:`.horibar-chart-box {\r
display: flex;\r
flex-direction: column;\r
justify-content: space-between;\r
position: relative;\r
}\r
.horibar-chart-box .horibar-item-row {\r
display: flex;\r
}\r
.horibar-chart-box .horibar-item-row .horibar-name {\r
flex: 0 0 auto;\r
overflow: hidden;\r
text-overflow: ellipsis;\r
white-space: nowrap;\r
display: flex;\r
align-items: center;\r
padding: 0 5px;\r
}\r
.horibar-chart-box .horibar-item-row .horibar-value-wrapper {\r
flex: 1;\r
position: relative;\r
}\r
.horibar-chart-box .horibar-item-row .horibar-value-wrapper .horibar-value {\r
position: absolute;\r
top: 0;\r
bottom: 0;\r
height: 100%;\r
z-index: 1;\r
border-radius: 20px;\r
transform: scaleX(0);\r
transform-origin: 0%;\r
transition: all 0.35s ease-in-out;\r
}\r
.horibar-chart-box .horibar-item-row .horibar-value-wrapper .horibar-bg {\r
width: 100%;\r
height: 100%;\r
border-radius: 20px;\r
transform: scaleX(0);\r
transform-origin: 0%;\r
transition: all 0.2s ease-in-out;\r
}\r
\r
.horibar-chart-box .horibar-item-row .horibar-value-show {\r
flex: 0 0 70px;\r
overflow: hidden;\r
text-overflow: ellipsis;\r
white-space: nowrap;\r
display: flex;\r
align-items: center;\r
padding-left: 5px;\r
}`,fakeData:""},u={id:e,name:t,aliasName:a,image:n,imageType:o,groupName:i,groupType:r,isRemote:!1,isDefault:!0,sectionType:l,config:s,files:d};export{a as aliasName,s as config,u as default,d as files,i as groupName,r as groupType,e as id,n as image,o as imageType,p as isDefault,c as isRemote,t as name,l as sectionType};