效果图
效果图描述
点击柱状图的每根柱子显示对应的值和name及图例对应的总额
柱图点击事件
<template>
<div ref="dom" class="charts chart-bar"></div>
</template>
this.dom = echarts.init(this.$refs.dom, theme);
this.dom.on('click', (event) => { // 柱图绑定点击事件
this.$emit('chart_click', event)
})
父组件使用
<template>
<div class="chart_table_box">
<Row>
<Col>
<div class="chart_box" style="width: 100%; height: 340px; position: relative;">
<ChartBar :option="options" @chart_click="handleChartClick"></ChartBar>
<div class="legend_box">
<div>{{countNum}}<span>万</span></div>
<div>{{countName}}</div>
<div class="line1"></div>
<div class="line2"></div>
<div class="kailong"></div>
</div>
</div>
</Col>
</Row>
</div>
</template>
<script>
import lodash from "lodash";
import ChartBar from "../../common/bar.vue";
// import { ChartBar } from "_c/charts";
import { postTender } from "@/api/business/tender/tenderCom.js";
export default {
components: {
ChartBar
},
props: {
deptCode: { // 调取接口 所传的参数
type: String,
default: () => '60'
},
basicData: {
// 基本数据 url
type: Object,
default: () => ({
url: ""
})
},
},
watch: {
deptCode: {
handler () {
this.getData();
}
}
},
mounted () {
// 根据布局模式,动态设置图例位置
let layoutType = this.$store.state.app.layoutType;
switch (layoutType) {
case 'layoutA':
this.options.legend.left = '80.4%';
break;
case 'layoutB':
this.options.legend.left = '83.5%';
break;
default:
break;
}
},
data () {
return {
countName: '总额', // 统计柱图的名称
countNum: 0, // 统计的总金额
chartData: [], // 图例用来格式化的数据源
copyChartData: [], // 拷贝图表的数据,用来动态改变柱图对应的数据结构
styleList: [ // 样式数组
{color: 'rgba(32, 166, 119, 1)'},
{color: 'rgba(31, 187, 237, 1)'},
{color: 'rgba(247, 177, 60, 1)'}
],
options: {
color: [],
grid: {
top: '20%',
left: '3%',
right: '30%',
bottom: '2%',
containLabel: true
},
legend: {
itemHeight: 10,
itemWidth: 10,
icon: "rect",
orient: 'vertical',
top: '53%',
itemGap: 15,
zlevel: 999,
z: 999,
data: [],
formatter: (name) => {
let data = this.chartData;
let target;
for (let i = 0; i < data.length; i++) {
if (data[i].name === name) {
target = data[i].value;
}
}
let arr = [
'{a|' + name + '}',
'{b|' + target + '}',
'{c|' + '万}'
]
return arr.join('')
},
textStyle: {
rich: {
a: {
fontSize: 12,
color: '#333',
},
b: {
fontSize: 16,
padding: [0, 0, 0, 10],
// width: 80
},
c: {
fontSize: 12
}
}
}
},
toolbox: {
feature: {
saveAsImage: {
backgroundColor: '#fff'
}
},
right: 20
},
xAxis: [{
type: "category",
data: [],
axisTick: {
show: true,
length: 5,
lineStyle: {}
},
axisLabel: {
show: true,
interval: 0,
rotate: 45,
color: '#000',
borderWidth: 15, // 加边框,解决最后一个文字加粗加黑问题
borderColor: '#fff', // 背景色
margin: 15, // 刻度标签与轴线之间的距离
}
}],
yAxis: [{
type: "value",
name: '概算金额(万元)',
axisLabel: {
color: '#333'
},
nameTextStyle: {
color: '#333'
}
}],
series: []
},
tableData: []
}
},
methods: {
calc (pIndex, cIndex, pLength, cLength) {
let cellW = (parseInt((100 / 10) * 100) / 100).toFixed(2);
if (pIndex === 0) {
return cellW * 2 + "%";
} else {
switch (cIndex) {
case 0:
return cellW * 2 + "%";
default:
return cellW + "%";
}
}
},
getData () { // 获取接口数据
let data = {
deptCode: this.deptCode
};
postTender(this.basicData.url, data).then(res => {
const jsonData = res.data;
if (jsonData.status === 1 && jsonData.code === 200 && !lodash.isEmpty(jsonData.data)) {
this.tableData = jsonData.data.tableData; // 表格数据
let {data, xAxis, deptSum} = jsonData.data.chartsData;
let legendData = lodash.cloneDeep(jsonData.data.chartData);
// 动态设置图例颜色
if (legendData.length > 0) {
legendData.forEach((item, index) => {
item.textStyle = this.styleList[index];
})
}
this.setOptionsColor(); // 设置调色盘颜色列表
this.options.legend.data = legendData; // 初始化图例及总额数据、名称
this.countNum = (jsonData.data.totalSum ? jsonData.data.totalSum : 0);
this.countName = '总额';
this.chartData = legendData;
this.options.xAxis[0].data = xAxis;
this.copyChartData = lodash.cloneDeep(data); // 拷贝图表数据用来动态改变柱图数据结构
let arr = [...data];
arr.map((item, index) => {
item.type = "bar";
item.stack = '总量';
item.barWidth = "15";
return item;
});
this.options.series = arr;
}
})
},
handleChartClick (event) { // 获取柱图的点击事件
this.countName = event.name;
this.countNum = event.value;
let dataIndex = event.dataIndex;
let arr = []; // 重新组装不同柱子对应的数据结构
this.copyChartData.forEach((ele, index) => {
arr.push({
name: ele.name,
value: ele.data[dataIndex],
textStyle: this.styleList[index]
})
});
// 重新设置图例与formatter
this.options.legend.data = arr;
this.chartData = arr;
},
setOptionsColor () { // 调色盘颜色列表
let arr = [];
this.styleList.forEach(item => {
arr.push(item.color)
})
this.options.color = arr;
}
}
}
</script>