Commit 29389308 by yuwei

Feature: 图表类型添加指标卡

parent ff485e77
...@@ -120,17 +120,17 @@ export const chartTypes = [ ...@@ -120,17 +120,17 @@ export const chartTypes = [
} }
} }
}, },
// { {
// name: '指标卡', value: 'kpi', icon: 'chart_kpi', name: '指标卡', value: 'kpi', icon: 'chart_kpi',
// status: true, status: true,
// component: 'ChartKpi', component: 'ChartKpi',
// rule: { rule: {
// text: '0 行维;0 列维;1 指标', text: '0 行维;0 列维;1 指标',
// check(rows, columns, measures) { check(rows, columns, measures) {
// return rows.length === 0 && columns.length === 0 && measures.length === 1 return rows.length === 0 && columns.length === 0 && measures.length === 1
// } }
// } }
// }, },
{ {
name: '水球图', value: 'liquidFill', icon: 'chart_liquidfill', name: '水球图', value: 'liquidFill', icon: 'chart_liquidfill',
status: true, status: true,
......
...@@ -130,6 +130,7 @@ export default { ...@@ -130,6 +130,7 @@ export default {
if (response.success) { if (response.success) {
this.dataBoard = response.data this.dataBoard = response.data
this.layout = this.dataBoard.boardConfig ? JSON.parse(JSON.stringify(this.dataBoard.boardConfig.layout)) : [] this.layout = this.dataBoard.boardConfig ? JSON.parse(JSON.stringify(this.dataBoard.boardConfig.layout)) : []
this.interval = this.dataBoard.boardConfig ? JSON.parse(JSON.stringify(this.dataBoard.boardConfig.interval)) : []
const charts = this.dataBoard.charts ? JSON.parse(JSON.stringify(this.dataBoard.charts)) : [] const charts = this.dataBoard.charts ? JSON.parse(JSON.stringify(this.dataBoard.charts)) : []
charts.forEach((item, index, arr) => { charts.forEach((item, index, arr) => {
this.parserChart(item) this.parserChart(item)
......
<template> <template>
<div ref="chart" :style="chartStyle">ChartKpi</div> <div ref="chart" :style="chartStyle" style="max-height: 100%; max-width: 100%;">
<div class="card-panel">
<div class="card-panel-description">
<div class="card-panel-num">{{ calcData.val }}</div>
<div class="card-panel-text">{{ calcData.key }}</div>
</div>
<div class="card-panel-icon-wrapper icon-people">
<i class="el-icon-s-data"></i>
</div>
</div>
</div>
</template> </template>
<script> <script>
import { SEPARATOR } from '@/utils/visual-chart'
export default { export default {
name: 'ChartKpi', name: 'ChartKpi',
props: { props: {
...@@ -32,7 +44,8 @@ export default { ...@@ -32,7 +44,8 @@ export default {
}, },
chartTheme: { chartTheme: {
type: String, type: String,
require: true require: true,
default: 'default'
}, },
chartOption: { chartOption: {
type: Object, type: Object,
...@@ -42,19 +55,191 @@ export default { ...@@ -42,19 +55,191 @@ export default {
chartStyle: { chartStyle: {
type: Object, type: Object,
require: false, require: false,
default: () => { default: () => ({})
return { }
height: '200px' },
} data() {
} return {
localRows: [],
localColumns: [],
localValues: [],
localData: [],
// 连接符
connector: '-',
calcData: { key: '', val: '' }
}
},
computed: {
watchAllProps() {
const { rows, columns, values, data } = this
return { rows, columns, values, data }
}
},
watch: {
watchAllProps() {
this.init()
this.mergeChartOption()
},
chartTheme() {
this.mergeChartTheme()
},
chartOption: {
handler(newValue, oldValue) {
this.mergeChartOption()
},
deep: true
} }
}, },
created() { created() {
console.log(this.data) this.init()
},
methods: {
init() {
if (this.rows.length || this.columns.length || this.values.length) {
this.handleDataClone()
this.setValuesToColAndRow()
this.handleCalcData()
} else {
console.warn('[Warn]: props.rows, props.columns, props.values at least one is not empty.')
}
},
// clone data
handleDataClone() {
this.localRows = JSON.parse(JSON.stringify(this.rows))
this.localColumns = JSON.parse(JSON.stringify(this.columns))
this.localValues = JSON.parse(JSON.stringify(this.values))
this.localData = Object.freeze(this.data)
},
// set the `values` attribute to rows and columns
setValuesToColAndRow() {
const rowKeys = this.localRows.map(({ key }) => key)
const columnKeys = this.localColumns.map(({ key }) => key)
const rowValues = this._findCategory(rowKeys, this.localData)
const columnValues = this._findCategory(columnKeys, this.localData)
this.localRows.forEach((row) => {
const { key, values } = row
this.$set(row, 'values', values || rowValues[key] || [])
})
this.localColumns.forEach((column) => {
const { key, values } = column
this.$set(column, 'values', values || columnValues[key] || [])
})
},
// 计算值
handleCalcData() {
if (!this.localValues.length) return
const localValue = this.localValues[0]
const seriesName = localValue.key
this.calcData.key = seriesName
this.calcData.val = this.localData[0][seriesName]
},
mergeChartOption() {},
mergeChartTheme() {},
_combineRowPaths(data, ...arrays) {
const len = arrays.length
let _result = []
if (len) {
const rowPaths = arrays.reduce((prev, curr) => {
const arr = []
prev.values.forEach(_prevEl => {
const prevKey = prev.key.split(SEPARATOR)
curr.values.forEach(_currEl => {
const currKey = curr.key
const conditions = {}
prevKey.forEach((key, i) => {
conditions[key] = _prevEl.split(SEPARATOR)[i]
})
conditions[currKey] = _currEl
// 判断数据里是否有该项
const filter = data.some((data) => {
let status = true
for (const key in conditions) {
if (conditions[key] !== data[key]) {
status = false
return
}
}
return status
})
if (filter) {
arr.push(_prevEl + SEPARATOR + _currEl)
}
})
})
return { key: prev.key + SEPARATOR + curr.key, values: arr }
}) || {}
_result = rowPaths.values || []
}
return _result
},
_combineColPaths(...arrays) {
return arrays.length ? arrays.reduce((prev, curr) => {
const arr = []
prev.forEach(_prevEl => {
curr.forEach(_currEl => {
arr.push(_prevEl + SEPARATOR + _currEl)
})
})
return arr
}) : arrays
},
_findCategory(keys = [], data = []) {
const _result = {}
data.forEach(item => {
keys.forEach(key => {
// Remove duplicates
_result[key] = _result[key] || []
_result[key].push(item[key])
_result[key] = [...new Set(_result[key])]
})
})
return _result
},
_reduceValue(data, key) {
if (!data.length) return 0
return data.reduce((sum, item) => { return sum + Number(item[key]) }, 0)
},
_filterData(conditions, data) {
return data.filter((data) => {
let status = true
for (const key in conditions) {
if (conditions[key] !== data[key]) {
status = false
return
}
}
return status
})
}
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.card-panel {
display: flex;
align-items: center; /*垂直居中*/
justify-content: center; /*水平居中*/
background-color: #00c0ef;
.card-panel-description {
flex:1;
text-align: center;
.card-panel-num {
font-size: 38px;
font-weight: bold;
color: #fff;
}
.card-panel-text {
color: rgba(0,0,0,.45);
font-size: 16px;
margin-top: 12px;
}
}
.card-panel-icon-wrapper {
i {
font-size: 90px;
color: rgba(0, 0, 0, 0.15);
}
}
}
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment