Vue +echart 组件化实例
后端基础response
return :{ "code": "状态码", "data": "相关数据", "error": "错误信息" }
1 饼图(图例垂直滑动)
返回数据:
res.data= [ { "hospital_id": 1, "hospital__short_name": "深圳华侨医院", "news_count": 149 }, { "hospital_id": 2, "hospital__short_name": "南方医科大学深圳医院", "news_count": 126 }, ..... ]
vue组件
// 医院新闻总数统计 <template> <div class="com-container"> <div class="com-chart" ref="HospitalNewsCount_ref"></div> </div> </template> <script> import { mapState } from "vuex"; export default { data() { return { chartInstance: null, //echarts实例对象 alldata: null, //服务器获取的所有数据 }; }, computed: { ...mapState(["theme"]) }, watch: { theme() { this.chartInstance.dispose(); this.initChart(); this.screenAdapter(); this.updateChart(); }, }, mounted() { this.initChart(); this.getData(); window.addEventListener("resize", this.screenAdapter); // 在页面加载完成的时候, 主动进行屏幕的适配 this.screenAdapter(); }, destroyed() { // 在组件销毁的时候, 需要将监听器取消掉 window.removeEventListener("resize", this.screenAdapter); }, methods: { // 初始化echartInstance对象 initChart() { this.chartInstance = this.$echarts.init( this.$refs.HospitalNewsCount_ref, this.theme ); // 对图表初始化配置的控制 const initOption = { title: { text: "▎深圳三级医院", subtext: " 来源互联网", left: 10, top: 10, }, tooltip: { trigger: "item", formatter: "{a} <br/>{b} : {c} ({d}%)", }, legend: { type: "scroll", orient: "vertical", right: 10, top: 10, bottom: 10, }, series: [ { name: "医院", type: "pie", radius: "55%", center: ["40%", "50%"], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)", }, }, }, ], }; this.chartInstance.setOption(initOption); }, //获取服务器的数据 async getData() { const { data: ret } = await this.$http.get("map/hospitalnewscount"); this.alldata = ret.data; this.updateChart(); }, //更新图表 updateChart() { const HospitalNames = this.alldata.map((item) => { return item.hospital__short_name; }); const HospitalnewsCount = this.alldata.map((item) => { return { name: item.hospital__short_name, value: item.news_count }; }); // console.log(HospitalNames) // console.log(HospitalnewsCount) const dataOption = { legend: { data: HospitalNames, }, series: [ { data: HospitalnewsCount, }, ], }; this.chartInstance.setOption(dataOption); }, // 当浏览器的大小发生变化的时候, 会调用的方法, 来完成屏幕的适配 screenAdapter() { const titleFontSize = (this.$refs.HospitalNewsCount_ref.offsetWidth / 100) * 3.6; // 和分辨率大小相关的配置项 const adapterOption = { title: { textStyle: { fontSize: titleFontSize, }, }, tooltip: { axisPointer: { lineStyle: { width: titleFontSize, }, }, }, series: [ { barWidth: titleFontSize, itemStyle: { barBorderRadius: [0, titleFontSize / 2, titleFontSize / 2, 0], }, }, ], }; this.chartInstance.setOption(adapterOption); // 手动的调用图表对象的resize 才能产生效果 this.chartInstance.resize(); }, }, }; </script> <style> </style>
2 南丁格尔图
data
res.data=[ { "name": "深圳", "value": 99 }, { "name": "华侨", "value": 84 }...]
vue组件
// 舆情关键词分布 <template> <div class="com-container"> <div class="com-chart" ref="NewsKeyWord_ref"></div> </div> </template> <script> import { mapState } from "vuex"; export default { data() { return { chartInstance: null, //echarts实例对象 alldata: null, //服务器获取的所有数据 }; }, computed: { ...mapState(["theme"]) }, watch: { theme() { this.chartInstance.dispose(); this.initChart(); this.screenAdapter(); this.updateChart(); }, }, mounted() { this.initChart(); this.getData(); window.addEventListener("resize", this.screenAdapter); // 在页面加载完成的时候, 主动进行屏幕的适配 this.screenAdapter(); }, destroyed() { // 在组件销毁的时候, 需要将监听器取消掉 window.removeEventListener("resize", this.screenAdapter); }, methods: { // 初始化echartInstance对象 initChart() { this.chartInstance = this.$echarts.init(this.$refs.NewsKeyWord_ref, this.theme); // 对图表初始化配置的控制 const initOption = { title: { text: "▎舆情关键字", left: 10, top: 10, }, legend: { type: ‘scroll‘, orient: ‘horizontal‘, bottom: ‘1%‘ }, toolbox: { show: true, feature: { mark: {show: true}, dataView: {show: true, readOnly: false}, // restore: {show: true}, // saveAsImage: {show: true} } }, series: [ { name: ‘情感分析‘, type: ‘pie‘, radius: [10, 130], center: [‘50%‘, ‘50%‘], roseType: ‘area‘, itemStyle: { borderRadius: 8 }, data: [ ] } ] }; this.chartInstance.setOption(initOption); }, //获取服务器的数据 async getData() { // http://127.0.0.1:8000/api/map/NewsKeyword/1 const { data: ret } = await this.$http.get("map/news_keyword_rank/1"); this.alldata = ret; // console.log(this.alldata) this.updateChart(); }, //更新图表 updateChart() { const NewsKeywordNames = this.alldata.data.type; const NewsKeywordnewsCount = this.alldata.data.count; const dataOption = { series: [ { data: this.alldata.data, }, ], }; this.chartInstance.setOption(dataOption); }, // 当浏览器的大小发生变化的时候, 会调用的方法, 来完成屏幕的适配 screenAdapter() { // console.log(this.$refs.media_ref.offsetWidth) const titleFontSize = (this.$refs.NewsKeyWord_ref.offsetWidth / 100) * 3.6; // 和分辨率大小相关的配置项 const adapterOption = { title: { textStyle: { fontSize: titleFontSize, }, }, tooltip: { axisPointer: { lineStyle: { width: titleFontSize, }, }, }, series: [ { barWidth: titleFontSize, itemStyle: { barBorderRadius: [0, titleFontSize / 2, titleFontSize / 2, 0], }, }, ], }; this.chartInstance.setOption(adapterOption); // 手动的调用图表对象的resize 才能产生效果 this.chartInstance.resize(); }, }, }; </script> <style> </style>
3 词云图
data
res.data=[ { "name": "深圳", "value": 99 }, { "name": "华侨", "value": 84 }...]
vue
导入echarts-wordcloud
<script src="static/lib/echarts.min.js"></script> <script src="static/lib/echarts-wordcloud.min.js"></script> <script src="static/theme/chalk.js"></script> <script src="static/theme/vintage.js"></script>
// 关键字云图展示 <template> <div class="com-container"> <div class="com-chart" ref="yuntu_ref"></div> </div> </template> <script> import { mapState } from "vuex"; export default { data() { return { chartInstance: null, //echarts实例对象 alldata: null, //服务器获取的所有数据 }; }, computed: { ...mapState(["theme"]) }, watch: { theme() { this.chartInstance.dispose(); this.initChart(); this.screenAdapter(); this.updateChart(); }, }, mounted() { this.initChart(); this.getData(); window.addEventListener("resize", this.screenAdapter); 在页面加载完成的时候, 主动进行屏幕的适配 this.screenAdapter(); }, destroyed() { // 在组件销毁的时候, 需要将监听器取消掉 window.removeEventListener("resize", this.screenAdapter); }, methods: { // 初始化echartInstance对象 initChart() { this.chartInstance = this.$echarts.init(this.$refs.yuntu_ref, this.theme); const initOption = { tooltip: {}, series: [ { type: "wordCloud", gridSize: 1, //网格大小越大,单词之间的差距就越大 sizeRange: [12,60], //文字大小范围 rotationRange: [-45, 0, 45, 90], // shape: "pentagon", // circle,pentagon width: ‘100%‘, height: ‘100%‘, // drawOutOfBound: true, textStyle: { color: function () { return ( "rgb(" + [ Math.round(Math.random() * 160), Math.round(Math.random() * 160), Math.round(Math.random() * 160), ].join(",") + ")" ); }, }, emphasis: { textStyle: { shadowBlur: 10, shadowColor: "#333", }, }, data: [], }, ], }; this.chartInstance.setOption(initOption); }, //获取服务器的数据 async getData() { // http://127.0.0.1:8000/api/map/media/1 const { data: ret } = await this.$http.get("map/news_yuntu/1"); this.alldata = ret; // console.log(this.alldata) this.updateChart(); }, //更新图表 updateChart() { const data = this.alldata.data; const dataOption = { series: [ { data: data, }, ], }; this.chartInstance.setOption(dataOption); }, // 当浏览器的大小发生变化的时候, 会调用的方法, 来完成屏幕的适配 screenAdapter() { // console.log(this.$refs.media_ref.offsetWidth) const titleFontSize = (this.$refs.yuntu_ref.offsetWidth / 100) * 3.6; // 和分辨率大小相关的配置项 const adapterOption = { title: { textStyle: { fontSize: titleFontSize, }, }, tooltip: { axisPointer: { lineStyle: { width: titleFontSize, }, }, }, series: [ { barWidth: titleFontSize, itemStyle: { barBorderRadius: [0, titleFontSize / 2, titleFontSize / 2, 0], }, }, ], }; this.chartInstance.setOption(adapterOption); // 手动的调用图表对象的resize 才能产生效果 this.chartInstance.resize(); }, }, }; </script> <style lang="less" scoped> </style>
4 折线图-柱状图切换
data
res.data={ "2020":{ title:"2020舆情数量统计", "util":"条", "data":[ {"name":"正面","data":[1-12月份数据]}, {"name":"负面","data":[1-12月份数据]}, {"name":"中性","data":[1-12月份数据]}, ] }, "2021":{} "common": {"month": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]} "type": [{"key": "2020","text": "2020舆情数量统计"},{"key": "2021","text": "2021舆情数量统计"}] }
vue
//舆情情感统计 <template> <div class="com-container"> <div class="title" :style="comStyle"> <span style="font-size: small">{{ "▎ " + showTitle }}</span> <span class="iconfont title-icon" :style="comStyle" @click="showChoice = !showChoice" ></span > <div class="select-con" v-show="showChoice" :style="marginStyle"> <div class="select-item" style="font-size: small" v-for="item in selectTypes" :key="item.key" @click="handleSelect(item.key)" > {{ item.text }} </div> </div> </div> <div class="com-chart" ref="trend_ref"></div> </div> </template> <script> import { mapState } from "vuex"; import { getThemeValue } from ‘@/utils/theme_utils‘ export default { data() { return { chartInstane: null, allData: null, // 从服务器中获取的所有数据 showChoice: false, // 是否显示可选项 choiceType: "2021", // 显示的数据类型 titleFontSize: 0, // 指明标题的字体大小 }; }, // computed: { ...mapState(["theme"]) }, mounted() { this.initChart(); this.getData(); window.addEventListener("resize", this.screenAdapter); this.screenAdapter(); }, destroyed() { window.removeEventListener("resize", this.screenAdapter); }, computed: { selectTypes() { if (!this.allData) { return []; } else { return this.allData.type.filter((item) => { return item.key !== this.choiceType; }); } }, showTitle() { if (!this.allData) { return ""; } else { return this.allData[this.choiceType].title; } }, // 设置给标题的样式 comStyle() { return { fontSize: this.titleFontSize + "px", }; }, marginStyle() { return { marginLeft: this.titleFontSize + "px", }; }, ...mapState(["theme"]), comStyle () { return { fontSize: this.titleFontSize + ‘px‘, color: getThemeValue(this.theme).titleColor } }, }, methods: { initChart() { this.chartInstane = this.$echarts.init(this.$refs.trend_ref, this.theme); const initOption = { grid: { left: "3%", top: "35%", right: "4%", bottom: "1%", containLabel: true, }, tooltip: { trigger: "axis", }, toolbox: { show: true, feature: { dataView: { show: true, readOnly: false }, magicType: { show: true, type: ["line", "bar"] }, restore: { show: true }, saveAsImage: { show: true }, }, }, legend: { right: 7, top: "15%", icon: "circle", }, xAxis: { type: "category", boundaryGap: false, }, yAxis: { type: "value", }, }; this.chartInstane.setOption(initOption); }, async getData() { // await this.$http.get() // 对allData进行赋值 const { data: ret } = await this.$http.get("map/news_polarity/1"); this.allData = ret; // console.log(this.allData) this.updateChart(); }, updateChart() { // 半透明的颜色值 const colorArr1 = [ "rgba(11, 168, 44, 0.5)", "rgba(44, 110, 255, 0.5)", "rgba(22, 242, 217, 0.5)", "rgba(254, 33, 30, 0.5)", "rgba(250, 105, 0, 0.5)", ]; // 全透明的颜色值 const colorArr2 = [ "rgba(11, 168, 44, 0)", "rgba(44, 110, 255, 0)", "rgba(22, 242, 217, 0)", "rgba(254, 33, 30, 0)", "rgba(250, 105, 0, 0)", ]; // 处理数据 // 类目轴的数据 const timeArr = this.allData.common.month; // y轴的数据 series下的数据 const valueArr = this.allData[this.choiceType].data; const seriesArr = valueArr.map((item, index) => { return { name: item.name, type: "line", data: item.data, stack: this.choiceType, areaStyle: { color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: colorArr1[index], }, // %0的颜色值 { offset: 1, color: colorArr2[index], }, // 100%的颜色值 ]), }, }; }); // 图例的数据 const legendArr = valueArr.map((item) => { return item.name; }); const dataOption = { xAxis: { data: timeArr, }, legend: { data: legendArr, }, series: seriesArr, }; this.chartInstane.setOption(dataOption); }, screenAdapter() { this.titleFontSize = (this.$refs.trend_ref.offsetWidth / 100) * 3.6; const adapterOption = { legend: { itemWidth: this.titleFontSize, itemHeight: this.titleFontSize, itemGap: this.titleFontSize, textStyle: { fontSize: this.titleFontSize / 2, }, }, }; this.chartInstane.setOption(adapterOption); this.chartInstane.resize(); }, handleSelect(currentType) { this.choiceType = currentType; this.updateChart(); this.showChoice = false; }, }, watch: { theme() { this.chartInstane.dispose(); this.initChart(); this.screenAdapter(); this.updateChart(); }, }, }; </script> <style lang="less" scoped> .title { position: absolute; left: 20px; top: 10px; z-index: 10; color: white; .title-icon { margin-left: 10px; cursor: pointer; } .select-con { background-color: #222733; } } </style>
原文:https://www.cnblogs.com/huahuawang/p/14876350.html