zoukankan      html  css  js  c++  java
  • 动态配置生成echarts图表

    动态配置x轴和y轴的数据,并且可以选择柱状图、折线图、饼状图等图形

    父组件代码:

    <template>
      <div class="reportPicture">
        <div class="reportPicture_inner">
          <header>
            <span>图形设置</span>
            <ul>
              <li
                v-for="(item,index) in  graphList"
                :key="item.id"
                :class="{ 'highLight':index == currentIndex }"
                @click="currentIndex = index;currentType = item.type"
              >
                <img :src="graphIcon(item.type)" />
                <span>{{item.name}}</span>
              </li>
            </ul>
          </header>
          <main>
            <aside>
              <el-tabs v-model="activeTab">
                <el-tab-pane label="X轴" name="x">
                  <div class="tab_item">
                    <ul>
                      <el-scrollbar style="height: 100%">
                        <li
                          v-for="item in xList"
                          :key="item.id"
                          :class="{'highLight':item.selected}"
                          @click="toggleSeletX(item)"
                        >
                          {{item.name}}
                        </li>
                      </el-scrollbar>
                    </ul>
                  </div>
                </el-tab-pane>
                <el-tab-pane label="Y轴" name="y">
                  <div class="tab_item" v-show="showTwo">
                    <section>
                      <span>柱状:</span>
                      <ul>
                        <el-scrollbar style="height: 100%">
                          <li
                            v-for="item in barList"
                            :key="item.id"
                            :class="{'highLight':item.selected}"
                            @click="toggleSelet(item)"
                          >
                            {{item.name}}
                          </li>
                        </el-scrollbar>
                      </ul>
                    </section>
                    <section>
                      <span>折线:</span>
                      <ul>
                        <el-scrollbar style="height: 100%">
                          <li
                            v-for="item in lineList"
                            :key="item.id"
                            :class="{'highLight':item.selected}"
                            @click="toggleSelet(item)"
                          >
                            {{item.name}}
                          </li>
                        </el-scrollbar>
                      </ul>
                    </section>
                  </div>
                  <ul v-show="!showTwo">
                    <el-scrollbar style="height: 100%">
                      <li
                        v-for="item in yList"
                        :key="item.id"
                        :class="{'highLight':item.selected}"
                        @click="toggleSelet(item)"
                      >
                        {{item.name}}
                      </li>
                    </el-scrollbar>
                  </ul>
                </el-tab-pane>
              </el-tabs>
              <footer>
                <el-button
                  size="mini"
                  type="danger"
                  plain
                  @click="handle_addPicture"
                  >生成图形</el-button
                >
                <el-button size="mini" type="danger" @click="saveImage"
                  >保存图形</el-button
                >
              </footer>
            </aside>
            <main>
              <header>
                <div class="input_box">
                  <el-input
                    size="mini"
                    type="text"
                    placeholder="请输入"
                    v-model="chartData.title"
                    clearable
                  ></el-input>
                </div>
              </header>
              <div class="chart_box">
                <div id="chart">
                  <line-chart
                    ref="line"
                    class="line"
                    v-if="currentType == 'line'"
                    :chartData="chartData"
                  />
                  <pie-chart
                    ref="pie"
                    class="pie"
                    v-if="currentType == 'pie'"
                    :chartData="chartData"
                  />
                  <bar-chart
                    ref="bar2"
                    class="bar2"
                    v-if="currentType == 'bar2'"
                    :chartData="chartData"
                  />
                  <bar-chart-horizental
                    ref="bar1"
                    class="bar1"
                    v-if="currentType == 'bar1'"
                    :chartData="chartData"
                  />
                  <line-bar-chart
                    ref="lineBar"
                    class="lineBar"
                    v-if="currentType == 'lineBar'"
                    :chartData="chartData"
                  />
                </div>
              </div>
            </main>
          </main>
        </div>
      </div>
    </template>
    <script> 
    import echarts from 'echarts';
    import PieChart from '@/views/dashboard/PieChart';
    import BarChart from '@/views/dashboard/BarChart';
    import LineChart from '@/views/dashboard/LineChart';
    import BarChartHorizental from '@/views/dashboard/BarChartHorizental';
    import LineBarChart from '@/views/dashboard/LineBarChart';
    export default {
    	name: 'reportPicture',
    	components: {
    		LineChart, PieChart, BarChart, BarChartHorizental, LineBarChart
    	},
    	data() {
    		return {
    			activeTab: 'x',
    			graphList: [{
    				id: 1,
    				type: 'pie',
    				name: '饼状图'
    			}, {
    				id: 2,
    				type: 'bar1',
    				name: '柱状图(橫)'
    			}, {
    				id: 3,
    				type: 'line',
    				name: '折线图'
    			}, {
    				id: 4,
    				type: 'bar2',
    				name: '柱状图(竖)'
    			}, {
    				id: 5,
    				type: 'lineBar',
    				name: '柱状+折线'
    			}],
    			currentIndex: 0,
    			xList: [{
    				id: 1,
    				name: '轴1',
    				selected: false,
    				children: ['江干区1', '西湖区1', '拱墅区1', '余杭区1', '临安1']
    			}, {
    				id: 2,
    				name: '轴2',
    				selected: false,
    				children: ['江干区2', '西湖区2', '拱墅区2', '余杭区2', '临安2']
    			}, {
    				id: 3,
    				name: '轴3',
    				selected: false,
    				children: ['江干区3', '西湖区3', '拱墅区3', '余杭区3', '临安3']
    			}, {
    				id: 4,
    				name: '轴4',
    				selected: false,
    				children: ['江干区4', '西湖区4', '拱墅区4', '余杭区4', '临安4']
    			}],
    			yList: [{
    				id: 1,
    				name: '控件1',
    				selected: false,
    				seritesObj: {
    					name: '控件1',
    					data: [79, 254, 200, 334, 390, 320, 220],
    					dataPie: [{
    						value: 40,
    						name: '江干区'
    					}, {
    						value: 38,
    						name: '西湖区'
    					}, {
    						value: 32,
    						name: '拱墅区'
    					}, {
    						value: 30,
    						name: '余杭区'
    					}, {
    						value: 28,
    						name: '临安'
    					}]
    				}
    			}, {
    				id: 2,
    				name: '控件2',
    				selected: false,
    				seritesObj: {
    					name: '控件2',
    					data: [179, 52, 200, 334, 390, 330, 220],
    					dataPie: [{
    						value: 45,
    						name: '江干区'
    					}, {
    						value: 38,
    						name: '西湖区'
    					}, {
    						value: 32,
    						name: '拱墅区'
    					}, {
    						value: 30,
    						name: '余杭区'
    					}, {
    						value: 28,
    						name: '临安'
    					}]
    				}
    			}, {
    				id: 3,
    				name: '控件3',
    				selected: false,
    				seritesObj: {
    					name: '控件3',
    					data: [79, 452, 260, 334, 390, 350, 220],
    					dataPie: [{
    						value: 49,
    						name: '江干区'
    					}, {
    						value: 38,
    						name: '西湖区'
    					}, {
    						value: 32,
    						name: '拱墅区'
    					}, {
    						value: 30,
    						name: '余杭区'
    					}, {
    						value: 28,
    						name: '临安'
    					}]
    				}
    			}, {
    				id: 4,
    				name: '控件4',
    				selected: false,
    				seritesObj: {
    					name: '控件4',
    					data: [79, 52, 250, 334, 320, 330, 220],
    					dataPie: [{
    						value: 50,
    						name: '江干区'
    					}, {
    						value: 38,
    						name: '西湖区'
    					}, {
    						value: 32,
    						name: '拱墅区'
    					}, {
    						value: 30,
    						name: '余杭区'
    					}, {
    						value: 28,
    						name: '临安'
    					}]
    				}
    			}],
    			barList: [{
    				id: 1,
    				chartType: 'bar',
    				name: '控件1',
    				selected: false,
    				seritesObj: {
    					name: '控件1',
    					data: [79, 254, 200, 334, 390, 320, 220]
    				}
    			}, {
    				id: 2,
    				chartType: 'bar',
    				name: '控件2',
    				selected: false,
    				seritesObj: {
    					name: '控件2',
    					data: [179, 52, 200, 334, 390, 330, 220]
    				}
    			}, {
    				id: 3,
    				chartType: 'bar',
    				name: '控件3',
    				selected: false,
    				seritesObj: {
    					name: '控件3',
    					data: [79, 452, 260, 334, 390, 350, 220]
    				}
    			}, {
    				id: 4,
    				chartType: 'bar',
    				name: '控件4',
    				selected: false,
    				seritesObj: {
    					name: '控件4',
    					data: [79, 52, 250, 334, 320, 330, 220]
    				}
    			}],
    			lineList: [{
    				id: 1,
    				chartType: 'line',
    				name: '控件1',
    				selected: false,
    				seritesObj: {
    					name: '控件1',
    					data: [79, 254, 200, 334, 390, 320, 220]
    				}
    			}, {
    				id: 2,
    				chartType: 'line',
    				name: '控件2',
    				selected: false,
    				seritesObj: {
    					name: '控件2',
    					data: [179, 52, 200, 334, 390, 330, 220]
    				}
    			}, {
    				id: 3,
    				chartType: 'line',
    				name: '控件3',
    				selected: false,
    				seritesObj: {
    					name: '控件3',
    					data: [79, 452, 260, 334, 390, 350, 220]
    				}
    			}, {
    				id: 4,
    				chartType: 'line',
    				name: '控件4',
    				selected: false,
    				seritesObj: {
    					name: '控件4',
    					data: [79, 52, 250, 334, 320, 330, 220]
    				}
    			}],
    			showTwo: false,
    			currentType: 'pie',
    			chartData: {
    				xData: [],
    				series: [],
    				legend: [],
    				title: ''
    			},
    			chartTitle: '',
    			seritesObj: {},
    			seritesObjBar: {},
    			seritesObjLine: {}
    		};
    	},
    	watch: {
    		currentType: {
    			handler(newVal, oldVal) {
    				this.yList.map(item = > {
    					item.selected = false;
    				});
    				this.chartData.series = [];
    				this.chartData.legend = [];
    				this.seritesObj.name = '';
    				this.seritesObj.data = [];
    				switch (newVal) {
    				case 'pie':
    					this.showTwo = false;
    					break;
    				case 'line':
    					this.showTwo = false;
    					break;
    				case 'bar1':
    					this.showTwo = false;
    					break;
    				case 'bar2':
    					this.showTwo = false;
    					break;
    				case 'lineBar':
    					this.showTwo = true;
    					break;
    				}
    			}, deep: true,
    			immediate: true
    		}
    	},
    	methods: {
    		graphIcon(type) {
    			let img = '';
    			switch (type) {
    			case 'pie':
    				img = require('@/assets/image/icon_pie.png');
    				this.seritesObj = {
    					type: 'pie',
    					roseType: 'radius',
    					// radius: [15, 95],
    					center: ['50%', '50%'],
    					animationEasing: 'cubicInOut',
    					animationDuration: 2600
    				};
    				break;
    			case 'line':
    				img = require('@/assets/image/icon_line.png');
    				this.seritesObj = {
    					smooth: true,
    					type: 'line',
    					animationDuration: 2800,
    					animationEasing: 'cubicInOut'
    				};
    				break;
    			case 'bar1':
    				img = require('@/assets/image/icon_bar_horizontal.png');
    				this.seritesObj = {
    					type: 'bar',
    					stack: 'vistors',
    					barWidth: '60%'
    				};
    				break;
    			case 'bar2':
    				img = require('@/assets/image/icon_bar_vertical.png');
    				break;
    			case 'lineBar':
    				img = require('@/assets/image/icon_line.png');
    				this.seritesObj = {
    					type: 'bar',
    					stack: 'vistors',
    					barWidth: '60%'
    				};
    				break;
    			}
    			return img;
    		}, 
    		toggleSeletX(item) {
    			this.xList.map(it = > {
    				it.selected = false;
    			});
    			item.selected = true;
    			this.chartData.xData = item.children;
    			console.log(this.chartData.series, 'this.chartData.series');
    			if (this.currentType == 'pie') {}
    			if (this.chartData.series && this.chartData.series.length > 0) {
    				this.chartData.series[0].data.map((ite, index) = > {
    					item.children.map((it, i) = > {
    						if (index == i) {
    							ite.name = it;
    						}
    					});
    				});
    			}
    		}, 
    	        toggleSelet(item) {
    			if (this.currentType == 'pie') {
    				this.yList.map(it = > {
    					it.selected = false;
    				});
    				item.selected = true;
    			} else {
    				item.selected = !item.selected;
    			}
    			switch (this.currentType) {
    			case 'pie':
    				this.seritesObj = {
    					type: 'pie',
    					roseType: 'radius',
    					// radius: [15, 95],
    					// center: ['50%', '50%'],
    					animationEasing: 'cubicInOut',
    					animationDuration: 2600
    				};
    				break;
    			case 'line':
    				this.seritesObj = {
    					smooth: true,
    					type: 'line',
    					animationDuration: 2800,
    					animationEasing: 'cubicInOut'
    				};
    				break;
    			case 'bar1':
    				this.seritesObj = {
    					type: 'bar',
    					stack: 'vistors',
    					barWidth: '60%'
    				};
    				break;
    			case 'bar2':
    				this.seritesObj = {
    					type: 'bar',
    					stack: 'vistors',
    					barWidth: '60%'
    				};
    				break;
    			case 'lineBar':
    				this.seritesObjBar = {
    					type: 'bar',
    					stack: 'vistors',
    					barWidth: '60%',
    					offset: 80
    				};
    				this.seritesObjLine = {
    					smooth: true,
    					type: 'line',
    					animationDuration: 2800,
    					animationEasing: 'cubicInOut'
    				};
    				break;
    			}
    
    			this.seritesObj.name = item.name;
    			let $name_index = this.chartData.legend.indexOf(item.name);
    			let arr = [];
    			if (this.currentType == 'pie') {
    				// 饼图
    				this.chartData.xData.map((ite, index) = > {
    					item.seritesObj.dataPie.map((it, i) = > {
    						if (index == i) {
    							it.name = ite;
    						}
    					});
    				});
    				this.seritesObj.data = item.seritesObj.dataPie;
    				this.chartData.series = [];
    				this.chartData.series.push(this.seritesObj);
    			} else if (this.currentType == 'lineBar') {
    				// 柱状+折线
    				if (item.chartType == 'bar') {
    					this.seritesObjBar.name = item.name;
    				} else {
    					this.seritesObjLine.name = item.name;
    				}
    				if (item.selected) {
    					this.chartData.legend.push(item.name);
    					if (item.chartType == 'bar') {
    						this.seritesObjBar.data = item.seritesObj.data;
    						this.chartData.series.push(this.seritesObjBar);
    					} else {
    						this.seritesObjLine.data = item.seritesObj.data;
    						this.chartData.series.push(this.seritesObjLine);
    					}
    				} else {
    					this.chartData.legend.splice($name_index, 1);
    					console.log(this.chartData.series, 'this.chartData.series');
    					this.chartData.series.map((it, i) = > {
    						if (it.name == item.name) {
    							this.chartData.series.splice(i, 1);
    						}
    					});
    				}
    				// console.log(this.chartData.series, 'this.chartData.series');
    			} else {
    				this.seritesObj.data = item.seritesObj.data;
    				if (item.selected) {
    					this.chartData.legend.push(item.name);
    					this.chartData.series.push(this.seritesObj);
    				} else {
    					this.chartData.legend.splice($name_index, 1);
    					this.chartData.series.map((it, i) = > {
    						if (it.name == item.name) {
    							this.chartData.series.splice(i, 1);
    						}
    					});
    				}
    			}
    			this.chartData.legend = [...new Set(this.chartData.legend)];
    		}, 
    		handle_addPicture() {
    			switch (this.currentType) {
    			case 'pie':
    				this.$refs.pie.initChart();
    				break;
    			case 'line':
    				this.$refs.line.initChart();
    				break;
    			case 'bar1':
    				this.$refs.bar1.initChart();
    				break;
    			case 'bar2':
    				this.$refs.bar2.initChart();
    				break;
    			case 'lineBar':
    				this.$refs.lineBar.initChart();
    				break;
    			}
    		},
    		// 保存图片
    		saveImage() {
    			// 请求接口成功后返回列表页面
    			this.$message({
    				type: 'success',
    				message: '保存成功!'
    			});
    			this.$router.go(-1);
    		},
    		//下载图片
    		downloadFile() {
    			let aLink = document.createElement('a');
    			let blob = this.base64ToBlob();
    			let evt = document.createEvent('HTMLEvents');
    			evt.initEvent('click', true, true);
    			aLink.download = chartData.title ? chartData.title : '报表图形'; //下载图片的名称
    			aLink.href = URL.createObjectURL(blob);
    			aLink.click();
    		}, 
    		exportImg() {
    			//echart返回一个 base64 的 URL
    			let myChart = echarts.init(document.getElementsByClassName(this.currentType)[0]);
    			console.log(myChart, 'myChart');
    			return myChart.getDataURL({
    				type: 'png',
    				pixelRatio: 1,
    				backgroundColor: '#fff'
    			});
    		}, 
    		base64ToBlob() {
    			//将base64转换blob
    			let img = this.exportImg();
    			let parts = img.split(';base64,');
    			let contentType = parts[0].split(':')[1];
    			let raw = window.atob(parts[1]);
    			let rawLength = raw.length;
    			let uInt8Array = new Uint8Array(rawLength);
    			for (let i = 0; i < rawLength; ++i) {
    				uInt8Array[i] = raw.charCodeAt(i);
    			}
    			return new Blob([uInt8Array], {
    				type: contentType
    			});
    		}
    	}
    }; 
    </script>    
    
    <style lang="scss" scoped>
    @import '@/assets/styles/variables.scss';
    .reportPicture {
         100%;
        height: 100%;
        padding: 12px 20px;
        background-color: #f7f7f7;
        .reportPicture_inner {
             100%;
            height: 100%;
            border-radius: 6px;
            background-color: #fff;
            // padding: 20px 15px;
            & > header {
                padding: 20px 16px;
                display: flex;
                align-items: center;
                border-bottom: 1px solid #ececec;
                & > span {
                    margin-right: 15px;
                    font-size: 14px;
                }
                & > ul {
                    display: flex;
                    align-items: center;
                    list-style: none;
                    margin: 0;
                    padding: 0;
                    & > li {
                        padding: 0 12px;
                        min- 130px;
                        height: 38px;
                        border: 1px solid #e6e5e5;
                        background-color: #fff;
                        border-radius: 24px;
                        display: flex;
                        align-items: center;
                        margin-right: 10px;
                        cursor: pointer;
                        &.highLight {
                            border: 1px solid $themeColor;
                        }
                        img {
                             20px;
                            margin-right: 10px;
                        }
                        span {
                            font-size: 14px;
                        }
                    }
                }
            }
            & > main {
                padding: 20px;
                height: 80%;
                display: flex;
                .text {
                    font-size: 14px;
                    margin-right: 10px;
                }
                & > aside,
                & > main {
                    background-color: #fff;
                }
                & > aside {
                     20%;
                    height: 100%;
                    display: flex;
                    flex-direction: column;
                    background-color: #fff;
                    margin: 0;
                    margin-right: 10px;
                    padding: 0 12px;
                    /deep/ .el-tabs {
                        display: flex;
                        flex-direction: column;
                        height: 100%;
                        .el-tabs__content {
                            flex: 1;
                            height: 100%;
                            .el-tab-pane {
                                height: 100%;
                            }
                        }
                        .el-tabs__item {
                            &.is-active,
                            &:hover {
                                color: $themeColor !important;
                            }
                        }
                        .el-tabs__active-bar {
                            background-color: $themeColor;
                        }
                    }
                    .tab_item {
                        height: 100%;
                    }
                    section {
                        display: flex;
                        margin-bottom: 20px;
                        height: 47%;
                        & > span {
                            font-size: 14px;
                        }
                    }
                    ul {
                        flex: 1;
                        height: 100%;
                        list-style: none;
                        padding: 0;
                        margin: 0;
                        border-radius: 4px;
                        border: solid 1px #e6e5e5;
                        /deep/.el-scrollbar__wrap {
                            overflow-x: hidden;
                        }
                        li {
                            line-height: 30px;
                            color: #333;
                            font-size: 14px;
                            padding-left: 10px;
                            border-radius: 3px;
                            margin-bottom: 4px;
                            cursor: pointer;
                            overflow: hidden;
                            text-overflow: ellipsis;
                            white-space: nowrap;
                            &.highLight {
                                background-color: $themeColor;
                                color: #fff;
                            }
                        }
                    }
                    & > footer {
                        height: 5%;
                        margin-top: 10px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                    }
                }
                & > main {
                    flex: 1;
                    display: flex;
                    flex-direction: column;
                    border: solid 1px #e6e5e5;
                    border-radius: 4px;
                    & > header {
                        height: 42px;
                        background-color: #f9f9f9;
                        display: flex;
                        align-items: center;
                        padding-left: 10px;
                        .input_box {
                             400px;
                        }
                    }
                    .chart_box {
                        flex: 1;
                        padding: 20px;
                        #chart {
                             100%;
                            height: 100%;
                        }
                    }
                }
            }
        }
    }
    </style>
    

    子组件:

    <template>
      <div :class="className" :style="{height:height,width}" />
    </template>
    
    <script>
    import echarts from 'echarts';
    require('echarts/theme/macarons'); // echarts theme
    import resize from './mixins/resize';
    
    const animationDuration = 6000;
    
    export default {
        mixins: [resize],
        props: {
            className: {
                type: String,
                default: 'chart'
            },
             {
                type: String,
                default: '100%'
            },
            height: {
                type: String,
                default: '100%'
            },
            chartData: {
                type: Object
            }
        },
        data() {
            return {
                chart: null
            };
        },
        mounted() {
            this.$nextTick(() => {
                this.initChart();
            });
        },
        beforeDestroy() {
            if (!this.chart) {
                return;
            }
            this.chart.dispose();
            this.chart = null;
        },
        methods: {
            initChart() {
                this.chart = echarts.init(this.$el);
                this.chart.clear();
                this.setOptions(this.chartData);
            },
            setOptions({ xData, series, legend, title } = {}) {
                this.chart.setOption({
                    title: {
                        text: title
                    },
                    tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            // 坐标轴指示器,坐标轴触发有效
                            type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
                        }
                    },
                    grid: {
                        // top: 10,
                        left: '2%',
                        right: '2%',
                        bottom: '3%',
                        containLabel: true
                    },
                    legend: {
                        data: legend
                    },
                    xAxis: [
                        {
                            type: 'category',
                            data: xData,
                            axisTick: {
                                alignWithLabel: true
                            }
                        }
                    ],
                    yAxis: [
                        {
                            type: 'value',
                            axisTick: {
                                show: false
                            }
                        }
                    ],
                    series: series
                });
            }
        }
    };
    </script>
    

      

  • 相关阅读:
    收集Linux常用命令
    loadrunner没有告诉你的
    loadrunner没有告诉你的
    loadrunner没有告诉你的
    QA、EPG、PMO各自的职能划分及关系是什么?
    QA、EPG、PMO各自的职能划分及关系是什么?
    QA、EPG、PMO各自的职能划分及关系是什么?
    loadrunner通过odbc测mysql数据库语句
    loadrunner通过odbc测mysql数据库语句
    loadrunner通过odbc测mysql数据库语句
  • 原文地址:https://www.cnblogs.com/florazeng/p/14622361.html
Copyright © 2011-2022 走看看