stackBarChart.vue 9.27 KB
<template>
	<view class="piechart">
		<div :id='bindId' class="chart"></div>
	</view>
</template>

<script>
	export default {
	  data () {
		return {
		}
	  },
	  mounted() {
		   console.log('chartData',this.chartData)
	  },
	  watch:{
		  bindId:function(newValue,oldValue){
		  },
		  chartData:{
			handler(newValue,oldValue){
				this.drawStackBar();
			},
			deep:true
		  },
	  },
	  props:{
			bindId:{
				type:String,
				default:''
			},
		   chartData: {
                type: Object,
                default: function(){
					return {}
				}
            }
	  },
	  methods: {
	  	 drawStackBar() {
           let myChart = {};
           let chartDom = document.getElementById(this.bindId);
           myChart = this.echarts.init(chartDom);
           myChart.showLoading('default', {
               text: '',
               color: '#409eff'
           });
            let option = {
				title :{
					show:true,
					 text:this.chartData.title,
					 left: '13px',
					 top: '13px',
					 textStyle: {
						 fontWeight: "normal",
						 fontSize: 14,
						 color: '#444'
					 }
				},
				color: ["#0069FF", "#3BB8FF", "#87D14B", "#FFC62E", "#FF9631"],
                grid: {
					left: '50px',
					right: '26px',
					top: '55px',
					bottom: '60px'
				},
                legend: {
                    data: [],
                    bottom: 12,
                    textStyle: {
                        color: '#555',
                        fontSize: 12
                    },
                    itemGap: 10,
                    itemWidth: 10,
                    itemHeight: 10
                },
                tooltip: {
                    trigger: 'axis',
                    backgroundColor: '#fff',
                    padding: [0, 0, 0, 0],
                    textStyle: {
                        color: '#333'
                    },
                    axisPointer: {
                        type: 'line',
                        animation: true,
                        lineStyle: {
                            color: 'transparent'
                        }
                    },
                    extraCssText: 'box-shadow: 0px 0px 10px -4px rgba(3, 3, 3, .4)'
                },
                yAxis: {
                    name: '人次',
                    type: 'value',
                    nameRotate: 1,
                    splitLine: {
                        lineStyle: {
                            color: '#EBEBEB'
                        }
                    },
                    axisLine: {
                        lineStyle: {
                            color: '#888'
                        }
                    },
                    axisTick: {
                        show: false
                    },
                    axisLabel: {
                        fontSize: 13,
                        color: '#666'
                    }
                },
                xAxis: {
                    splitLine: {
                        show: false
                    },
                    axisLine: {
                        lineStyle: {
                            color: '#888'
                        }
                    },
                    axisTick: {
                        show: false
                    },
                    axisLabel: {
                        fontSize: 13,
                        color: '#666'
                    },
                    data:[]
                },
				series:this.chartData.series
            };
            if(!option.series) return;
            // 按照 echarts 数据规范重构数据
            let seriesObj = {}, seriesData = [], totalData = [], totalNum = 0, ageArr = [];
            try {
                seriesData = this.chartData.xaxis.data.map(item => {
                    return {
                        name: item,
                        data: []
                    }
                });
                if(option.series.length > 0) {
                    let ageNum;
                    for(let i = 0; i < option.series.length; i++) {
                        ageNum = 0;
                        option.xAxis.data.push(option.series[i].name);
                        for(let j = 0; j < option.series[i].data.length; j++) {
                            seriesObj[this.chartData.xaxis.data[j]] = option.series[i].data[j];
                            totalNum += option.series[i].data[j];
                            ageNum += option.series[i].data[j];
                            for(let k in seriesObj) {
                                if(seriesData[j].name == k) {
                                    seriesData[j].data.push(seriesObj[k])
                                }
                            }
                            seriesObj = {};
                        }
                        ageArr.push(ageNum);
                    }
                }
                for(let i = 0; i < seriesData.length; i++) {
                    seriesData[i].itemStyle = {
                        show: false
                    };
                    seriesData[i].type = 'bar';
                    seriesData[i].stack = 'gender';
                    // seriesData[i].barWidth = 20;
                    // seriesData[i].barCategoryGap = '50px';
                    option.legend.data.push(seriesData[i].name);
                }
                seriesData.forEach(item => {
                    item.data.forEach((k, i) => {
                        if(totalData[i]) {
                            totalData[i] += k;
                        } else {
                            totalData[i] = k;
                        }
                    })
                })
                option.series = seriesData;
                if(!option.series.length) {
                    option.graphic = {
                        type: 'text',
                        left: 'center',
                        top: 'middle',
                        z: 100,
                        style: {
                            fill: '#333',
                            text: '无数据',
                            font: '14px'
                        }
                    }
                    // option.xAxis.data = [];
                    myChart.clear();
                    setTimeout(() => {
                        myChart.hideLoading();
                        myChart.setOption(option);
                    }, 500);
                }
            } catch (error) {}
            option.tooltip.formatter = (params, ticket, callback) => {
                let htmls = '', xaxisName = '', ratio = '', numRatio = '', ageNum = '', ageRatioNum = '', ageRatio = '', ageUnit = '', genderUnit = '', genderNum = '';
                if(params.length > 0) {
                    xaxisName = params[0].axisValue;
                    ageNum = (ageArr[params[0].dataIndex] || ageArr[params[0].dataIndex] == 0) ? (ageArr[params[0].dataIndex] >= 100000 ? (ageArr[params[0].dataIndex] / 10000).toFixed(2) : ageArr[params[0].dataIndex]) : '--';
                    ageUnit = ageArr[params[0].dataIndex] ? ((ageArr[params[0].dataIndex] >= 100000) ? '万人' : '人') : '人';
                    ageRatioNum = ageArr[params[0].dataIndex] / totalNum;
                    ageRatio = ageRatioNum == 0 ? '0%' : (ageRatioNum * 100).toFixed(2) + '%';
                    htmls += '<div style="font-size:16px;height:32px;color:#0069FF;border-radius:4px;line-height:36px;padding-left:15px;padding-right:15px;text-align: left; overflow: hidden;"><span style="float: left; text-align: left;">' + xaxisName + '</span>';
                    htmls += '<span style="float: left; width: 60px; text-align: center; padding: 0 10px;">' + ageNum + ageUnit + '</span>';
                    htmls += '<span style="float: right; width: 60px; text-align: center;">' + ageRatio + '</span></div><div>';
                    for(let j = 0; j < params.length; j++) {
                        // totalNum
                        genderNum = (params[0].data || params[0].data == 0) ? (params[j].data >= 100000 ? (params[j].data / 10000).toFixed(2) : params[j].data) : '--';
                        numRatio = (params[j].data == 0 || totalData[params[j].dataIndex] == 0) ? 0 : params[j].data / totalData[params[j].dataIndex];
                        genderUnit = params[j].data ? (params[j].data >= 100000 ? '万人' : '人') : '人';
                        ratio = numRatio == 0 ? '0%' : (numRatio * 100).toFixed(2) + '%';
                        htmls += '<p style="font-size:14px;padding:4px 23px 6px 15px;color:#333;text-align: center; overflow: hidden;"><span style="float: left; text-align: center;">'+ params[j].seriesName + ':' + '</span>';
                        htmls += '<span style="float: right; text-align: center; width: 60px;">'+ ratio + '</span>';
                        htmls += '<span style="float: right; text-align: center; width: 60px;">'+ genderNum + genderUnit + '</span></p>';
                    }
                    htmls += '</div>';
                    return htmls;
                }
            }
			console.log(option)
            myChart.clear();
            setTimeout(() => {
                myChart.hideLoading();
            }, 500);
            myChart.setOption(option);
		 }
	  }
	}
</script>

<style>
	.chart{
		width:706.52upx;
		height:438.4upx;
		margin: 0 auto;
		box-shadow:0px 0px 7px 0px rgba(0,0,0,0.14);
		border-radius:4px;
		background: #FFFFFF;
		margin-bottom: 18.11upx;;
	}
</style>