feat: 实现 stat 的自动排列

This commit is contained in:
zhangyu
2021-12-10 16:18:18 +08:00
parent 167c4498bb
commit 0faf028ceb
7 changed files with 119 additions and 49 deletions

View File

@@ -257,12 +257,20 @@
} }
} }
.chart-stat{ .chart-stat{
width: 100%;
height: calc(100% - 20px); height: calc(100% - 20px);
margin: 10px;
display: flex; display: flex;
justify-content: center; flex-wrap: wrap;
align-items: center; padding: 5px;
font-size: 30px; box-sizing: border-box;
word-break: break-all; .chart-stat-item{
border-radius: 2px; display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
word-break: break-all;
border-radius: 2px;
box-sizing: border-box;
border: 2px solid #fff;
}
} }

View File

@@ -5,12 +5,14 @@
<template v-else> <template v-else>
<chart-time-series <chart-time-series
v-if="isTimeSeries(chartInfo.type)" v-if="isTimeSeries(chartInfo.type)"
:ref="'chart' + chartInfo.id"
:chart-data="chartData" :chart-data="chartData"
:chart-info="chartInfo" :chart-info="chartInfo"
:chart-option="chartOption" :chart-option="chartOption"
:is-fullscreen="isFullscreen" :is-fullscreen="isFullscreen"
></chart-time-series> ></chart-time-series>
<chart-pie <chart-pie
:ref="'chart' + chartInfo.id"
v-if="isChartPie(chartInfo.type)" v-if="isChartPie(chartInfo.type)"
:chart-data="chartData" :chart-data="chartData"
:chart-info="chartInfo" :chart-info="chartInfo"
@@ -18,6 +20,7 @@
:is-fullscreen="isFullscreen" :is-fullscreen="isFullscreen"
></chart-pie> ></chart-pie>
<chart-bar <chart-bar
:ref="'chart' + chartInfo.id"
v-if="isChartBar(chartInfo.type)" v-if="isChartBar(chartInfo.type)"
:chart-data="chartData" :chart-data="chartData"
:chart-info="chartInfo" :chart-info="chartInfo"
@@ -32,30 +35,35 @@
:chart-option="chartOption" :chart-option="chartOption"
></chartHexagon> ></chartHexagon>
<chart-url <chart-url
:ref="'chart' + chartInfo.id"
v-if="isUrl(chartInfo.type)" v-if="isUrl(chartInfo.type)"
:chart-data="chartData" :chart-data="chartData"
:chart-info="chartInfo" :chart-info="chartInfo"
:chart-option="chartOption" :chart-option="chartOption"
></chart-url> ></chart-url>
<chart-text <chart-text
:ref="'chart' + chartInfo.id"
v-if="isText(chartInfo.type)" v-if="isText(chartInfo.type)"
:chart-data="chartData" :chart-data="chartData"
:chart-info="chartInfo" :chart-info="chartInfo"
:chart-option="chartOption" :chart-option="chartOption"
></chart-text> ></chart-text>
<chart-treemap <chart-treemap
:ref="'chart' + chartInfo.id"
v-if="isTreemap(chartInfo.type)" v-if="isTreemap(chartInfo.type)"
:chart-data="chartData" :chart-data="chartData"
:chart-info="chartInfo" :chart-info="chartInfo"
:chart-option="chartOption" :chart-option="chartOption"
></chart-treemap> ></chart-treemap>
<chart-log <chart-log
:ref="'chart' + chartInfo.id"
v-if="isLog(chartInfo.type)" v-if="isLog(chartInfo.type)"
:chart-data="chartData" :chart-data="chartData"
:chart-info="chartInfo" :chart-info="chartInfo"
:chart-option="chartOption" :chart-option="chartOption"
></chart-log> ></chart-log>
<chart-stat <chart-stat
:ref="'chart' + chartInfo.id"
v-if="isStat(chartInfo.type)" v-if="isStat(chartInfo.type)"
:chart-data="chartData" :chart-data="chartData"
:chart-info="chartInfo" :chart-info="chartInfo"

View File

