Skip to content

气泡图

效果展示

示例代码

html
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Title</title>
		<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
		<style>
			.container {
				width: 500px;
				height: 300px;
			}

			.main {
				width: 500px;
				height: 100px;
				border: 1px solid gray;
				padding: 10px 0;
				background-color: #031c4c;
				display: flex;
				justify-content: center;
				align-items: center;
				gap: 5px;
				translate: 1;
			}

			.item {
				cursor: pointer;
				line-height: initial;
				color: #fff;
				border: 0px solid red;
				border-radius: 50%;
				font-size: 12px;
				/* background-image: radial-gradient(circle, #251571, #5a41dd); */
				display: flex;
				align-items: center;
				justify-content: center;
			}

			.item:hover {
				scale: 1.1;
			}

			.item .label {
				border: 0px solid red;
				text-align: center;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<div id="main" class="main">
				<div class="box">
					<div class="item">
						<div class="label">
							<div class="name">A+</div>
							<div class="value">90%</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</body>
</html>

<script>
	$(function() {

	})

	var demoObj = new DemoClass();
	demoObj.init('main');

	function DemoClass() {
		this.domId = '';
		this.myChart = null;
		this.option = {};
		this.data = [{
				name: 'A',
				value: 100,
				startColor: '#251571',
				endColor: '#5a41dd'
			},
			{
				name: 'A+',
				value: 200,
				startColor: '#251571',
				endColor: '#24ac82'
			},
			{
				name: 'B',
				value: 300,
				startColor: '#251571',
				endColor: '#0173e4'
			},
			{
				name: 'B+',
				value: 400,
				startColor: '#251571',
				endColor: '#926710'
			},
			{
				name: 'C',
				value: 50,
				startColor: '#251571',
				endColor: '#5a41dd'
			},
			{
				name: 'C+',
				value: 60,
				startColor: '#251571',
				endColor: '#5a41dd'
			},
		];
		this.colors = [{
				startColor: '#251571',
				endColor: '#5a41dd'
			},
			{
				startColor: '#251571',
				endColor: '#24ac82'
			},
			{
				startColor: '#251571',
				endColor: '#0173e4'
			},
			{
				startColor: '#251571',
				endColor: '#926710'
			},
		];

		this.init = function(dom_id) {
			this.domId = dom_id;
			var chartDom = document.getElementById(dom_id);
			// todo 请求接口拿数据赋给 this.data
			this.update();
		};

		this.change = function() {
			// todo 请求接口拿数据赋给 this.data

			this.data = randomSort(this.data)
			console.log(this.data);
			this.update()
		};

		this.update = function() {
			// 请求返回的数据: [{name:'专业名称',num:10}]

			this.colors = randomSort(this.colors)
			this.data = randomSort(this.data)
			this.calculateValues();

			var boxDom = $('.box').clone(true);
			$('.box').hide();

			this.data.forEach((e, i) => {
				var node = boxDom.clone(true);
				node.find('.item').width(e.symbolSize).height(e.symbolSize).css({
					width: e.symbolSize + 'px',
					height: e.symbolSize + 'px',
					translate: '0 ' + e.translateY + 'px',
					'background-image': 'radial-gradient(circle, ' + e.startColor + ', ' + e.endColor + ')',
				});
				node.find('.item .label').css({
					scale: e.labelScale
				});
				node.find('.item .label .name').text(e.name);
				node.find('.item .label .value').text(e.value);
				$('#main').append(node);
			});
		};

		this.calculateValues = function() {
			var minValue = 0;
			var maxValue = 0;
			var sumValue = 0;
			this.data.forEach((e, i) => {
				sumValue += e.value;
				if (i == 0) {
					minValue = e.value;
					maxValue = e.value;
				} else {
					if (minValue > e.value) minValue = e.value;
					if (maxValue < e.value) maxValue = e.value;
				}
			})

			var domWight = $('#' + this.domId).width();
			var domHeight = $('#' + this.domId).height();

			// 先用x轴计算
			var baseRate = (domWight - (this.data.length + 1) * 5) / sumValue;
			if (baseRate * maxValue > domHeight) {
				// 说明 最大的圆直径会超过容器的高度,需要用 x 轴来计算
				baseRate = (domHeight - 10) / maxValue;
			}

			this.data.forEach((e, i) => {
				e.symbolSize = e.value * baseRate;
				if (e.symbolSize < 30) e.symbolSize = 30;
				var diff = domHeight - e.symbolSize;
				e.translateY = getRandomNumber(-diff, diff) / 2; // 计算圆的上下偏移量
				e.labelScale = this.getLabelScale(e.symbolSize); // 文字的缩放比例
				var colorIndex = i;
				if (i >= this.colors.length) {
					colorIndex = getRandomNumber(0, this.colors.length);
				}
				var colors = this.colors[colorIndex];
				e.startColor = colors.startColor;
				e.endColor = colors.endColor;
			})
		};

		this.getLabelScale = function(width) {
			var baseWidth = 70; // 基础宽度:width:70px;
			var baseSize = 12; // 基础字体大小:font-size:12px;

			var size = 1;
			if (width < 40) {
				size = 0.7;
			} else if (width < 50) {
				size = 0.8;
			} else if (width < 60) {
				size = 0.9;
			} else if (width < 70) {
				size = 1;
			} else if (width < 80) {
				size = 1.1;
			} else if (width < 90) {
				size = 1.2;
			} else if (width < 100) {
				size = 1.3;
			} else if (width < 110) {
				size = 1.4;
			} else {
				size = 1.5;
			}
			return size;
		}
	}


	// 生成随机数
	function getRandomNumber(min, max) {
		return Math.floor(Math.random() * (max - min) + min);
	}

	function randomSort(arr) {
		var newArr = [];
		var length = arr.length;
		for (var i = 0; i < length; i++) {
			var index = getRandomNumber(0, arr.length);
			var res = arr.splice(index, 1)
			newArr.push(res[0])
		}
		return newArr;
	}
</script>