Echarts实现男女比例图表

实现用 Echarts 图表库完成一个展示 男女比例 的效果图 :

示例 代码如下 :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .chart {
        width: 300px;
        height: 200px;
        border: 1px solid red;
      }
    </style>
  </head>
  <body>
    <div class="chart" id="chart"></div>
    <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
    <script>
      // 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById("chart"));
      var man = `path://M516.608 217.6c40.448 0 72.704-32.768 72.704-72.704 0-40.448-32.768-72.704-72.704-72.704-40.448 0-72.704 32.768-72.704 72.704s32.256 72.704 72.704 72.704z m80.384 18.432H435.712c-51.2 0-93.696 41.472-93.696 93.184v225.28c0 17.408 13.824 31.744 31.232 31.744s31.744-14.336 31.744-31.744V351.744h16.384v565.76c0 23.552 18.944 42.496 43.008 42.496 23.552 0 42.496-18.944 42.496-42.496V588.8h17.408v328.192c0 23.552 18.944 42.496 42.496 42.496 23.552 0 43.008-18.944 43.008-42.496V351.744h16.384v203.264c0 17.408 14.336 31.744 31.744 31.744 17.408 0 31.232-14.336 31.232-31.744v-225.28c1.024-51.712-40.96-93.696-92.16-93.696z`;
      var girl = `path://M693.064905 504.590142l-55.845778-202.954549c-7.532724-22.967796-34.488553-63.372358-79.685923-65.239925h-89.777337c-46.750604 1.927976-73.520086 41.894316-80.000256 65.365863l-55.777177 202.707792c-11.954885 44.266658 39.220951 61.57032 51.857744 19.985218l49.867311-187.020846h14.008799l-85.85176 328.529989h80.247012v246.909946c0 44.697714 60.764522 44.697714 60.764522 0v-246.909946h18.924473v246.909946c0 44.697714 58.766922 44.697714 58.766922 0v-246.909946h82.427888l-87.654823-328.529989h15.938823l49.988129 187.020846c12.331675 42.517862 63.256659 24.280417 51.801431-19.864399zM512.336858 219.833299c38.471467 0 69.538196-32.435663 69.538196-72.527941 0-40.031868-31.066729-72.528965-69.538196-72.528965-38.415154 0-69.48393 32.497096-69.48393 72.528965 0 40.030845 31.0698 72.527941 69.48393 72.527941z`;
      var option1 = {};
      var option2 = {};
      function mans(mannum, max) {
        option1 = {
          color: ["#29D7A8", "#3C404C"],
          tooltip: {
            show: false,
          },
          xAxis: {
            type: "value",
            max: max,
            splitLine: { show: false },
            offset: 10,
            axisLine: {
              show: false,
              lineStyle: {
                color: "#999",
              },
            },
            axisLabel: {
              show: false,
              margin: 10,
            },
          },
          yAxis: {
            type: "category",
            data: ["男"],
            inverse: true,
            axisTick: { show: false },
            axisLine: { show: false },
            axisLabel: {
              show: false,
              margin: 10,
              color: "#999",
              fontSize: 16,
            },
          },

          series: [
            {
              // current data
              type: "pictorialBar",
              symbol: man,
              symbolRepeat: "false",
              symbolMargin: [10, 0],
              symbolClip: true,
              symbolSize: [17, 44],
              symbolBoundingData: max,
              data: [mannum],
              z: 10,
            },
            {
              type: "pictorialBar",
              label: {
                show: false,
              },
              animationDuration: 0,
              symbolRepeat: "fixed",
              symbolMargin: [10, 0],
              symbol: man,
              symbolSize: [17, 44],
              symbolBoundingData: max,
              data: [max],
              z: 5,
            },
          ],
        };
      }

      function wonman(girlnum,max) {
        option2 = {
          color: ["#E03DA4", "#3C404C"],
          tooltip: {
            show: false,
          },
          xAxis: {
            type: "value",
            max: max,
            splitLine: { show: false },
            offset: 10,
            axisLine: {
              show: false,
              lineStyle: {
                color: "#999",
              },
            },
            axisLabel: {
              show: false,
              margin: 10,
            },
          },
          yAxis: {
            type: "category",
            data: ["女"],
            inverse: true,
            axisTick: { show: false },
            axisLine: { show: false },
            axisLabel: {
              show: false,
              margin: 10,
              color: "#999",
              fontSize: 16,
            },
          },

          series: [
            {
              // current data
              type: "pictorialBar",
              symbol: girl,
              symbolRepeat: "false",
              symbolMargin: [10, 0],
              symbolClip: true,
              symbolSize: [17, 44],
              symbolBoundingData: max,
              data: [girlnum],
              z: 10,
            },
            {
              type: "pictorialBar",
              itemStyle: {
                normal: {},
              },
              label: {
                show: false,
              },
              animationDuration: 0,
              symbolRepeat: "fixed",
              symbolMargin: [10, 0],
              symbol: girl,
              symbolSize: [17, 44],
              symbolBoundingData: max,
              data: [max],
              z: 5,
            },
          ],
        };
      }

      mans(4, 10);
      wonman(5,10)
      myChart.setOption(option2);
    </script>
  </body>
