cmc-web/packages/common/components/rich-chart/index.vue

141 lines
3.6 KiB
Vue

<template>
<el-card class="chart-card">
<div slot="header" class="chart-header">
<div>{{ title }}</div>
<div class="operate">
<el-radio-group v-model="chartType" size="mini" class="m-r-sm">
<template v-if="defaultChart === 'loop-charts'">
<el-radio-button label="loop-charts">环状</el-radio-button>
<el-radio-button label="bar-charts">柱状</el-radio-button>
</template>
<template v-else>
<el-radio-button label="line-charts">折线</el-radio-button>
<el-radio-button label="bar-charts">柱状</el-radio-button>
</template>
</el-radio-group>
<el-button type="ghost" class="operate-btn" @click="enlarge">放大</el-button>
<!-- <el-button type="ghost" class="operate-btn" @click="download">下载</el-button> -->
</div>
</div>
<slot></slot>
<component ref="charts" :is="chartMap[chartType]" :setting="chartSetting" :data="getResData()" v-if="data" :theme="title" :id="chartId" :height="height" width="100%"></component>
<el-dialog :title="title" :visible.sync="dialogVisible" v-if="dialogVisible" fullscreen class="chart-dialog">
<component :is="chartMap[chartType]" :setting="chartSetting" :data="getResData()" :theme="title" :id="`${chartId}dialog`" height="100%" width="100%"></component>
</el-dialog>
</el-card>
</template>
<script>
import { downloadFile } from './tools'
export default {
props: {
title: {
type: String
},
defaultChart: {
type: String,
default: 'loop-charts'
},
data: {
type: [Object, Array]
},
setting: {
type: Object,
default: function () {
return {}
}
},
height: {
type: String,
default: '260px'
},
// 图片下载配置
downloadOpt: {
type: Object,
default: function () {
return {}
}
}
},
data() {
return {
chartId: Math.random().toString(),
chartType: '',
dialogVisible: false,
chartMap: {
'pie-charts': 'cg-pie-charts',
'bar-charts': 'cg-bar-charts',
'line-charts': 'cg-line-charts',
'loop-charts': 'cg-pie-charts'
}
}
},
computed: {
chartSetting() {
const setting = {}
if (this.chartType === 'pie-charts') setting.radius = '75%'
return {
...this.setting,
...setting
}
}
},
created() {
this.chartType = this.defaultChart
},
methods: {
// 处理环状图切换为柱状图
getResData() {
if (this.defaultChart === 'loop-charts' && this.chartType === 'bar-charts') {
const keys = []
const values = [
{
name: '统计数据',
data: []
}
]
this.data.forEach(item => {
const { name, value } = item
keys.push(name)
values[0].data.push(value)
})
return {
keys,
values
}
}
return this.data
},
enlarge() {
this.dialogVisible = true
},
download() {
const image = this.$refs.charts.chart.getDataURL(this.downloadOpt)
downloadFile(this.downloadOpt.name || this.title, image)
}
}
}
</script>
<style scoped lang="scss">
.chart-card {
.chart-header {
display: flex;
align-items: center;
}
.operate {
flex: 1;
text-align: right;
.operate-btn {
padding: 7px 15px;
}
}
::v-deep .el-card__body {
padding: 10px !important;
}
.chart-dialog {
::v-deep .el-dialog__body {
height: calc(100vh - 130px);
}
}
}
</style>