@@ -1,9 +1,11 @@
<template> <template>
<div class="chart-stat" :style="{background:stat.mapping ? stat.mapping.color.bac : false}"> <div class="chart-stat" ref="chart-stat-box">
<span v-if="stat.mapping" :style="{color:stat.mapping.color.text}"> <div class="chart-stat-item" :style="{background:item.mapping ? item.mapping.color.bac : false,height:item.height+'px',width:item.width + 'px'}" v-for="(item,index) in statData" :key="index">
{{handleDisplay(stat.mapping.display, { ...stat.label, value: stat.showValue })}} <span v-if="item.mapping" :style="{color:item.mapping.color.text}">
{{handleDisplay(item.mapping.display, { ...item.label, value: item.showValue })}}
</span> </span>
<span v-else>{{stat.showValue}}</span> <span v-else>{{item.showValue}}</span>
</div>
</div> </div>
</template> </template>
@@ -18,40 +20,94 @@ export default {
mixins: [chartMixin, chartFormat], mixins: [chartMixin, chartFormat],
data () { data () {
return { return {
stat: { statData: [],
value: '', boxWidth: 0,
showValue: '', boxHeight: 0,
label: {}, boxPadding: 5
mapping: {
}
}
} }
}, },
methods: { methods: {
initChart () { initChart () {
console.log(this.chartInfo, this.chartData) this.initStatData(this.chartInfo, this.chartData).then(() => {
this.stat = this.initStatData(this.chartInfo, this.chartData) this.getLayout().then(layout => {
console.log(this.stat) this.renderStat(layout)
},
initStatData (chartInfo, originalDatas) {
const stat = {
value: '',
showValue: '',
label: {},
mapping: {
}
}
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
stat.value = getMetricTypeValue(data.values, chartInfo.param.statistics)
stat.label = data.metric
stat.showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(stat.value, null, -1, 2)
stat.mapping = this.selectMapping(stat.value, chartInfo.param.valueMapping)
}) })
}) })
return stat },
initStatData (chartInfo, originalDatas) {
return new Promise(resolve => {
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
const stat = {
value: '',
showValue: '',
label: {},
width: '',
height: '',
mapping: {
}
}
stat.value = getMetricTypeValue(data.values, chartInfo.param.statistics)
stat.label = data.metric
stat.showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(stat.value, null, -1, 2)
stat.mapping = this.selectMapping(stat.value, chartInfo.param.valueMapping)
this.statData.push(stat)
})
})
resolve()
})
},
getLayout () {
this.boxWidth = this.$refs['chart-stat-box'].offsetWidth - 2 * this.boxPadding
this.boxHeight = this.$refs['chart-stat-box'].offsetHeight - 2 * this.boxPadding
return new Promise(resolve => {
let rateMax = 0
let col = 0
let row = 0
for (let i = 1; i <= this.statData.length; i++) {
const cols = Math.ceil(this.statData.length / i)
const w = this.boxWidth / i
const h = this.boxHeight / cols
const rate = w > h ? h / w : w / h
if (rate > rateMax) {
rateMax = rate
col = cols
row = i
}
}
while (col * row >= this.statData.length) { // 避免出现空白
row--
}
row++
if (col === 1 || row === 1) { // 行 或 列有一个为1时 需要调换位置 显示才会好看
const temp = col
col = row
row = temp
}
resolve({ col, row })
})
},
renderStat (layout) {
const width = this.boxWidth / layout.col
const height = this.boxHeight / layout.row
const integer = Math.floor(this.statData.length / layout.col)
const remainder = this.statData.length % layout.col
const specialIndex = integer * layout.col
const specialWidth = this.boxWidth / remainder
this.statData.forEach((item, index) => {
item.height = height
if (remainder && index >= specialIndex) {
item.width = specialWidth
} else {
item.width = width
}
})
},
resize () {
this.getLayout().then(layout => {
this.renderStat(layout)
})
} }
}, },
mounted () { mounted () {

View File

@@ -21,11 +21,9 @@ export default {
return str return str
}, },
handleDisplay (display, params) { handleDisplay (display, params) {
console.log(params)
if (/\{\{.+\}\}/.test(display)) { if (/\{\{.+\}\}/.test(display)) {
const labelValue = display.replace(/(\{\{.+?\}\})/g, function (i) { const labelValue = display.replace(/(\{\{.+?\}\})/g, function (i) {
const label = i.substr(i.indexOf('{{') + 2, i.indexOf('}}') - i.indexOf('{{') - 2) const label = i.substr(i.indexOf('{{') + 2, i.indexOf('}}') - i.indexOf('{{') - 2)
console.log(label)
let value = null let value = null
if (params[label]) { if (params[label]) {
value = params[label] value = params[label]

View File

@@ -110,13 +110,20 @@ export default {
}, },
resizeEvent (i, newH, newW, newHPx, newWPx) { resizeEvent (i, newH, newW, newHPx, newWPx) {
// TODO 分段重新渲染图表,或者暂时隐藏图表 // TODO 分段重新渲染图表,或者暂时隐藏图表
setTimeout(() => {
this.$refs['chart' + i][0].resize()
}, 50)
}, },
resizedEvent (i, newH, newW, newHPx, newWPx) { resizedEvent (i, newH, newW, newHPx, newWPx) {
// TODO 重新渲染图表向后端发送put请求 // TODO 重新渲染图表向后端发送put请求
setTimeout(() => {
this.$refs['chart' + i][0].resize()
}, 100)
}, },
containerResizedEvent (i, newH, newW, newHPx, newWPx) { containerResizedEvent (i, newH, newW, newHPx, newWPx) {
// TODO 重新渲染图表 // TODO 重新渲染图表
// this.$refs['chart' + i].resize() // this.$refs['chart' + i].resize()
// this.$refs['chart' + i][0].resize()
}, },
showFullscreen (show, chartInfo) { showFullscreen (show, chartInfo) {
this.fullscreen.chartInfo = chartInfo this.fullscreen.chartInfo = chartInfo
@@ -135,7 +142,7 @@ export default {
handler (n, o) { handler (n, o) {
this.noData = !n || n.length < 1 this.noData = !n || n.length < 1
this.copyDataList = n.map(item => { this.copyDataList = n.map(item => {
let param = item.param const param = item.param
// try { // try {
// param = JSON.parse(item.param) // param = JSON.parse(item.param)
// } catch (e) { // } catch (e) {

View File

@@ -115,7 +115,6 @@ export default {
chartData.push({ error: r.msg || r.error || r }) chartData.push({ error: r.msg || r.error || r })
} }
}) })
console.log(chartData)
this.chartData = chartData this.chartData = chartData
if (this.chartInfo.type === 'log') { if (this.chartInfo.type === 'log') {
this.logChartDataFormat() this.logChartDataFormat()

View File

@@ -52,7 +52,7 @@
<div v-if="expressionsShow[index-1].error" class="el-form-item__error" style="top: 10px;left: 164px"> {{expressionsShow[index-1].error}}</div> <div v-if="expressionsShow[index-1].error" class="el-form-item__error" style="top: 10px;left: 164px"> {{expressionsShow[index-1].error}}</div>
</span> </span>
<span> <span>
<span @click="()=>{addExpression()}" style="margin-right: 5px;padding-left: 10px" v-if="!isStat(chartConfig.type)"> <span @click="()=>{addExpression()}" style="margin-right: 5px;padding-left: 10px">
<i class="nz-icon nz-icon-create-square" style="font-weight: normal; font-size: 17px; cursor: pointer;"></i> <i class="nz-icon nz-icon-create-square" style="font-weight: normal; font-size: 17px; cursor: pointer;"></i>
</span> </span>
<span @click="copyExpression(index - 1)" style="margin-right: 5px"> <span @click="copyExpression(index - 1)" style="margin-right: 5px">
@@ -770,12 +770,6 @@ export default {
case 'treemap': case 'treemap':
case 'guage': case 'guage':
case 'pie': case 'pie':
if (type === 'stat') {
this.expressions = []
this.expressionName = []
this.chartConfig.elements = [this.chartConfig.elements[0]]
this.addExpression(this.chartConfig.elements[0])
}
if (this.oldType === 'stat' || this.oldType === 'bar' || this.oldType === 'treemap' || this.oldType === 'guage' || this.oldType === 'pie') { if (this.oldType === 'stat' || this.oldType === 'bar' || this.oldType === 'treemap' || this.oldType === 'guage' || this.oldType === 'pie') {
break break
} }