</html>

真实项目使用 案例 :

代码 实现 :

src / components / Echarts / index.vue

<!-- 
* 功能:echarts 图表
* 日期:2022-11
* 作者:小灰狼
-->
<template>
	<div>
		<div id="id" class="myChart" :style="setStyle"></div>
	</div>
</template>

<script>
import * as echarts from 'echarts';

export default {
	name: 'echartsChart',
	props: {
		id: {
			type: String, // 类型
			default: null, // 默认值
		},
		options: {
			type: Object, // 类型
			default: null,
		},
		setStyle: {
			type: Object, // 类型
			default: null,
		},
	},
	data() {
		return {
			myChart: null,
			myChartStyle: { height: '300px' }, // 图标样式
			tooltip: {
				trigger: 'item',
			},
			legend: {
				origin: 'vertical',
				left: 'left',
			},
		};
	},
	watch: {
		option: {
			handler(newValue) {
				this.$nextTick(() => {
					if (document.getElementById(this.id)) {
						if (!this.myChart) {
							this.myChart = echarts.init(
								document.getElementById(this.id)
							);
							// 新增配置 Echarts 图表的自带 showLoading 方法
							this.myChart.showLoading({
								text: '加载中...',
							});
							this.myChart.setOption(newValue, true);
							this.myChart.hideLoading(); // 关闭Echarts的Loading
						}
					}
				});
			},
		},
		deep: true,
	},
	mounted() {
		this.initChart(this.id, this.options);
		window.addEventListener('resize', function () {
			if (this.myChart) {
				this.myChart.resize();
			}
		});
	},
	methods: {
		initChart(id, options) {
			if (document.getElementById(id)) {
				this.myChart = echarts.init(document.getElementById(id));
				// 新增配置 Echarts 图表的自带 showLoading 方法
				this.myChart.showLoading({
					text: '加载中...',
				});
				// this.myChart.setOption(options, true);
				setTimeout(() => {
					this.myChart.setOption(options, true);
					this.myChart.hideLoading(); // 关闭Echarts的Loading
				}, 100);
			}
		},
		// 解决Echarts页面切换卡顿的问题
		beforeDestroy() {
			this.myChart.clear();
		},
	},
};
</script>

<style lang="scss" scoped>
// .myChart {
// 	width: 95%;
// 	height: 400px;
// }
</style>

src / views / ......

<template>
	<div class="sex-box">
		<div class="sex-echarts">
			<!-- 性别 -->
			<EchartsChart
				id="manChart"
				:options.sync="manOptions"
				:setStyle="sexChartCss"
			/>
			<EchartsChart
				id="womanChart"
				:options.sync="womanOptions"
				:setStyle="sexChartCss"
			/>
		</div>
	</div>
</template>

<script>
import EchartsChart from '@components/Echarts/index';
import SessionStore from '@utils/sessionStore';

