326 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			326 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
| <template>
 | |
| 	<view class="table pr" :style="'zoom:'+size+';'">
 | |
| 		<view class="v-tr" style="display: flex;">
 | |
| 			<view class="v-td" :class="{
 | |
| 					colspan: Array.isArray(treeData.children) ? treeData.children.length * 2 : 1,
 | |
| 					parentLevel: Array.isArray(treeData.children) && treeData.children.length,
 | |
| 					extend: Array.isArray(treeData.children) && treeData.children.length && treeData.extend
 | |
| 				}">
 | |
| 				<view :class="{ node: true }">
 | |
| 					<view class="person" :class="Array.isArray(treeData.class) ? treeData.class : []">
 | |
| 						<image @click.stop="clickNode(treeData)" class="person-ava" :src="treeData.avatarUrl" mode=""></image>
 | |
| 					</view>
 | |
| 				</view>
 | |
| 			</view>
 | |
| 		</view>
 | |
| 		<view class="v-tr" v-if="Array.isArray(treeData.children) && treeData.children.length && treeData.extend">
 | |
| 			<view v-for="(children, index) in treeData.children" :key="index" colspan="2" class="childLevel v-td">
 | |
| 				<TreeChart :json="children" :left="0" :top="0" @click-node="clickNode" />
 | |
| 			</view>
 | |
| 		</view>
 | |
| 	</view>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| 	export default {
 | |
| 		name: 'TreeChart',
 | |
| 		props: ['json', 'size'],
 | |
| 		data() {
 | |
| 			return {
 | |
| 				treeData: {}
 | |
| 			};
 | |
| 		},
 | |
| 		watch: {
 | |
| 			json: {
 | |
| 				handler: function(Props) {
 | |
| 					let extendKey = function(jsonData) {
 | |
| 						jsonData.extend = jsonData.extend === void 0 ? true : !!jsonData.extend;
 | |
| 						if (Array.isArray(jsonData.children)) {
 | |
| 							jsonData.children.forEach(c => {
 | |
| 								extendKey(c);
 | |
| 							});
 | |
| 						}
 | |
| 						return jsonData;
 | |
| 					};
 | |
| 					if (Props) {
 | |
| 						this.treeData = extendKey(Props);
 | |
| 					}
 | |
| 				},
 | |
| 				immediate: true
 | |
| 			}
 | |
| 		},
 | |
| 		methods: {
 | |
| 			toggleExtend: function(treeData) {
 | |
| 				treeData.extend = !treeData.extend;
 | |
| 				this.$forceUpdate();
 | |
| 			},
 | |
| 			clickNode(e){
 | |
| 				this.$emit('click-node',e)
 | |
| 			}
 | |
| 		}
 | |
| 	};
 | |
| </script>
 | |
| 
 | |
| <style scoped>
 | |
| 	.f18 {
 | |
| 		font-size: 18rpx;
 | |
| 	}
 | |
| 
 | |
| 	.pv-btn {
 | |
| 		width: 200rpx;
 | |
| 		height: 50rpx;
 | |
| 		background-color: #b2821e;
 | |
| 		color: #fff;
 | |
| 		font-size: 20rpx;
 | |
| 		line-height: 50rpx;
 | |
| 		display: flex;
 | |
| 		align-items: center;
 | |
| 		margin: auto;
 | |
| 		margin-top: 12rpx;
 | |
| 		margin-bottom: 12rpx;
 | |
| 	}
 | |
| 
 | |
| 	.next-btn {
 | |
| 		border-radius: 50%;
 | |
| 		background: none;
 | |
| 		width: 40rpx;
 | |
| 		height: 40rpx;
 | |
| 		margin: auto;
 | |
| 		padding: 0;
 | |
| 		display: flex;
 | |
| 		justify-content: center;
 | |
| 		align-items: center;
 | |
| 	}
 | |
| 
 | |
| 	.table {
 | |
| 		border-collapse: separate !important;
 | |
| 		border-spacing: 0 !important;
 | |
| 		width: 100%;
 | |
| 	}
 | |
| 
 | |
