|
@@ -0,0 +1,371 @@
|
|
|
+<script setup>
|
|
|
+import { onMounted } from 'vue'
|
|
|
+import { Graph } from '@antv/g6'
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ const lList = [
|
|
|
+ {
|
|
|
+ id: '1',
|
|
|
+ name: '深圳市九连山农产品配送有限公司'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '2',
|
|
|
+ name: '深圳市九连山农产品配送有限公司2'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '3',
|
|
|
+ name: '深圳市九连山农产品配送有限公司3'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '4',
|
|
|
+ name: '深圳市九连山农产品配送有限公司4'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '5',
|
|
|
+ name: '广州市六数饮食管理有限公司'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '6',
|
|
|
+ name: '广州市六数饮食管理有限公司2'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '7',
|
|
|
+ name: '广州市六数饮食管理有限公司3'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '8',
|
|
|
+ name: '广州市六数饮食管理有限公司4'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ const rList = [
|
|
|
+ {
|
|
|
+ id: '1',
|
|
|
+ name: '广州市六数饮食管理有限公司'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '2',
|
|
|
+ name: '广州市六数饮食管理有限公司2'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '3',
|
|
|
+ name: '广州市六数饮食管理有限公司3'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '4',
|
|
|
+ name: '广州市六数饮食管理有限公司4'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '5',
|
|
|
+ name: '广州市六数饮食管理有限公司'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '6',
|
|
|
+ name: '广州市六数饮食管理有限公司2'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '7',
|
|
|
+ name: '广州市六数饮食管理有限公司3'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '8',
|
|
|
+ name: '广州市六数饮食管理有限公司4'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+
|
|
|
+ function getItemStyle(type) {
|
|
|
+ let result = ''
|
|
|
+ switch (type) {
|
|
|
+ case 'blue': {
|
|
|
+ result = `
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 152px;
|
|
|
+ padding: 6px 16px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: rgba(5, 165, 242, 1);
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 18px;
|
|
|
+ text-align: center;
|
|
|
+ color: #fff;
|
|
|
+ `
|
|
|
+ break
|
|
|
+ }
|
|
|
+ case 'y': {
|
|
|
+ result = `
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 88px;
|
|
|
+ height: 48px;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 6px 16px;
|
|
|
+ background: rgba(255, 207, 159, 1);
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 18px;
|
|
|
+ text-align: center;
|
|
|
+ color: #1d1d1d;
|
|
|
+ `
|
|
|
+ break
|
|
|
+ }
|
|
|
+ case 'item': {
|
|
|
+ result = `
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 6px;
|
|
|
+ border: 2px solid rgba(255, 207, 159, 1);
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 18px;
|
|
|
+ text-align: center;
|
|
|
+ color: #1d1d1d;
|
|
|
+ `
|
|
|
+ break
|
|
|
+ }
|
|
|
+ case 'label': {
|
|
|
+ result = `
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 18px;
|
|
|
+ text-align: center;
|
|
|
+ color: rgba(255, 159, 64, 1);
|
|
|
+ `
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result
|
|
|
+ }
|
|
|
+
|
|
|
+ const nodeFill = [].concat(
|
|
|
+ lList.map((v) => {
|
|
|
+ return {
|
|
|
+ id: 'left-' + v.id,
|
|
|
+ depth: 2,
|
|
|
+ size: [128, 48],
|
|
|
+ data: {
|
|
|
+ label: v.name,
|
|
|
+ type: 'item'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ rList.map((v) => {
|
|
|
+ return {
|
|
|
+ id: 'right-' + v.id,
|
|
|
+ depth: 2,
|
|
|
+ size: [128, 48],
|
|
|
+ data: {
|
|
|
+ label: v.name,
|
|
|
+ type: 'item'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ )
|
|
|
+
|
|
|
+ const lineFill = [].concat(
|
|
|
+ lList.map((v) => {
|
|
|
+ return {
|
|
|
+ source: 'left',
|
|
|
+ target: 'left-' + v.id,
|
|
|
+ data: {
|
|
|
+ label: v.name,
|
|
|
+ type: 'item',
|
|
|
+ tip: `竞标(1${v.id}个)`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ rList.map((v) => {
|
|
|
+ return {
|
|
|
+ source: 'right',
|
|
|
+ target: 'right-' + v.id,
|
|
|
+ data: {
|
|
|
+ label: v.name,
|
|
|
+ type: 'item',
|
|
|
+ tip: `竞标(1${v.id}个)`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ )
|
|
|
+
|
|
|
+ const data2 = {
|
|
|
+ nodes: [
|
|
|
+ {
|
|
|
+ id: 'root',
|
|
|
+ depth: 0,
|
|
|
+ size: [152, 48],
|
|
|
+ data: {
|
|
|
+ label: '讯飞智元信息科技有限公司',
|
|
|
+ type: 'blue'
|
|
|
+ },
|
|
|
+ children: ['left', 'right']
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'left',
|
|
|
+ depth: 1,
|
|
|
+ size: [88, 48],
|
|
|
+ data: {
|
|
|
+ label: '共同竞标',
|
|
|
+ type: 'y'
|
|
|
+ },
|
|
|
+ children: lList.map((v) => {
|
|
|
+ return 'left-' + v.id
|
|
|
+ })
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'right',
|
|
|
+ depth: 1,
|
|
|
+ size: [88, 48],
|
|
|
+ data: {
|
|
|
+ label: '共同竞标',
|
|
|
+ type: 'y'
|
|
|
+ },
|
|
|
+ children: rList.map((v) => {
|
|
|
+ return 'right-' + v.id
|
|
|
+ })
|
|
|
+ },
|
|
|
+ ...nodeFill
|
|
|
+ ],
|
|
|
+ edges: [
|
|
|
+ { source: 'root', target: 'left' },
|
|
|
+ { source: 'root', target: 'right' },
|
|
|
+ ...lineFill
|
|
|
+ ]
|
|
|
+ }
|
|
|
+
|
|
|
+ const graph = new Graph({
|
|
|
+ container: document.getElementById('container'),
|
|
|
+ autoFit: {
|
|
|
+ type: 'view' // 自适应类型:'view' 或 'center'
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ ...data2
|
|
|
+ },
|
|
|
+ node: {
|
|
|
+ type: 'html',
|
|
|
+ style: {
|
|
|
+ size: (d) => d.size || [],
|
|
|
+ dx: (d) => {
|
|
|
+ if (d.id === 'root') {
|
|
|
+ return -76
|
|
|
+ }
|
|
|
+ if (d.depth === 2) {
|
|
|
+ return -68
|
|
|
+ }
|
|
|
+ return -44
|
|
|
+ },
|
|
|
+ dy: -24,
|
|
|
+ innerHTML: (d) => {
|
|
|
+ return `<div style="${getItemStyle(d.data.type)}">${
|
|
|
+ d.data.label
|
|
|
+ }</div>`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ edge2: {
|
|
|
+ type: 'cubic-horizontal',
|
|
|
+ animation: {
|
|
|
+ enter: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ edge: {
|
|
|
+ type: 'polyline',
|
|
|
+ style: {
|
|
|
+ router: {
|
|
|
+ // type: 'shortest-path',
|
|
|
+ type: 'orth'
|
|
|
+ },
|
|
|
+ stroke: (d) =>
|
|
|
+ d.target === 'root' || d.source === 'root' ? '#05a5f2' : '#FF9F40', // 边颜色
|
|
|
+ lineWidth: (d) => (d.target === 'root' || d.source === 'root' ? 2 : 1), // 边的宽度
|
|
|
+
|
|
|
+ endArrow: (d) => d.source === 'root',
|
|
|
+
|
|
|
+ label: (d) =>
|
|
|
+ d.target === 'root' || d.source === 'root' ? false : true, // 开启边标签展示
|
|
|
+ labelAutoRotate: false,
|
|
|
+ labelTextAlign: (d) =>
|
|
|
+ d.id.indexOf('right') !== -1 ? 'left' : 'right',
|
|
|
+ labelText: (d) => `${d.data.tip}`, // 边标签文字
|
|
|
+ labelPlacement: 'end', // 边标签相对于边的位置
|
|
|
+ labelFill: '#FF9F40', // 边标签文字颜色
|
|
|
+ labelOffsetX: (d) => (d.id.indexOf('right') !== -1 ? 28 : -18), // 边标签在y轴方向上的偏移量
|
|
|
+ labelOffsetY: -12 // 边标签在y轴方向上的偏移量
|
|
|
+ }
|
|
|
+ },
|
|
|
+ layout: {
|
|
|
+ type: 'mindmap',
|
|
|
+ direction: 'H',
|
|
|
+ getHeight: () => 12,
|
|
|
+ getWidth: () => 32,
|
|
|
+ getVGap: () => 42,
|
|
|
+ getHGap: () => 62
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ graph.render()
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="treeChart" id="container"></div>
|
|
|
+ <!-- <div>-->
|
|
|
+ <!-- <div>-->
|
|
|
+ <!-- <div class='tree-item-type-blue'>讯飞智元信息科技有限公司</div>-->
|
|
|
+ <!-- <div class='tree-item-type-y'>共同竞标</div>-->
|
|
|
+ <!-- <div class='tree-item-type-item'>广州市六数饮食管理有限公司</div>-->
|
|
|
+ <!-- <div class='tree-item-type-label'>竞标(14个)</div>-->
|
|
|
+ <!-- </div>-->
|
|
|
+ <!-- </div>-->
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.tree-item-type-label {
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 18px;
|
|
|
+ text-align: center;
|
|
|
+ color: rgba(255, 159, 64, 1);
|
|
|
+}
|
|
|
+.tree-item-type-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 128px;
|
|
|
+ height: 48px;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 6px;
|
|
|
+ border: 2px solid rgba(255, 207, 159, 1);
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 18px;
|
|
|
+ text-align: center;
|
|
|
+ color: #1d1d1d;
|
|
|
+}
|
|
|
+.tree-item-type-y {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 88px;
|
|
|
+ height: 48px;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 6px 16px;
|
|
|
+ background: rgba(255, 207, 159, 1);
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 18px;
|
|
|
+ text-align: center;
|
|
|
+ color: #1d1d1d;
|
|
|
+}
|
|
|
+.tree-item-type-blue {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 152px;
|
|
|
+ height: 48px;
|
|
|
+ padding: 6px 16px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: rgba(5, 165, 242, 1);
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 18px;
|
|
|
+ text-align: center;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+</style>
|