鱼骨图功能实现

dom:


                <div class="module-content">
                    <div class="title">
                        <span>[</span>
                        <p>鱼骨图</p>
                        <span>]</span>
                    </div>
                    <div class="line-mian"></div>
                    <div :ref="'module' + i" v-for="(item,i) in list" :key="i" class="module-pub">
                        <div :ref="'line' + i" class="line-pub"></div>
                        <div :ref="'lineOne' + i + j" v-for="(k,j) in item.children" class="module-pub-one">
                            <div class="line-pub_"></div>
                            <p>{{k.name}}</p>
                        </div>
                        <div :ref="'text' + i" class="module-pub-text">
                            <p>{{(item.value).toFixed(0)}}%</p>
                            <p>{{item.name}}</p>
                        </div>
                    </div>
                </div>

js:


mounted() {
	list = [
		{
			name: '标题1',
			value: 15,
			children: [
				{
					name: '内容1-1',
					value: 40,
				},
				{
					name: '内容1-2',
					value: 20,
				},
				{
					name: '内容1-3',
					value: 40,
				},
			]
		},
		{
			name: '标题2',
			value: 15,
			children: [
				{
					name: '内容2-1',
					value: 40,
				},
				{
					name: '内容2-2',
					value: 20,
				},
				{
					name: '内容2-3',
					value: 40,
				},
			]
		},
		{
			name: '标题3',
			value: 25,
			children: [
				{
					name: '内容3-1',
					value: 20,
				},
				{
					name: '内容3-2',
					value: 20,
				},
			]
		},
		{
			name: '标题4',
			value: 25,
			children: [
				{
					name: '内容4-1',
					value: 0,
				},
				{
					name: '内容4-2',
					value: 0,
				},
				{
					name: '内容4-3',
					value: 0,
				},
			]
		},
		{
			name: '标题5',
			value: 20,
			children: [
				{
					name: '内容5-1',
					value: 0,
				},
				{
					name: '内容5-2',
					value: 0,
				},
				{
					name: '内容5-3',
					value: 0,
				},
				{
					name: '内容5-4',
					value: 0,
				},
				{
					name: '内容5-5',
					value: 0,
				},
			]
		},
	];

	this.setStyle();
},

methods: {
	setStyle() {
		this.$nextTick(()=> {
			this.list.forEach((item,i) => {
				let left = (i + 1) * 100;
				this.$refs['module'+i][0].style.left = left +'px';
				let length = (item.children.length + 1) * 40;
				this.$refs['line'+i][0].style.width = length +'px';
				if (i % 2 === 0) {
					this.$refs['line'+i][0].style.transform = 'rotate(' + -30 +'deg)';
				} else {
					this.$refs['line'+i][0].style.transform = 'rotate(' + 30 +'deg)';
				}
				let top = 0;
				let left2 = 0;
				item.children.forEach((k,j)=>{
					top = (j + 1) * 20;
					if (i % 2 === 0) {
						top = -top;
					}
					left2 = Math.abs(top) / Math.tan(30 * Math.PI / 180) - 13;
					if (i % 2 === 1) { // 下斜线
						left2 = left2 + 26
					}
					this.$refs['lineOne'+i+j][0].style.left = left2 +'px';
					this.$refs['lineOne'+i+j][0].style.top = top +'px';
				});
				if (i % 2 === 1) {
					top = top + 24;
					left2 = left2 - 10;
				} else {
					top = top - 58;
					left2 = left2 + 4;
				}
				this.$refs['text'+i][0].style.left = left2 +'px';
				this.$refs['text'+i][0].style.top = top +'px';
			})
		})
	},

},

css:

		
.module-content {
	position: relative;
	margin: 24px 30px 0;
	height: calc(18vh);
	margin-bottom: 0;
	height: calc(33vh);
	.line-mian {
		width: 84%;
		height: 3px;
		background: #00CCFF;
		position: absolute;
		left: 90px;
		top: calc(50% - 1px);
	}
	.module-pub {
		position: absolute;
		left: 0;
		width: 100px;
		bottom: calc(50% + 1px);
		color: #fff;
		.module-pub-one {
			position: absolute;
			top: 10px;
			width: 9vw;
			.line-pub_ {
				width: 40px;
				/*height: 1px;*/
				border-bottom: 1.5px solid #00CCFF;
				/*background: #00CCFF;*/
				position: absolute;
				left: 0;
				top: 7px;
			}
			p {
				font-size: 12px;
				position: absolute;
				left: 42px;
			}
		}
		.module-pub-text {
			position: absolute;
			right: 0;
			bottom: 0;
			p {
				width: 80px;
				font-size: 14px;
				font-weight: bold;
				text-align: center;
				&:nth-child(1) {
					color: #EF822F;
					line-height: 16px;
				}
				&:nth-child(2) {
					color: #5AD6FC;
					cursor: pointer;
					border-radius: 8px;
					padding: 1px 0;
					&.active {
						background: #4594F9;
						color: #fff;
					}
					&:hover {
						background: #4594F9;
						color: #fff;
					}
				}
			}
		}
	}
	.line-pub {
		width: 80%;
		height: 2px;
		background: #00CCFF;
		position: absolute;
		left: 0;
		bottom: -2px;
		transform-origin: left bottom;
	}
	.title {
		position: absolute;
		left: 10px;
		top: calc(50% - 8px);
		display: flex;
		align-items: center;
		justify-content: center;
		p {
			font-weight: 700;
			font-size: 16px;
			line-height: 16px;
			color: #C7F805;
			margin: 0 4px;
		}
		span {
			font-weight: 700;
			line-height: 16px;
			font-size: 16px;
			color: #00CCFF
		}
	}
}

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值