| 	.v-tr {
 | |
| 		
 | |
| 		 display: inline-flex;
 | |
| 		  justify-content: center;
 | |
| 		  align-items: flex-start;
 | |
| 		  /* width: 100%; */
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	.v-td {
 | |
| 		position: relative;
 | |
| 		vertical-align: top;
 | |
| 		padding: 0 0 100rpx 0;
 | |
| 		text-align: center;
 | |
| 	}
 | |
| 
 | |
| 	.extend_handle {
 | |
| 		position: absolute;
 | |
| 		left: 50%;
 | |
| 		bottom: 30rpx;
 | |
| 		width: 10rpx;
 | |
| 		height: 10rpx;
 | |
| 		padding: 10rpx;
 | |
| 		transform: translate3d(-30rpx, 0, 0);
 | |
| 		cursor: pointer;
 | |
| 	}
 | |
| 
 | |
| 	.extend_handle:before {
 | |
| 		content: '';
 | |
| 		display: block;
 | |
| 		width: 100%;
 | |
| 		height: 100%;
 | |
| 		box-sizing: border-box;
 | |
| 		border: 4rpx solid;
 | |
| 		border-color: #f2f2f2 #f2f2f2 transparent transparent;
 | |
| 		transform: rotateZ(135deg);
 | |
| 		transform-origin: 50% 50% 0;
 | |
| 		transition: transform ease 300ms;
 | |
| 	}
 | |
| 
 | |
| 	.extend_handle:hover:before {
 | |
| 		border-color: #f2f2f2 #f2f2f2 transparent transparent;
 | |
| 	}
 | |
| 
 | |
| 	.extend .extend_handle:before {
 | |
| 		transform: rotateZ(-45deg);
 | |
| 	}
 | |
| 
 | |
| 	.extend::after {
 | |
| 		content: '';
 | |
| 		position: absolute;
 | |
| 		left: 50%;
 | |
| 		bottom: 84rpx;
 | |
| 		height: 84rpx;
 | |
| 		border-left: 4rpx solid #f2f2f2;
 | |
| 		transform: translate3d(-2rpx, 0, 0);
 | |
| 	}
 | |
| 
 | |
| 	.childLevel::before {
 | |
| 		content: '';
 | |
| 		position: absolute;
 | |
| 		left: 50%;
 | |
| 		bottom: 100%;
 | |
| 		height: 84rpx;
 | |
| 		border-left: 4rpx solid #f2f2f2;
 | |
| 		transform: translate3d(-2rpx, 0, 0);
 | |
| 	}
 | |
| 
 | |
| 	.childLevel::after {
 | |
| 		content: '';
 | |
| 		position: absolute;
 | |
| 		left: 0;
 | |
| 		right: 0;
 | |
| 		top: -88rpx;
 | |
| 		border-top: 4rpx solid #f2f2f2;
 | |
| 	}
 | |
| 
 | |
| 	.childLevel:first-child:before,
 | |
| 	.childLevel:last-child:before {
 | |
| 		display: none;
 | |
| 	}
 | |
| 
 | |
| 	.childLevel:first-child:after {
 | |
| 		left: 50%;
 | |
| 		height: 84rpx;
 | |
| 		border: 4rpx solid;
 | |
| 		border-color: #f2f2f2 transparent transparent #f2f2f2;
 | |
| 		border-radius: 6rpx 0 0 0;
 | |
| 		transform: translate3d(2rpx, 0, 0);
 | |
| 	}
 | |
| 
 | |
| 	.childLevel:last-child:after {
 | |
| 		right: 50%;
 | |
| 		height: 84rpx;
 | |
| 		border: 4rpx solid;
 | |
| 		border-color: #f2f2f2 #f2f2f2 transparent transparent;
 | |
| 		border-radius: 0 6rpx 0 0;
 | |
| 		transform: translate3d(-2rpx, 0, 0);
 | |
| 	}
 | |
| 
 | |
| 	.childLevel:first-child.childLevel:last-child::after {
 | |
| 		left: auto;
 | |
| 		border-radius: 0;
 | |
| 		border-color: transparent #f2f2f2 transparent transparent;
 | |
| 		transform: translate3d(2rpx, 0, 0);
 | |
| 	}
 | |
| 
 | |
| 	.node {
 | |
| 		position: relative;
 | |
| 		display: inline-block;
 | |
| 		margin: 0 10rpx;
 | |
| 		box-sizing: border-box;
 | |
| 		text-align: center;
 | |
| 	}
 | |
| 
 | |
| 	.node .person {
 | |
| 		position: relative;
 | |
| 		display: inline-block;
 | |
| 		z-index: 2;
 | |
| 		width: 104rpx;
 | |
| 		height: 104rpx;
 | |
| 	}
 | |
| 
 | |
| 	.node .person .person-ava {
 | |
| 		width: 104rpx;
 | |
| 		height: 104rpx;
 | |
| 	}
 | |
| 
 | |
| 	.node .person .avat {
 | |
| 		display: block;
 | |
| 		width: 4em;
 | |
| 		height: 4em;
 | |
| 		margin: auto;
 | |
| 		overflow: hidden;
 | |
| 		background: #fff;
 | |
| 		border: 4px solid #f2f2f2;
 | |
| 		box-sizing: border-box;
 | |
| 		border-radius: 0.5em;
 | |
| 	}
 | |
| 
 | |
| 	.node .person .avat img {
 | |
| 		width: 100%;
 | |
| 		height: 100%;
 | |
| 	}
 | |
| 
 | |
| 	.node .person .name {
 | |
| 		display: block;
 | |
| 		margin: auto;
 | |
| 		overflow: hidden;
 | |
| 		box-sizing: border-box;
 | |
| 		overflow: hidden;
 | |
| 		font-size: 20rpx;
 | |
| 		line-height: 1.5;
 | |
| 		padding-top: 24rpx;
 | |
| 	}
 | |
| 
 | |
| 	.node .person .name-bottom {
 | |
| 		display: block;
 | |
| 		margin: auto;
 | |
| 		overflow: hidden;
 | |
| 		border-top: none;
 | |
| 		box-sizing: border-box;
 | |
| 		overflow: hidden;
 | |
| 	}
 | |
| 
 | |
| 	.node .person .operation {}
 | |
| 
 | |
| 	.node.hasMate::after {
 | |
| 		content: '';
 | |
| 		position: absolute;
 | |
| 		left: 2em;
 | |
| 		right: 2em;
 | |
| 		top: 2em;
 | |
| 		border-top: 4px solid #f2f2f2;
 | |
| 		z-index: 1;
 | |
| 	}
 | |
| 
 | |
| 	/* 横板 */
 | |
| 	.landscape {
 | |
| 		transform: translate(-100%, 0) rotate(-90deg);
 | |
| 		transform-origin: 100% 0;
 | |
| 	}
 | |
| 
 | |
| 	.landscape .node {
 | |
| 		text-align: left;
 | |
| 		height: 8em;
 | |
| 		width: 8em;
 | |
| 	}
 | |
| 
 | |
| 	.landscape .person {
 | |
| 		position: relative;
 | |
| 		transform: rotate(90deg);
 | |
| 		padding-left: 4.5em;
 | |
| 		height: 4em;
 | |
| 		top: 4em;
 | |
| 		left: -1em;
 | |
| 	}
 | |
| 
 | |
| 	.landscape .person .avat {
 | |
| 		position: absolute;
 | |
| 		left: 0;
 | |
| 	}
 | |
| 
 | |
| 	.landscape .person .name {
 | |
| 		height: 4em;
 | |
| 		line-height: 4em;
 | |
| 	}
 | |
| 
 | |
| 	.landscape .hasMate {
 | |
| 		position: relative;
 | |
| 	}
 | |
| 
 | |
| 	.landscape .hasMate .person {
 | |
| 		position: absolute;
 | |
| 	}
 | |
| 
 | |
| 	.landscape .hasMate .person:first-child {
 | |
| 		left: auto;
 | |
| 		right: -4em;
 | |
| 	}
 | |
| 
 | |
| 	.landscape .hasMate .person:last-child {
 | |
| 		left: -4em;
 | |
| 		margin-left: 0;
 | |
| 	}
 | |
| </style> |