export default {
	name: 'Sex Chart',
	inject: ['getCentralData'],
	comments: { EchartsChart },
	props: {
		// 性别图表样式设置
		sexChartCss: {
			typeof: Object,
			default: () => ({}), // 对象默认值写法
		},
	},
	data() {
		return {
			option1: {}, // 男
			option2: {}, // 女
			manOptions: {}, // 男
			womanOptions: {}, // 女
			sexData: {}, // 图表栏数据
			man: `path://M516.608 217.6c40.448 0 72.704-32.768 72.704-72.704 0-40.448-32.768-72.704-72.704-72.704-40.448 0-72.704 32.768-72.704 72.704s32.256 72.704 72.704 72.704z m80.384 18.432H435.712c-51.2 0-93.696 41.472-93.696 93.184v225.28c0 17.408 13.824 31.744 31.232 31.744s31.744-14.336 31.744-31.744V351.744h16.384v565.76c0 23.552 18.944 42.496 43.008 42.496 23.552 0 42.496-18.944 42.496-42.496V588.8h17.408v328.192c0 23.552 18.944 42.496 42.496 42.496 23.552 0 43.008-18.944 43.008-42.496V351.744h16.384v203.264c0 17.408 14.336 31.744 31.744 31.744 17.408 0 31.232-14.336 31.232-31.744v-225.28c1.024-51.712-40.96-93.696-92.16-93.696z`,
			girl: `path://M693.064905 504.590142l-55.845778-202.954549c-7.532724-22.967796-34.488553-63.372358-79.685923-65.239925h-89.777337c-46.750604 1.927976-73.520086 41.894316-80.000256 65.365863l-55.777177 202.707792c-11.954885 44.266658 39.220951 61.57032 51.857744 19.985218l49.867311-187.020846h14.008799l-85.85176 328.529989h80.247012v246.909946c0 44.697714 60.764522 44.697714 60.764522 0v-246.909946h18.924473v246.909946c0 44.697714 58.766922 44.697714 58.766922 0v-246.909946h82.427888l-87.654823-328.529989h15.938823l49.988129 187.020846c12.331675 42.517862 63.256659 24.280417 51.801431-19.864399zM512.336858 219.833299c38.471467 0 69.538196-32.435663 69.538196-72.527941 0-40.031868-31.066729-72.528965-69.538196-72.528965-38.415154 0-69.48393 32.497096-69.48393 72.528965 0 40.030845 31.0698 72.527941 69.48393 72.527941z`,
		};
	},
	created() {
		if (
			SessionStore.get('dataInfo') != '' ||
			SessionStore.get('dataInfo') != null ||
			SessionStore.get('dataInfo') != undefined
		) {
			this.sexData = SessionStore.get('dataInfo');
			this.mans(this.sexData.manNum, this.sexData.manCount, 10);
			this.womans(this.sexData.womanNum, this.sexData.womanCount, 10);
			this.manOptions = this.option1;
			this.womanOptions = this.option2;
		}
	},
	methods: {
		mans(boyNum, boyCount, max) {
			this.option1 = {
				color: ['rgb(87,138,248)', 'rgb(212,212,212)'],
				tooltip: {
					show: true,
					trigger: 'item',
					formatter: (params) => {
						// return `男:${boyNum}人,${params.value * 10}%`
						if (params.componentIndex === 0) {
							return `男:${boyNum}人,${params.value * 10}%`;
						} else {
							return ``;
							// return `男:${(10 - boyCount) * 10}%`;
						}
					},
				},
				legend: {
					left: '20px',
					top: 'bottom',
					orient: 'vertical',
					data: ['男', '女'],
				},
				xAxis: {
					type: 'value',
					max: max,
					splitLine: { show: false },
					offset: 10,
					axisLine: {
						show: false,
						lineStyle: {
							color: 'red',
						},
					},
					axisLabel: {
						show: false,
						margin: 10,
					},
				},
				yAxis: {
					type: 'category',
					data: ['男'],
					inverse: true,
					axisTick: { show: false },
					axisLine: { show: false },
					axisLabel: {
						show: false,
						margin: 10,
						color: '#999',
						fontSize: 16,
					},
				},

				series: [
					{
						center: ['70%', '50%'],
						// current data
						type: 'pictorialBar',
						symbol: this.man,
						symbolRepeat: 'false',
						symbolMargin: [10, 0],
						symbolClip: true,
						symbolSize: [17, 44],
						symbolBoundingData: max,
						// data: [mannum],
						data: [boyCount],
						z: 10,
					},
					{
						center: ['70%', '50%'],
						type: 'pictorialBar',
						label: {
							show: false,
						},
						animationDuration: 0,
						symbolRepeat: 'fixed',
						symbolMargin: [10, 0],
						symbol: this.man,
						symbolSize: [17, 44],
						symbolBoundingData: max,
						data: [max],
						z: 5,
					},
				],
			};
		},
		womans(girlNum, girlCount, max) {
			this.option2 = {
				color: ['rgb(230,104,198)', 'rgb(212,212,212)'],
				tooltip: {
					show: true,
					trigger: 'item',
					formatter: (params) => {
						if (params.componentIndex === 0) {
							return `女:${girlNum}人,${params.value * 10}%`;
						} else {
							return ``;
							// return `女:${(10 - girlCount) * 10}%`;
						}
					},
				},
				// legend: {
				//   left: '20px',
				//   top: 'bottom',
				//   orient: 'vertical',
				//   data: ['男', '女'],
				// },
				xAxis: {
					type: 'value',
					max: max,
					splitLine: { show: false },
					offset: 10,
					axisLine: {
						show: false,
						lineStyle: {
							color: '#999',
						},
					},
					axisLabel: {
						show: false,
						margin: 10,
					},
				},
				yAxis: {
					type: 'category',
					data: ['女'],
					inverse: true,
					axisTick: { show: false },
					axisLine: { show: false },
					axisLabel: {
						show: false,
						margin: 10,
						color: '#999',
						fontSize: 16,
					},
				},

				series: [
					{
						center: ['70%', '50%'],
						// current data
						type: 'pictorialBar',
						symbol: this.girl,
						symbolRepeat: 'false',
						symbolMargin: [10, 0],
						symbolClip: true,
						symbolSize: [17, 44],
						symbolBoundingData: max,
						data: [girlCount],
						z: 10,
					},
					{
						center: ['70%', '50%'],
						type: 'pictorialBar',
						itemStyle: {
							normal: {},
						},
						label: {
							show: false,
						},
						animationDuration: 0,
						symbolRepeat: 'fixed',
						symbolMargin: [10, 0],
						symbol: this.girl,
						symbolSize: [17, 44],
						symbolBoundingData: max,
						data: [max],
						z: 5,
					},
				],
			};
		},
	},
	watch: {
		centralData: {
			handler: function (newValue) {
				this.$nextTick(() => {
					this.sexData = newValue; // 重新赋值
					this.mans(this.sexData.manNum, this.sexData.manCount, 10);
					this.womans(
						this.sexData.womanNum,
						this.sexData.womanCount,
						10
					);
					this.manOptions = this.option1;
					this.womanOptions = this.option2;
				});
			},
		},
	},
	computed: {
		centralData() {
			return this.getCentralData();
		},
	},
};
</script>

<style lang="scss" scoped>
.sex-box {
	position: relative;
	.sex-echarts {
		position: absolute;
		top: 68px;
	}
}
</style>

src / utils / sessionStore.js

/**
 * sessionStorage 会话存储
 * 小灰狼
 * 2022-11
 */

class SessionStore {
	// 获取
	get(key) {
		// 会话存储 + 取 :
		let value = sessionStorage.getItem(key) || '';
		if (/^[\[\{]/.test(value)) {
			value = JSON.parse(value);
		}
		return value;
	}

	// 设置
	set(key, value) {
		if (typeof value === 'object') {
			value = JSON.stringify(value);
		}
		sessionStorage.setItem(key, value);
	}

	// 删除
	delay(key) {
		sessionStorage.removeItem(key);
	}
}

export default new SessionStore();

猜你喜欢

转载自blog.csdn.net/weixin_58099903/article/details/127928584