NEZ-1294 feat: 初始chart-clock 时钟组件开发

This commit is contained in:
@changcode
2021-12-28 16:48:50 +08:00
parent caa8e2d0e6
commit 835d3afba5
8 changed files with 426 additions and 8 deletions

View File

@@ -162,6 +162,15 @@
@chartIsNoData="chartIsNoData"
:chart-option="chartOption"
></chart-group>
<chart-clock
:ref="'chart' + chartInfo.id"
v-if="isClock(chartInfo.type)"
:chart-data="chartData"
:chart-info="chartInfo"
:chart-option="chartOption"
:is-fullscreen="isFullscreen"
@chartIsNoData="chartIsNoData"
></chart-clock>
</template>
</div>
</template>
@@ -188,7 +197,7 @@ import chartUrl from './chart/chartUrl'
import chartValue from './chart/chartValue'
import chartHexagon from './chart/chartHexagon'
import chartMap from './chart/chartMap'
import { getOption, isTimeSeries, isHexagon, isUrl, isText, isChartPie, isChartBar, isTreemap, isLog, isStat, isDiagram, isGroup, isAutotopology, isMap, isAssetInfo, isEndpointInfo, isTable, isGauge } from './chart/tools'
import { getOption, isTimeSeries, isHexagon, isUrl, isText, isChartPie, isChartBar, isTreemap, isLog, isStat, isDiagram, isGroup, isAutotopology, isMap, isAssetInfo, isEndpointInfo, isTable, isGauge, isClock } from './chart/tools'
import lodash from 'lodash'
export default {
@@ -244,7 +253,7 @@ export default {
},
computed: {
isNoData () {
return lodash.isEmpty(this.chartData) && ['text', 'url'].indexOf(this.chartInfo.type) === -1
return lodash.isEmpty(this.chartData) && ['text', 'url', 'clock'].indexOf(this.chartInfo.type) === -1
},
chartOption () {
if (this.customChartOption) {
@@ -272,6 +281,7 @@ export default {
isMap,
isTable,
isGauge,
isClock,
chartIsNoData (flag) {
this.chartChildrenData = flag
},

View File

@@ -1,13 +1,184 @@
<template>
<div
:class="legendPlacement"
ref="pie-chart-box"
class="nz-chart__component nz-chart__component--time-series" @mouseenter="mouseEnterChart"
@mouseleave="mouseLeaveChart"
>
<div :id="`chart-canvas-${chartId}`" class="chart__canvas"></div>
<chart-legend
v-if="hasLegend"
:chart-data="chartData"
:chart-info="chartInfo"
:legends="legends"
:is-fullscreen="isFullscreen"
></chart-legend>
</div>
</template>
<script>
import legend from '@/components/chart/chart/legend'
import chartMixin from '@/components/chart/chartMixin'
import chartFormat from '@/components/chart/chartFormat'
import { chartLegendPlacement } from '@/components/common/js/constants'
import * as echarts from 'echarts'
import { getChart, setChart } from '@/components/common/js/common'
import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools'
import chartDataFormat from '@/components/charts/chartDataFormat'
import { initColor } from '@/components/chart/chart/tools'
import lodash from 'lodash'
export default {
name: 'chart-clock'
name: 'chart-clock',
components: {
chartLegend: legend
},
mixins: [chartMixin, chartFormat],
props: {
chartInfo: Object,
chartData: Array,
chartOption: Object,
isFullscreen: Boolean
},
computed: {
hasLegend () {
try {
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
} catch (e) {
return false
}
},
legendPlacement () {
try {
switch (this.chartInfo.param.legend.placement) {
case 'left':
case 'right':
case 'bottom': {
return `nz-chart__component--${this.chartInfo.param.legend.placement}`
}
default: return ''
}
} catch (e) {
return ''
}
}
},
data () {
return {
colorList: [],
chartDot: 2,
isInit: true, // 是否是初始化初始化时为true图表初始化结束后设为false
toolboxIconColor: {
active: '#53a3cb',
inactive: '#7e7e7e'
},
chartId: ''
}
},
methods: {
initChart (chartOption = this.chartOption) {
const self = this
chartOption.axisLabel = {
margin: 8,
formatter (params) {
const dataLength = chartOption.series[0].data.length || 1
const chartWidth = (document.getElementById('chart-canvas-' + self.chartInfo.id).offsetWidth - 80) / dataLength// 容器宽 - padding - 空余
const length = Math.ceil((chartWidth) / 16)
let val = ''
if (params.length > length) {
val = params.substr(0, length) + '...'
return val
} else {
return params
}
}
}
/* 使用setTimeout延迟渲染图表避免样式错乱 */
// setTimeout(() => {
const myChart = this.isInit ? echarts.init(document.getElementById(`chart-canvas-${this.chartId}`)) : getChart(this.chartId)
myChart.setOption(chartOption)
this.isInit && setChart(this.chartId, myChart) // 缓存不使用vue的data是为避免整个chart被监听导致卡顿
this.isInit = false
if (this.chartInfo.param && this.chartInfo.param.timeType === 'local') {
setInterval(function () {
const time = new Date()
let h = time.getHours() >= 12 ? time.getHours() - 12 : time.getHours()
const m = time.getMinutes() / 5
const s = time.getSeconds() / 5
h = h + time.getMinutes() / 60
chartOption.animationDurationUpdate = 300
chartOption.series[0].data[0].value = h
chartOption.series[1].data[0].value = m.toFixed(1)
chartOption.series[2].data[0].value = s.toFixed(1)
myChart.setOption(chartOption)
}, 1000)
}
// }, 200)
},
initBarData (chartInfo, seriesTemplate, originalDatas) {
let colorIndex = 0
const self = this
const s = lodash.cloneDeep(seriesTemplate)
s.data = []
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
this.isNoData = false
if (s) {
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, 2)
const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping)
// eslint-disable-next-line vue/no-mutating-props
mapping && (this.chartOption.color[colorIndex] = mapping.color.bac)
s.data.push({
value: value,
realValue: value,
showValue: showValue,
name: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex).name,
alias: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex).alias,
labels: data.metric,
seriesIndex: expressionIndex,
dataIndex: dataIndex,
mapping: mapping,
label: {
...s.label,
formatter: this.pieFormatterLabel,
color: mapping ? mapping.color.text : '#000000'
},
itemStyle: {
color: mapping ? mapping.color.bac : this.colorList[colorIndex]
}
})
colorIndex++
}
})
})
this.$emit('chartIsNoData', this.isNoData)
return [s]
},
formatterFunc (params, ticket, callback) {
const self = this
return `
<div>
<div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;">
<div style="max-width: 500px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.alias}</div>
<div style="font-size:12px;display:flex;justify-content: space-between;">
<div>value</div>
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'none' : 'inline-block'}">${params.data.showValue}</div>
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
</div>
</div>
</div>
`
}
},
mounted () {
// eslint-disable-next-line vue/no-mutating-props
this.chartOption.color || (this.chartOption.color = initColor(20))
this.colorList = this.chartOption.color
try {
this.isStack = this.chartInfo.param.stack
} catch (e) {}
this.chartInfo.loaded && this.initChart(this.chartOption)
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,181 @@
const chartClockOption = {
series: [
{
name: 'hour',
type: 'gauge',
startAngle: 90,
endAngle: -270,
min: 0,
max: 12,
splitNumber: 12,
clockwise: true,
axisLine: {
lineStyle: {
width: 15,
color: [[1, 'rgba(0,0,0,0.7)']],
shadowColor: 'rgba(0, 0, 0, 0.5)',
shadowBlur: 15
}
},
splitLine: {
lineStyle: {
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 3,
shadowOffsetX: 1,
shadowOffsetY: 2
}
},
axisLabel: {
fontSize: 50,
distance: 25,
formatter: function (value) {
if (value === 0) {
return ''
}
return value + ''
}
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 12,
length: '55%',
offsetCenter: [0, '8%'],
itemStyle: {
color: '#C0911F',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
detail: {
show: false
},
title: {
offsetCenter: [0, '30%']
},
data: [
{
value: 0
}
]
},
{
name: 'minute',
type: 'gauge',
startAngle: 90,
endAngle: -270,
min: 0,
max: 60,
clockwise: true,
axisLine: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 8,
length: '70%',
offsetCenter: [0, '8%'],
itemStyle: {
color: '#C0911F',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
anchor: {
show: true,
size: 20,
showAbove: false,
itemStyle: {
borderWidth: 15,
borderColor: '#C0911F',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
detail: {
show: false
},
title: {
offsetCenter: ['0%', '-40%']
},
data: [
{
value: 0
}
]
},
{
name: 'second',
type: 'gauge',
startAngle: 90,
endAngle: -270,
min: 0,
max: 60,
animationEasingUpdate: 'bounceOut',
clockwise: true,
axisLine: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 4,
length: '85%',
offsetCenter: [0, '8%'],
itemStyle: {
color: '#C0911F',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
anchor: {
show: true,
size: 15,
showAbove: true,
itemStyle: {
color: '#C0911F',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
detail: {
show: false
},
title: {
offsetCenter: ['0%', '-40%']
},
data: [
{
value: 0
}
]
}
]
}
export default chartClockOption

View File

@@ -9,6 +9,7 @@ import {
} from './options/chartTimeSeries'
import chartTreemapOption from './options/chartTreemap'
import chartGaugeOption from './options/chartGauge'
import chartClockOption from '@/components/chart/chart/options/chartClock'
import { randomcolor } from '@/components/common/js/radomcolor/randomcolor'
export function getOption (type) {
@@ -46,6 +47,10 @@ export function getOption (type) {
chartOption = lodash.cloneDeep(chartGaugeOption)
break
}
case chartType.clock: {
chartOption = lodash.cloneDeep(chartClockOption)
break
}
default:
chartOption = {}
break
@@ -106,6 +111,9 @@ export function isTable (type) {
export function isGauge (type) {
return type === chartType.guage
}
export function isClock (type) {
return type === chartType.clock
}
export function getGroupHeight (arr) {
if (arr.length) {
let lastItem = []

View File

@@ -399,6 +399,7 @@ export const chartType = {
log: 'log',
text: 'text',
url: 'url',
clock: 'clock',
group: 'group',
diagram: 'diagram',
assetInfo: 'assetInfo',

View File

@@ -145,6 +145,7 @@ export default {
case 'map' :
case 'topology' :
case 'hexagon' :
case 'clock' :
return false
default: return true
}

View File

@@ -99,6 +99,32 @@
</el-option>
</el-select>
</el-form-item>
<!-- timeType -->
<el-form-item
:label="$t('dashboard.panel.chartForm.timeType')"
class="form-item--half-width"
v-if="chartConfig.type === 'clock'"
prop="type"
>
<el-select
id="chart-box-type"
v-model="chartConfig.param.timeType"
:disabled="chartConfig.type === 'group'"
:placeholder="$t('el.select.placeholder')"
popper-class="right-box-select-top prevent-clickoutside"
size="small"
value-key="chartType"
@change="change">
<el-option
v-for="item in timeType"
:key="item.value"
:label="item.label"
:value="item.value">
<span class="panel-dropdown-label-txt" >{{item.label}}</span>
</el-option>
</el-select>
</el-form-item>
</div>
<!--content-->
<div v-if="contentShow(chartConfig.type)" class="form__sub-title">
@@ -178,6 +204,10 @@ export default {
{
id: 'hexagon',
name: this.$t('dashboard.panel.chartForm.typeVal.hexagonFigure.label')
},
{
id: 'clock',
name: this.$t('dashboard.panel.chartForm.typeVal.clock.label')
}
]
}
@@ -187,6 +217,7 @@ export default {
this.chartConfig = JSON.parse(JSON.stringify(this.params))
},
chartTypeChange (type) {
console.log(type)
switch (type) {
case 'group':
this.chartConfig.span = 12
@@ -213,6 +244,11 @@ export default {
url: ''
}
break
case 'clock':
this.chartConfig.param = {
timeType: this.chartConfig.param.timeType
}
break
}
this.change()
},

View File

@@ -160,6 +160,16 @@ export default {
label: 'None',
value: 'none'
}
],
timeType: [
{
value: 'local',
label: this.$t('dashboard.panel.chartForm.typeVal.local')
},
{
value: 'server',
label: this.$t('dashboard.panel.chartForm.typeVal.server')
}
]
}
},