D3股权穿透图

news2024/11/17 11:54:20

前言:最近做了一个项目,主要就是实现各种类似企查查的各种图谱,欢迎交流。后期将完成的谱图全部链接上,目前已大致实现了:
【企业关系图谱】、【企业构成图谱】、【股权穿透图】、【股权结构图】、【关联方认定图】

准备:

vue版本:安装的3.x但是代码风格用的2.x,不太标准
D3版本:3.2.7

最终效果图展示:

在这里插入图片描述
实现思路:
1、将树结构看做是上下两部分:以【北京麻六记餐饮管理有限公司】为根节点,分为上游股东和下游对外投资
2、绘制两颗树,将根节点重合,及得到效果图

右侧实现的功能也在js里了,同企查查页面功能,全屏用的其他查件

主界面vue文件:

<!-- 股权穿透图 -->
<template>
  <div id="borrow" style="width: 100%;height: 100%;background-color: #fff;">
    <div id="mountNode" style="width: 100%;height: 100%;"></div>
    <ToolBox @maoScale="maoScale" @simpleChange="simpleChange" @editChange="editChange" @refresh="refresh" @exportImg="exportImg" @screenfullChange="toggleFullScreen" />
  </div>
</template>
<script>
import ToolBox from './components/Equity/ToolBox.vue'
import { drawing, simpleChange1, zoomClick, editChange1 } from './components/Equity/index.js'
import { D3Mixin } from '@/mixin/D3Mixin'

export default {
  components: {
    Header,
    ToolBox
  },
  mixins: [D3Mixin],
  data() {
    return {
    };
  },
  mounted() {
    drawing()
  },
  methods: {
    simpleChange(val) {
      simpleChange1(val.value)
    },
    maoScale(val) {
      zoomClick(val)
    },
    editChange(val) {
      editChange1(val.value)
    },
    refresh() {
      drawing()
    },
    exportImg() {
      this.downloadImpByChart('股权穿透图谱', '北京马六级餐饮')
    }
  }
};
</script>

<style lang="scss" scoped>
.downwardNode text,
.upwardNode text {
  font: 10px sans-serif;
}

.downwardLink {
  fill: none;
  stroke-width: 1px;
  /* opacity: 0.5; */
}

.upwardLink {
  fill: none;
  stroke-width: 1px;
  /* opacity: 0.5; */
}
::v-deep .downLine {
  stroke: #128bed;
  stroke-dasharray: 6, 2;
  stroke-dashoffset: 20;
  animation: 1s down-lines infinite linear;
  z-index: 999;
  opacity: 1;
  stroke-width: 2px;
}
::v-deep .upLine {
  stroke: #128bed;
  stroke-dasharray: 6, 2;
  stroke-dashoffset: 20;
  animation: 1s up-lines infinite linear;
  z-index: 999;
  opacity: 1;
  stroke-width: 2px;
}
@keyframes down-lines {
  0% {
    stroke-dashoffset: 10;
  }

  100% {
    stroke-dashoffset: -10;
  }
}
@keyframes up-lines {
  0% {
    stroke-dashoffset: -10;
  }

  100% {
    stroke-dashoffset: 10;
  }
}
::v-deep .isExpand {
  dominant-baseline: middle;
  text-anchor: middle;
}

::v-deep .linkname {
  text-anchor: middle;
}
</style>


数据json文件 EquityJson.json:

{
    "data": {
        "short_name": "北京麻六记餐饮管",
        "p_trees": [
            {
                "short_name": "宋娜",
                "level": "1",
                "isKey": true,
                "amount": "512.0",
                "has_problem": "0",
                "percent": "0.64",
                "pid": "77bd1a4a4459cafe587269a271c2261a",
                "sh_type": "工商股东",
                "children": [],
                "eid": "",
                "identifier": "2",
                "name": "宋娜",
                "type": "P"
            },
            {
                "short_name": "北京食通达科技发",
                "level": "1",
                "amount": "288.0",
                "has_problem": "0",
                "percent": "0.36",
                "sh_type": "工商股东",
                "children": [
                    {
                        "short_name": "菲特兰装饰设计",
                        "level": "2",
                        "amount": "640.0",
                        "has_problem": "0",
                        "percent": "0.64",
                        "sh_type": "工商股东",
                        "children": [
                            {
                                "short_name": "汪玺",
                                "level": "3",
                                "amount": "9.9",
                                "has_problem": "0",
                                "percent": "0.99",
                                "pid": "1421feeaf56724cdf537590b6e4f12e5",
                                "sh_type": "工商股东",
                                "children": [],
                                "eid": "",
                                "identifier": "5",
                                "name": "汪玺",
                                "type": "P"
                            },
                            {
                                "short_name": "安勇",
                                "level": "3",
                                "amount": "0.1",
                                "has_problem": "0",
                                "percent": "0.01",
                                "pid": "0d33371f31e7ce4734f75c575daf1a0b",
                                "sh_type": "工商股东",
                                "children": [],
                                "eid": "",
                                "identifier": "6",
                                "name": "安勇",
                                "type": "P"
                            }
                        ],
                        "eid": "50aeb7cb-8e99-4def-b1d8-b17fbdd0d41b",
                        "identifier": "4",
                        "name": "北京菲特兰装饰设计有限公司",
                        "type": "E"
                    },
                    {
                        "short_name": "MSA CHINA FUND II L.P",
                        "level": "2",
                        "amount": "200.0",
                        "has_problem": "0",
                        "percent": "0.2",
                        "sh_type": "工商股东",
                        "children": [],
                        "eid": "b3baec3812d0a3e83e96dbc492c74802",
                        "identifier": "7",
                        "name": "MSA CHINA FUND II L.P",
                        "type": "UE"
                    },
                    {
                        "short_name": "五鼎通达(上海)",
                        "level": "2",
                        "amount": "160.0",
                        "has_problem": "0",
                        "percent": "0.16",
                        "sh_type": "工商股东",
                        "children": [
                            {
                                "short_name": "安勇",
                                "level": "3",
                                "amount": "6.25",
                                "has_problem": "0",
                                "percent": "0.625",
                                "pid": "0d33371f31e7ce4734f75c575daf1a0b",
                                "sh_type": "工商股东",
                                "children": [],
                                "eid": "",
                                "identifier": "9",
                                "name": "安勇",
                                "type": "P"
                            },
                            {
                                "short_name": "杨洋",
                                "level": "3",
                                "amount": "1.25",
                                "has_problem": "0",
                                "percent": "0.125",
                                "pid": "05c5376b47c1d675119af0eb39fa0ec9",
                                "sh_type": "工商股东",
                                "children": [],
                                "eid": "",
                                "identifier": "10",
                                "name": "杨洋",
                                "type": "P"
                            },
                            {
                                "short_name": "李萍",
                                "level": "3",
                                "amount": "1.25",
                                "has_problem": "0",
                                "percent": "0.125",
                                "pid": "d222321e2f8e59a3d7dbc0e782fec491",
                                "sh_type": "工商股东",
                                "children": [],
                                "eid": "",
                                "identifier": "11",
                                "name": "李萍",
                                "type": "P"
                            },
                            {
                                "short_name": "钱秀琴",
                                "level": "3",
                                "amount": "0.625",
                                "has_problem": "0",
                                "percent": "0.0625",
                                "pid": "ae318e35f6e54b6bfefccf1c913e2564",
                                "sh_type": "工商股东",
                                "children": [],
                                "eid": "",
                                "identifier": "12",
                                "name": "钱秀琴",
                                "type": "P"
                            },
                            {
                                "short_name": "田金鹭",
                                "level": "3",
                                "amount": "0.625",
                                "has_problem": "0",
                                "percent": "0.0625",
                                "pid": "1b37d55ec0623cda2b0f5bf173b060a7",
                                "sh_type": "工商股东",
                                "children": [],
                                "eid": "",
                                "identifier": "13",
                                "name": "田金鹭",
                                "type": "P"
                            }
                        ],
                        "eid": "bb713bd6-6999-4335-8b18-1e4e4cd92276",
                        "identifier": "8",
                        "name": "五鼎通达(上海)食品科技中心(有限合伙)",
                        "type": "E"
                    }
                ],
                "eid": "6b38d70c-e01d-4548-92e6-0c3df677ac80",
                "identifier": "3",
                "name": "北京食通达科技发展有限公司",
                "type": "E"
            }
        ],
        "c_count": 10,
        "c_trees": [
            {
                "short_name": "青岛曜石麻六记酒",
                "level": "1",
                "amount": "100.0",
                "has_problem": "0",
                "percent": "1.0",
                "sh_type": "工商股东",
                "children": [],
                "eid": "dbc5122c-d56f-4fab-aa05-e8dfa8eae46f",
                "identifier": "15",
                "name": "青岛曜石麻六记酒店管理有限公司",
                "type": "E"
            },
            {
                "short_name": "成都麻六记餐饮管",
                "level": "1",
                "amount": "100.0",
                "has_problem": "0",
                "percent": "1.0",
                "sh_type": "工商股东",
                "children": [],
                "eid": "fc60ec15-db71-4252-b31d-1e4d3354669d",
                "identifier": "16",
                "name": "成都麻六记餐饮管理有限公司",
                "type": "E"
            },
            {
                "short_name": "太原麻六记酒店管",
                "level": "1",
                "amount": "100.0",
                "has_problem": "0",
                "percent": "1.0",
                "sh_type": "工商股东",
                "children": [],
                "eid": "63d94664-fd80-40fd-93a0-e695631c9ebd",
                "identifier": "17",
                "name": "太原麻六记酒店管理有限公司",
                "type": "E"
            },
            {
                "short_name": "北京麻六记酒店管",
                "level": "1",
                "amount": "100.0",
                "has_problem": "0",
                "percent": "1.0",
                "sh_type": "工商股东",
                "children": [
                    {
                        "short_name": "北京亦庄麻六记酒",
                        "level": "2",
                        "amount": "100.0",
                        "has_problem": "0",
                        "percent": "1.0",
                        "sh_type": "工商股东",
                        "children": [],
                        "eid": "4e0b5c24-bba4-4bee-a056-53d83d6264a0",
                        "identifier": "19",
                        "name": "北京亦庄麻六记酒店管理有限公司",
                        "type": "E"
                    },
                    {
                        "short_name": "北京乐堤港麻六记",
                        "level": "2",
                        "amount": "100.0",
                        "has_problem": "0",
                        "percent": "1.0",
                        "sh_type": "工商股东",
                        "children": [],
                        "eid": "7f258c98-c68c-4916-9af5-26b74f3c1e92",
                        "identifier": "20",
                        "name": "北京乐堤港麻六记酒店管理有限公司",
                        "type": "E"
                    },
                    {
                        "short_name": "北京银泰麻六记酒",
                        "level": "2",
                        "amount": "55.0",
                        "has_problem": "0",
                        "percent": "0.55",
                        "sh_type": "工商股东",
                        "children": [],
                        "eid": "3fb166e6-b780-4963-b1a4-0ffe94185d6b",
                        "identifier": "21",
                        "name": "北京银泰麻六记酒店管理有限公司",
                        "type": "E"
                    },
                    {
                        "short_name": "北京西直门麻六记",
                        "level": "2",
                        "amount": "55.0",
                        "has_problem": "0",
                        "percent": "0.55",
                        "sh_type": "工商股东",
                        "children": [],
                        "eid": "106dafe9-9c1a-485e-8580-76d87c7a8750",
                        "identifier": "22",
                        "name": "北京西直门麻六记酒店管理有限公司",
                        "type": "E"
                    }
                ],
                "eid": "980ff820-9473-40ba-b105-998ceec35823",
                "identifier": "18",
                "name": "北京麻六记酒店管理有限公司",
                "type": "E"
            },
            {
                "short_name": "上海麻六记餐饮管",
                "level": "1",
                "amount": "100.0",
                "has_problem": "0",
                "percent": "1.0",
                "sh_type": "工商股东",
                "children": [
                    {
                        "short_name": "上海守味麻六记餐",
                        "level": "2",
                        "amount": "100.0",
                        "has_problem": "0",
                        "percent": "1.0",
                        "sh_type": "工商股东",
                        "children": [],
                        "eid": "0fd17482-1465-11ed-8e23-83cf331ae46e",
                        "identifier": "24",
                        "name": "上海守味麻六记餐饮管理有限公司",
                        "type": "E"
                    }
                ],
                "eid": "21dfeb49-c277-4931-9717-a945735ad14b",
                "identifier": "23",
                "name": "上海麻六记餐饮管理有限公司",
                "type": "E"
            }
        ],
        "eid": "f6114a80-0f5b-4059-83f1-65dd0bdc6397",
        "p_count": 11,
        "has_problem": "0",
        "identifier": "1",
        "name": "北京麻六记餐饮管理有限公司",
        "type": "E"
    },
    "sign": "86f52c7430fe4797a01909365f28bb7f",
    "status": "200",
    "message": "操作成功"
}

js文件

import d3 from './d3.min.js'
import EquityJson from '@/api/EquityJson.json'
import deepcopy from 'deepcopy'

// 是否全称
let shortNameShow = false
// 是否显示编辑按钮
let editShow = false

var zoom,treeG
/* 如果需要将页面的整体高度拉伸
 *(折线的高度拉伸,公司长方体的块也的Y距也需要调整及所有标签Y轴都需要调整,
 * 始终保证折线的端点在长方形的中心点)
 */

// json数据结构改变

var rootData = {
	downward: {
		"direction": "downward",
		"name": "origin",
		"children": deepcopy(EquityJson.data.c_trees)
	},
	upward: {
		"direction": "upward",
		"name": "origin",
		"children": deepcopy(EquityJson.data.p_trees)
	}
}
var rootName = EquityJson.data.name;

let width = 0
let height = 0
var _this = this;
var rootRectWidth = 0; //根节点rect的宽度
var forUpward = true

// 数据重置
function resizeData() {
	shortNameShow = false
	editShow = false
	// 重新获取json数据
	rootData = {
		downward: {
			"direction": "downward",
			"name": "origin",
			"children": deepcopy(EquityJson.data.c_trees)
		},
		upward: {
			"direction": "upward",
			"name": "origin",
			"children": deepcopy(EquityJson.data.p_trees)
		}
	}
 	rootName = EquityJson.data.name
}

export function drawing() {
	if (d3.select('#svg')) {
		d3.select('#svg').remove();
		resizeData()
	}
	width = document.getElementById('mountNode').scrollWidth
	height = document.getElementById('mountNode').scrollHeight
	var d3GenerationChart = new treeChart(d3);
	d3GenerationChart.drawChart();
}
// 简称 全称切换
export function simpleChange1(val) {
	shortNameShow = val
	if (shortNameShow) {
		d3.selectAll(".text-g").attr('visibility', 'hidden');
		d3.selectAll(".short-text-g").attr('visibility', 'visible');
	} else {
		d3.selectAll(".text-g").attr('visibility', 'visible');
		d3.selectAll(".short-text-g").attr('visibility', 'hidden');
	}
}
// 编辑
export function editChange1(val) {
	editShow = val
	if (editShow) {
		d3.selectAll(".edit").attr('visibility', 'visible');
	} else {
		d3.selectAll(".edit").attr('visibility', 'hidden');
	}
}

	// 缩放
export function zoomClick(type) {
	// var clicked = d3.event.target,
		var direction = 1,
		factor = 0.3,
		target_zoom = 1,
		center = [width / 2, height / 2],
		extent = zoom.scaleExtent(),
		translate = zoom.translate(),
		translate0 = [],
		l = [],
		view = {
			x: translate[0],
			y: translate[1],
			k: zoom.scale()
		};

	// d3.event.preventDefault();
	direction = type === 1 ? 1 : -1;

	target_zoom = Number(zoom.scale() + factor * direction).toFixed(1)

	if (target_zoom === extent[0] || target_zoom === extent[1]) {
		return false
	}
	if (target_zoom < extent[0]) {
		target_zoom = extent[0]
	}
	if (target_zoom > extent[1]) {
		target_zoom = extent[1]
	}
	translate0 = [(center[0] - view.x) / view.k, (center[1] - view.y) / view.k];
	view.k = target_zoom;
	l = [translate0[0] * view.k + view.x, translate0[1] * view.k + view.y];

	view.x += center[0] - l[0];
	view.y += center[1] - l[1];
	// var d3GenerationChart = new treeChart(d3);
	// d3GenerationChart.drawChart();
	interpolateZoom([view.x, view.y], view.k);
}

// 重置刷新
export function refresh() {
	drawing()
}
	// d3.select("#reset").on("click", function(d) {
	// 	interpolateZoom([0, 0], 1);
	// });

	function interpolateZoom(translate, scale) {
		return d3
			.transition()
			.duration(350)
			.tween("zoom", function() {
				var iTranslate = d3.interpolate(zoom.translate(), translate),
					iScale = d3.interpolate(zoom.scale(), scale);
				return function(t) {
					zoom.scale(iScale(t)).translate(iTranslate(t));
					redraw();
				};
			});
}
function redraw() {
	treeG.attr('transform', 'translate(' + zoom.translate() + ')' +
		' scale(' + zoom.scale() + ')');
}

var treeChart = function(d3Object) {
	this.d3 = d3Object;
	this.directions = ['upward', 'downward'];
};

treeChart.prototype.drawChart = function() {
	// First get tree data for both directions.
	this.treeData = {};
	var self = this;
	self.directions.forEach(function(direction) {
		self.treeData[direction] = rootData[direction];
	});
	rootRectWidth = rootName.length * 15;
	self.graphTree(self.getTreeConfig());
};
treeChart.prototype.getTreeConfig = function() {
	var treeConfig = {};
	treeConfig.chartWidth = width
	treeConfig.chartHeight = height
	treeConfig.centralHeight = treeConfig.chartHeight / 2;
	treeConfig.centralWidth = treeConfig.chartWidth / 2;
	treeConfig.linkLength = 160; //箭头长度(上下节点距离)
	treeConfig.duration = 500; //动画时间
	return treeConfig;
};
treeChart.prototype.graphTree = function(config) {
	var self = this;
	var d3 = this.d3;
	var linkLength = config.linkLength;
	var duration = config.duration;
	var hasChildNodeArr = [];
	var id = 0;
	//折线
	var diagonal = function(obj) {
		var s = obj.d.source;
		var t = obj.d.target;
		return ("M" + s.x + "," + (s.y) + "L" + s.x + "," + (s.y + (t.y - s.y) / 2) + "L" + t.x + "," + (s.y + (t.y - s.y) / 2) + "L" + t.x + "," + (t.y));
		// return ("M" + s.x + "," + (s.y + 20) + "L" + s.x + "," + (s.y + 20 + (t.y - s.y) / 2) + "L" + t.x + "," + (s.y + 20 + (t.y - s.y) / 2) + "L" + t.x + "," + (t.y + 20));
	};
	zoom = d3.behavior.zoom().scaleExtent([0.5, 2]).on('zoom', redraw);
	var svg = d3.select('#mountNode')
		.append('svg')
		.attr('id', 'svg')
		.attr('width', '100%')
		.attr('height', '100%')
		.attr('viewBox', '0 0 ' + config.chartWidth + ' ' + config.chartHeight)
		.attr('xmlns', 'http://www.w3.org/2000/svg')
		// .on('mousedown', disableRightClick)
		.call(zoom)
		.on('dblclick.zoom', null);
	treeG = svg.append('g')
		.attr('class', 'gbox')
		.attr('transform', 'translate(0,0)');


	for (var d in this.directions) {
		var direction = this.directions[d];
		var data = self.treeData[direction];
		data.x0 = config.centralWidth;
		data.y0 = config.centralHeight;
		data.children.forEach(collapse);
		update(data, data, treeG);
	}

	function update(source, originalData, g) {
		var direction = originalData["direction"];
		forUpward = direction == "upward";
		var node_class = direction + "Node";
		var link_class = direction + "Link";
		var downwardSign = forUpward ? -1 : 1;
		var isExpand = false;
		var nodeSpace = 200;
		var tree = d3.layout.tree().sort(sortByDate).nodeSize([nodeSpace, 0]);
		var nodes = tree.nodes(originalData);
		var links = tree.links(nodes);
		var offsetX = -config.centralWidth;
		nodes.forEach(function(d) {
			d.y = downwardSign * (d.depth * linkLength) + config.centralHeight;
			d.x = d.x - offsetX;
			if (d.name == "origin") {
				d.x = config.centralWidth;
				d.y += downwardSign * 0; // 上下两树图根节点之间的距离
			}
		});

		// Update the node.
		var node = g.selectAll('g.' + node_class)
			.data(nodes, function(d) {
				return d.id || (d.id = ++id);
			})
		var nodeEnter = node.enter().append('g')
			.attr('class', node_class)
			.attr('transform', function(d) {
				return 'translate(' + source.x0 + ',' + source.y0 + ')';
			})
			.style('cursor', function(d) {
				return d.name == "origin" ?
					"" :
					d.children || d._children ?
					"pointer" :
					"";
			})
			.on('click', d => {
				if (d.direction == 'upward' || d.direction == 'downward') {
					// _this.$router.push({
					//   path: '/search/detail',
					//   name: 'search-detail',
					//   query: {
					//     companyId: d.direction == 'upward' ? d.beijingCrid : d.pbeijingCrid
					//     }
					//   })
				}
			})
			.on("mouseenter", nodeHover)
			.on("mouseleave", nodeOut);

		const rectG = nodeEnter.append("g")
		// 公司或股东长方形样式
		const rect = rectG.append("svg:rect")
			.attr("x", function(d) {
				return d.name == 'origin' ? -(rootRectWidth / 2) : -90;
			})
			.attr("y", function(d) {
				return d.name == "origin" ? -20 : forUpward ? -31 : -40;
			})
			.attr("width", function(d) {
				return d.name == 'origin' ? rootRectWidth : 180;
			})
			.attr("height", function(d) {
				return d.name == 'origin' ? 40 : 70;
			})
			.attr("rx", 0)
			.style('cursor', "pointer")
			// 边框线
			.style("stroke", "#128bed")
			// 字体填充颜色
			.style("fill", function(d) {
				if (d.name == 'origin') {
					return "#128bed"
				} else {
					return "#fff"
				}
			})
			.on("mouseenter", nodeHover);

		// 公司名称文本第一行  全称
		const textG = rectG.append("g")
			.attr('class', 'text-g')
			.attr('visibility', 'visible')
		textG.append("text")
			.attr("x", 0)
			.attr('dy', function(d) {
				if (d.name == 'origin') {
					return '.35em'
				} else if (forUpward) {
					return d.name.length > 10 ? '-1' : '10';
				} else {
					return d.name.length > 10 ? '-10' : '0';
				}
				// 后续方框底部有融资轮次,样式需要用这个
				//  else if (d.financingRound) {
				//   if (forUpward) {
				//     return d.name.length > 10 ? '0' : '0';
				//   } else {
				//     return d.name.length > 10 ? '-20' : '-10';
				//   }
				// } else {
				//   if (forUpward) {
				//     return d.name.length > 10 ? '-1' : '10';
				//   } else {
				//     return d.name.length > 10 ? '-10' : '0';
				//   }
				// }
			})
			.attr("text-anchor", "middle")
			.attr("fill", "#333")
			.text(function(d) {
				if (d.name == "origin") {
					return rootName;
				}
				if (d.repeated) {
					return "[Recurring] " + d.name;
				}
				return d.name.length > 10 ? d.name.substr(0, 10) : d.name;
			})
			.style({
				'fill': function(d) {
					if (d.name == 'origin') {
						return '#fff';
					}
				},
				'font-size': 14,
				'cursor': "pointer"
			})
			.on('click', Change_modal)
			.append('svg:title').text(d => d.name)

		// 公司名称文本第二行  全称
		textG.append("text")
			.attr("x", "0")
			.attr("dy", function(d) {
				if (d.name == 'origin') {
					return '.35em'
				} else if (forUpward) {
					return d.name.length > 10 ? '20' : '40';
				} else {
					return d.name.length > 10 ? '10' : '40';
				}
				// 后续方框底部有融资轮次,样式需要用这个
				//  else if (d.financingRound) {
				//   if (forUpward) {
				//     return d.name.length > 10 ? '-40' : '40';
				//   } else {
				//     return d.name.length > 10 ? '0' : '40';
				//   }
				// } else {
				//   if (forUpward) {
				//     return d.name.length > 10 ? '20' : '40';
				//   } else {
				//     return d.name.length > 10 ? '10' : '40';
				//   }
				// }
			})
			.attr("text-anchor", "middle")
			.text(function(d) {
				return d.name.length > 20 ? d.name.substr(10, 10) + '...' : d.name.substr(10, d.name.length);
			})
			.style({
				'fill': "#333", // 第二行字体颜色
				"font-size": 14,
				'cursor': "pointer"
			})
			.append('svg:title').text(d => d.name)

		// 公司名称文本第一行  简称
		const shortTextG = rectG.append("g")
			.attr('class', 'short-text-g')
			.attr('visibility', 'hidden')

		shortTextG.append("text")
			.attr("x", "0")
			.attr("dy", function(d) {
				if (d.name == 'origin') {
					return '.35em'
				} else {
					return forUpward ? 10 : 0
				}
				// 后续方框底部有融资轮次,样式需要用这个
				//  else if (d.financingRound) {
				//   if (forUpward) {
				//     return d.name.length > 10 ? '-40' : '40';
				//   } else {
				//     return d.name.length > 10 ? '0' : '40';
				//   }
				// } else {
				//   if (forUpward) {
				//     return d.name.length > 10 ? '20' : '40';
				//   } else {
				//     return d.name.length > 10 ? '10' : '40';
				//   }
				// }
			})
			.attr("text-anchor", "middle")
			.text(function (d) {
				return d.name == 'origin' ? rootName : d.short_name.length > 10 ? d.short_name.substr(0, 10) + '...' : d.short_name.substr(0, d.short_name.length);
			})
			.style({
				'fill': function (d) {
					return d.name == 'origin' ? '#fff' : "#333"
				},
				"font-size": 14,
				'cursor': "pointer",
			})
			.append('svg:title').text(d => d.name)
		
		// 最终受益人红色背景框 isKey
		const personTopRect = rectG.append("svg:rect")
			.attr("x", -40)
			.attr("y", -56)
			.attr("width", 80)
			.attr("height", function(d) {
				return d.isKey ? 18 : 0;
			})
			.attr("rx", 2)
			.style("stroke", "#FA6B64")
			.style("fill", "#FA6B64")
		// 最终受益人红色小三角形 isKey
		rectG
			.append("svg:path")
			.attr("fill", d => {
				return d.isKey ? "#FA6B64" : ""
			})
			.attr("d", function(d) {
				return d.isKey ? "M0 -33 L-5 -38 L5 -38 Z" : ""
			})
		// 最终受益人 文本 isKey
		rectG.append("text")
			.attr("x", 0)
			.attr("dy", -43)
			.attr("text-anchor", "middle")
			.style("fill", "#fff")
			.style('font-size', 10)
			.text(function(d) {
				return d.isKey ? "最终受益人" : '';
			});
		// 融资轮次背景框 financingRound
		const financingRoundRect = rectG.append('svg:rect')
			.attr("x", "-89")
			.attr("y", function(d) {
				return forUpward ? 18 : 9;
			})
			.attr("rx", 2)
			.attr("width", function(d) {
				return d.financingRound ? 178 : 0;
			})
			.attr("height", function(d) {
				return d.financingRound ? 20 : 0;
			})
			.style("fill", "#e9f3ff")

		// 融资轮次文字  financingRound
		rectG.append("text")
			.attr("x", "0")
			.attr("dy", () => {
				return forUpward ? 29 : 20
			})
			.attr("text-anchor", "middle")
			.attr("dominant-baseline", "middle")
			.style("fill", "#128bed")
			.style('font-size', 12)
			.text(function(d) {
				return d.financingRound ? "融资轮次:天使轮" : "";
			});
		// 注销红色标签背景 state
		const holdingCompanyRect = rectG.append('svg:rect')
			.attr("x", "55")
			.attr("y", function(d) {
				return d.name == 'origin' ? '.35em' : forUpward ? '-40' : '-50';
			})
			.attr("rx", 2)
			.attr("width", function(d) {
				return d.state ? 30 : 0;
			})
			.attr("height", function(d) {
				return d.state ? 18 : 0;
			})
			.style("fill", "#FFEEE5")

		// 注销红色标签文字
		rectG.append("text")
			.attr("x", "70")
			.attr("dy", function(d) {
				return (d.name == 'origin') ? '.35em' : forUpward ? '-27' : '-37';
			})
			.attr("text-anchor", "middle")
			.style("fill", "#FF722D")
			.style('font-size', 11)
			.text(function(d) {
				return d.state ? "注销" : "";
			});

		// 持资占比文字
		rectG
			.append("text")
			.attr("x", "18")
			.attr("dy", function(d) {
				return d.name == "origin" ? ".35em" : forUpward ? "50" : "-48";
			})
			.attr("text-anchor", "start")
			.attr("class", "linkname")
			.style("fill", "#128bed") //比例颜色(55%)
			.style("font-size", 10)
			.text(function(d) {
				if (d.percent != "0" && d.percent != "") {
					return d.name == "origin" ? "" : parseInt(parseFloat(d.percent) * 100) + '%';
				}
			})
			.on("mouseenter", nodeOut)
			.on("mouseleave", nodeOut);

		// 加减号圈
		rectG
			.append("circle")
			.attr('r', function(d) {
				return d.name == 'origin' ? 0 : (d.children && d.children.length || d._children && d._children
					.length) ? 10 : 0
			})
			.attr('cy', function(d) {
				return (d.name == 'origin') ? -20 : (forUpward) ? -42 : 41;
			})
			.style('fill', function(d) {
				return (d.children && d.children.length || d._children && d._children.length) ? "#fff" :
					"" //展开按钮背景颜色
			})
			.style("stroke", function(d) {
				// +号的外圈颜色 展开按钮背景颜色
				return hasChildNodeArr.indexOf(d) != -1 ?
					"#128bed" :
					""
			})
			.style('stroke-width', function(d) {
				if (d.repeated) {
					return 5;
				}
			})
			.on("mouseenter", nodeOut)
			.on("mouseleave", nodeOut);
		// + - 号样式及绑定点击事件
		rectG
			.append("svg:text")
			.attr("class", "isExpand")
			.attr("x", "0")
			.attr("dy", function(d) {
				return forUpward ? -40 : 42.5;
			})
			.attr("text-anchor", "middle")
			.style("fill", function(d) {
				return d.type != "P" ? "#128bed" : "#FF4D4D";
			})
			.style('cursor', 'pointer')
			.style('font-size', 20)
			//+、-字体颜色
			.text(function(d) {
				if (d.name == "origin") {
					return "";
				}
				return d._children ? "+" : ''
			})
			.on("click", click)
			.on("mouseenter", nodeOut)
			.on("mouseleave", nodeOut);
		
		// 编辑按钮圈
		const treeC = rectG.append("g")
			.attr('class', 'edit')
			.attr('visibility', 'hidden')
		
		treeC.append("circle")
			.attr('r', function(d) {
				return d.name == 'origin' ? 0 : 10
			})
			.attr('cx', function (d) {
				return (d.name == 'origin') ? 0 : 90;
			})
			.attr('cy', function(d) {
				return (d.name == 'origin') ? -20 : (forUpward) ? -35 : -40;
			})
			.style('fill', "#FF6060")
			.on("mouseenter", nodeOut)
			.on("mouseleave", nodeOut);
		// 编辑按钮×号样式及绑定点击事件
		treeC
			.append("svg:text")
			.attr("class", "isExpand")
			.attr("x", "0")
			.attr("dx", 90)
			.attr("dy", function(d) {
				return forUpward ? -33.5 : -38;
			})
			.attr("text-anchor", "middle")
			.style("fill", '#fff')
			.style('cursor', 'pointer')
			.style('font-size', 20)
			.text(function(d) {
				return d.name == "origin"? '':'×'
			})
			.on("click", editBtnClick)
			.on("mouseenter", nodeOut)
			.on("mouseleave", nodeOut);

		// Transition nodes to their new position.原有节点更新到新位置
		var nodeUpdate = node.transition()
			.duration(duration)
			.attr('transform', function(d) {
				return 'translate(' + d.x + ',' + d.y + ')';
			});

		nodeUpdate.select('text').style('fill-opacity', 1)

		nodeUpdate.select('text').style('fill-opacity', 1)

		var nodeExit = node.exit().transition()
			.duration(duration)
			.attr('transform', function(d) {
				return 'translate(' + source.x + ',' + source.y + ')';
			})
			.remove();
		nodeExit.select('circle')
			.attr('r', 1e-6)
		nodeExit.select('text')
			.style('fill-opacity', 1e-6);

		var link = g.selectAll('path.' + link_class)
			.data(links, function(d) {
				return d.target.id;
			});

		//箭头(下半部分)
		var markerDown = svg
			.append("marker")
			.attr("id", "resolvedDown")
			.attr("markerUnits", "strokeWidth") //设置为strokeWidth箭头会随着线的粗细发生变化
			.attr("markerUnits", "userSpaceOnUse")
			.attr("viewBox", "0 -5 10 10") //坐标系的区域
			.attr("refX", 51) //箭头坐标
			.attr("refY", 0)
			.attr("markerWidth", 10) //标识的大小
			.attr("markerHeight", 10)
			.attr("orient", "90") //绘制方向,可设定为:auto(自动确认方向)和 角度值
			.attr("stroke-width", 2) //箭头宽度
			.append("path")
			.attr("d", "M0,-5L10,0L0,5") //箭头的路径
			.attr("fill", "#128bed")
			.attr("fill-opacity", 1); //箭头颜色
		//箭头(上半部分)
		var markerUp = svg
			.append("marker")
			.attr("id", "resolvedUp")
			.attr("markerUnits", "strokeWidth") //设置为strokeWidth箭头会随着线的粗细发生变化
			.attr("markerUnits", "userSpaceOnUse")
			.attr("viewBox", "0 -5 10 10") //坐标系的区域
			.attr("refX", -50) //箭头坐标
			.attr("refY", 0)
			.attr("markerWidth", 10) //标识的大小
			.attr("markerHeight", 10)
			.attr("orient", "90") //绘制方向,可设定为:auto(自动确认方向)和 角度值
			.attr("stroke-width", 2) //箭头宽度
			.append("path")
			.attr("d", "M0,-5L10,0L0,5") //箭头的路径
			.attr("fill", "#128bed")
			.attr("fill-opacity", 1); //箭头颜色

		// 折线及三角形样式
		link.enter()
			.insert("path", "g")
			.attr("class", link_class)
			.attr("stroke", function(d) {
				return "#bbb";
			})
			.attr("fill", "none")
			.attr("stroke-width", "1px")
			.attr("opacity", 0.5)
			.attr("d", function(d) {
				var o = {
					x: source.x0,
					y: source.y0,
				};
				return diagonal({
					source: o,
					target: o,
					d,
				});
			})
			.attr("marker-end", function(d) {
				return forUpward ? "url(#resolvedUp)" : "url(#resolvedDown)";
			}) //根据箭头标记的id号标记箭头;
			.attr("id", function(d, i) {
				return "mypath" + i;
			});
		link.transition()
			.duration(duration)
			.attr('d', function(d) {
				return diagonal({
					d
				});
			});
		link.exit().transition()
			.duration(duration)
			.attr('d', function(d) {
				var o = {
					x: source.x,
					y: source.y
				};
				return diagonal({
					source: o,
					target: o,
					d
				});
			})
			.remove();
		nodes.forEach(function(d) {
			d.x0 = d.x;
			d.y0 = d.y;
		});

		//添加动态关系线
		function nodeHover(d, i) {
			if (d.name != "origin") {
				if (d.parent.direction == "downward") {
					var links = d3.selectAll(".downwardLink")[0];
					//当前节点的子级节点
					links.map((item, index) => {
						if (item.__data__.source.id == d.id) {
							if (d.children) {
								d.children.forEach((citem) => {
									if (item.__data__.target.id == citem.id) {
										d3.select(item).attr(
											"class",
											"downwardLink downLine"
										);
									}
								});
							}
						} else if (
							item.__data__.source.id == d.parent.id &&
							item.__data__.target.id == d.id
						) {
							d3.select(item).attr("class", "downwardLink downLine");
						}
					});
					//递归处理当前节点的祖先节点
					function changeUpLink(d) {
						links.map((item, index) => {
							if (d.name != "origin") {
								if (
									item.__data__.source.id == d.parent.id &&
									item.__data__.target.id == d.id
								) {
									d3.select(item).attr("class", "downwardLink downLine");
								}
							}
						});
						if (d.depth > 1) {
							if (!d.parent) {
								return;
							} else {
								changeUpLink(d.parent);
							}
						}
					}
					// changeUpLink(d, true);
				} else {
					var links = d3.selectAll(".upwardLink")[0];
					for (let i = 0; i < links.length; i++) {
						let item = links[i];
						if (item.__data__.source.id == d.id) {
							if (d.children) {
								d.children.forEach((citem) => {
									if (item.__data__.target.id == citem.id) {
										// console.log(item)
										d3.select(item).attr("class", "upwardLink upLine");
									}
								});
							}
						} else if (
							item.__data__.source.id == d.parent.id &&
							item.__data__.target.id == d.id
						) {
							d3.select(item).attr("class", "upwardLink upLine");
						}
					}

					function cancelUpLink(d) {
						for (let i = 0; i < links.length; i++) {
							let item = links[i];
							if (d.name != "origin") {
								if (
									item.__data__.source.id == d.parent.id &&
									item.__data__.target.id == d.id
								) {
									d3.select(item).attr("class", "upwardLink upLine");
								}
							}
						}
						if (d.parent) {
							cancelUpLink(d.parent);
						}
					}
					// cancelUpLink(d);
				}
			}
		}

		function nodeOut(d, i) {
			if (d.name != "origin") {
				if (d.parent.direction == "downward") {
					var links = d3.selectAll(".downwardLink")[0];
					for (let i = 0; i < links.length; i++) {
						let item = links[i];
						if (
							d3.select(item).attr("class").indexOf("downLine") != "-1"
						) {
							d3.select(item).attr("class", "downwardLink");
						}
					}
				} else {
					var links = d3.selectAll(".upwardLink")[0];
					for (let i = 0; i < links.length; i++) {
						let item = links[i];
						if (d3.select(item).attr("class").indexOf("upLine") != "-1") {
							d3.select(item).attr("class", "upwardLink");
						}
					}
				}
			}
		}

		function Change_modal() {
			_this.Modal = true
		}

		function click(d) {
			event.stopPropagation()
			if (forUpward) {} else {
				if (d._children) {
					console.log('对外投资--ok')
				} else {
					console.log('对外投资--no')
				}
			}
			isExpand = !isExpand;
			if (d.name == 'origin') {
				return;
			}
			if (d.children) {
				d._children = d.children;
				d.children = null;
				d3.select(this).text('+')
				update(d, originalData, g);
			} else {
				if (d._children && d._children.length > 0) {
					d.children = d._children;
					d._children = null;
					if (d.name == 'origin') {
						d.children.forEach(expand);
					}
					d3.select(this).text('-')
					update(d, originalData, g);
					simpleChange1(shortNameShow)
					editChange1(editShow)
				} else {
					// gqctt({
					// 	beijingCrid: d.direction == 'upward' ? d.beijingCrid : d.pbeijingCrid,
					// 	direction: d.direction
					// }).then(res => {
					// 	if (res.code === 0) {
					// 		if (d.direction == 'upward') {
					// 			d.children = res.result.investorList
					// 			d.children.map(item => {
					//   		item.amount = Number(item.subConAm).toFixed(2)
					// 				item.isKey = true
					// 				item.percent = item.subComBl.length > 6 ?
					// 					calculation.accMul(item.subComBl, 100).toFixed(2) + '%' :
					// 					calculation.accMul(item.subComBl, 100) + '%'
					//     item.name = item.entName
					// 				item.type = item.bz === '企业' ? 2 : 1
					// 				item.isKey = item.subComBl >= 0.25 && item.type == 1
					// 				item.direction = direction
					// 				item.holderPercent = item.percent
					// 			})
					// 		} else {
					// 			d.children = res.result.holderList
					// 			d.children.map(item => {
					// 				item.amount = Number(item.subConAm).toFixed(2)
					// 				item.isKey = true
					// 				item.percent = item.subComBl.length > 6 ?
					// 					calculation.accMul(item.subComBl, 100).toFixed(2) + '%' :
					// 					calculation.accMul(item.subComBl, 100) + '%'
					// 				item.name = item.pentName
					// 				item.type = item.bz === '企业' ? 2 : 1
					// 				item.isKey = item.subComBl >= 0.25 && item.type == 1
					// 				item.direction = direction
					// 				item.holderPercent = item.percent
					// 			})
					// 		}
					// 		d._children = null;
					// 		if (d.name == 'origin') {
					// 			d.children.forEach(expand);
					// 		}
					// 		d3.select(this).text('-')
					// 		update(d, originalData, g)
					// 	}
					// })
				}
			}
		}
		function editBtnClick(d) {
			if (d.name == 'origin') {
				return;
			} else {
				const filterId = (data, id) => {
					if (!Array.isArray(data)) {
						return data
					}
					return data.filter(item => {
						if ('children' in item) {
							item.children = filterId(item.children, id)
						} else if ('_children' in item) {
							item._children = filterId(item._children, id)
						}
						return (item.id === undefined || item.id !== id)
					})
				}
				const filtredData = filterId([originalData], d.id)
				update(d, filtredData[0], g);
			}
		}
	}

	function expand(d) {
		if (d._children) {
			d.children = d._children;
			d.children.forEach(expand);
			d._children = null;
		}
	}

	function collapse(d) {
		if (d.children && d.children.length != 0) {
			d._children = d.children;
			d._children.forEach(collapse);
			d.children = null;
			hasChildNodeArr.push(d);
		}
	}

	

	function disableRightClick() {
		// stop zoom
		if (d3.event.button == 2) {
			console.log('No right click allowed');
			d3.event.stopImmediatePropagation();
		}
	}

	function sortByDate(a, b) {
		var aNum = a.name.substr(a.name.lastIndexOf('(') + 1, 4);
		var bNum = b.name.substr(b.name.lastIndexOf('(') + 1, 4);
		return d3.ascending(aNum, bNum) ||
			d3.ascending(a.name, b.name) ||
			d3.ascending(a.id, b.id);
	}
};

混入的jsD3Mixin.js

/**
 * 全屏 toggleFullScreen
 * 保存 downloadImpByChart
 */
export const D3Mixin = {
  data() {
    return {
      isFullscreen: true,
    }
  },
  methods: {
    downloadSvgFn(svg, width, height, chartName, rootName) {
      var serializer = new XMLSerializer()
      var source = '<?xml version="1.0" standalone="no"?>\r\n' + serializer.serializeToString(svg)
      var image = new Image()
      image.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(source)
      image.onload = function () {
        var canvas = document.createElement('canvas')
        canvas.width = width + 40;
        canvas.height = height + 40;
        var context = canvas.getContext('2d');
        context.rect(0, 0, width + 40, height + 40);
        context.fillStyle = '#fff';
        context.fill();
        context.drawImage(image, 20, 20);
        var url = canvas.toDataURL("image/png");
        var a = document.createElement("a");
        a.download = chartName + '-' + rootName + ".png";
        a.href = url;
        a.click();
        return
      }
    },
    downloadImpByChart(chartName, rootName, zoomClassName = '') {
      //得到svg的真实大小    
      let box = document.querySelector('svg').getBBox(),
        x = box.x,
        y = box.y,
        width = box.width,
        height = box.height;
      if (zoomClassName) {
        //查找zoomObj
        var zoomObj = svg.getElementsByClassName(zoomClassName.replace(/\./g, ''))[0];
        if (!zoomObj) {
          return false;
        }
        /*------这里是处理svg缩放的--------*/
        var transformMath = zoomObj.getAttribute('transform'),
          scaleMath = zoomObj.getAttribute('transform');
        if (transformMath || scaleMath) {
          var transformObj = transformMath.match(/translate\(([^,]*),([^,)]*)\)/),
            scaleObj = scaleMath.match(/scale\((.*)\)/);
          if (transformObj || scaleObj) { //匹配到缩放
            var translateX = transformObj[1],
              translateY = transformObj[2],
              scale = scaleObj[1];
            x = (x - translateX) / scale;
            y = (y - translateY) / scale;
            width = width / scale;
            height = height / scale;
          }
        }
      }
      //克隆svg
      var node = svg.cloneNode(true);
      //重新设置svg的width,height,viewbox
      node.setAttribute('width', width);
      node.setAttribute('height', height);
      node.setAttribute('viewBox', [x, y, width, height]);
      if (zoomClassName) {
        var zoomObj = node.getElementsByClassName(zoomClassName.replace(/\./g, ''))[0];
        /*-------------清楚缩放元素的缩放-------------*/
        zoomObj.setAttribute('transform', 'translate(0,0) scale(1)');
      }
      this.downloadSvgFn(node, width, height, chartName, rootName);
    },
    checkFull() {
      var isFull =
        document.fullscreenEnabled || window.fullScreen || document.webkitIsFullScreen || document.msFullscreenEnabled
      if (isFull === undefined) {
        isFull = false
      }
      return isFull
    },
    FullScreen(el) {
      if (this.isFullscreen) {
        //退出全屏
        if (document.exitFullscreen) {
          document.exitFullscreen()
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
        } else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen()
        } else if (!document.msRequestFullscreen) {
          document.msExitFullscreen()
        }
      } else {
        //进入全屏
        if (el.requestFullscreen) {
          el.requestFullscreen()
        } else if (el.mozRequestFullScreen) {
          el.mozRequestFullScreen()
        } else if (el.webkitRequestFullscreen) {
          //改变平面图在google浏览器上面的样式问题
          el.webkitRequestFullscreen()
        } else if (el.msRequestFullscreen) {
          this.isFullscreen = true
          el.msRequestFullscreen()
        }
      }
    },
    toggleFullScreen(e) {
      this.isFullscreen = !this.isFullscreen
      this.FullScreen(document.getElementById('borrow'))
    }
  },
  mounted() {
    window.addEventListener('resize', () => {
      let that = this
      if (!that.checkFull()) {
        //要执行的动作
        that.isFullscreen = true
      }
    })
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/186279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【蓝桥杯基础题】2018年省赛—日志统计

&#x1f451;专栏内容&#xff1a;蓝桥杯刷题⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录一、题目描述1.问题描述2.输入格式3.输出格式4.一个例子二、题目分析1、暴力法2、双指针三、代码汇总1、暴力代码汇总2、双…

【Mysql第一期 数据库概述】

文章目录1. 为什么要使用数据库2. 数据库与数据库管理系统2.1 数据库的相关概念2.2 数据库特点2.3SQL优点3.常见的数据库介绍1.Oracle2.SQL Server3.MySQL4.Access5.DB26.PostgreSQL7.SQLite8.informix4. MySQL介绍4.1Mysql重大历史事件4.2 关于MySQL 8.04.3 Why choose MySQL?…

linux内核读文件代码分析

linux下“一切皆文件”,所有设备都可以被抽象成文件,用户态可以通过open、read、write、llseek等api操作一个文件,通过系统调用进入内核态,最终访问到pagecache/磁盘上的数据,然后返回给用户态。 kernel version:v6.2-rc4 社区master主干 用户态应用程序调用read接口,通…

【转载】车载传感器与云端数据交换标准SensorIS的理解与使用

原文 https://zhuanlan.zhihu.com/p/386277784 1、什么是SensorIS?SensorIS全称是Sensor Interface Specification&#xff0c;翻译为中文就是传感器接口规范&#xff0c;是由来自全球汽车行业的主机厂、地图和数据提供商、传感器制造商和电信运营商共同组成的开放团体发布的一…

JavaEE day10 初识SpringMVC

JSON简介 JSON &#xff1a;JavaScript Object Notation JS对象表示法 是轻量级的文本数据交换格式&#xff0c;但是JSON仍然独立于语言和平台。其解析器和库支持许多不同的编程语言。目前非常多的动态编程语言&#xff08;java&#xff0c;PHP&#xff09;都支持JSON。JSON…

禅道好用吗?优缺点及类似10大项目管理系统介绍

类似禅道的十大项目管理软件&#xff1a;1、一站式研发项目管理软件PingCode&#xff1b;2、通用型项目协作工具Worktile&#xff1b;3、开源项目管理软件Redmine&#xff1b;4、免费项目管理软件Trello&#xff1b;5、无代码项目管理软件Monday&#xff1b;6、IT项目追踪管理工…

面试宝典-数据库基础

数据库基础前言一、数据库1.1 sql练习题1.2 sql语句执行顺序1.3 sql语句编写前言 本文主要记录B站视频视频链接的内容&#xff0c;做到知识梳理和总结的作用&#xff0c;项目git地址。 一、数据库 1.1 sql练习题 user表数据: idusername1张三2李四3王五4小刘 user_role表数…

CrackQL:一款功能强大的图形化密码爆破和模糊测试工具

关于CrackQL CrackQL是一款功能强大的图形化密码爆破和模糊测试工具&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以针对密码安全和应用程序安全进行渗透测试。 除此之外&#xff0c;CrackQL同时也是一款通用的GraphQL渗透测试工具&#xff0c;它可以控制速率限制…

垃圾分类智能分析系统 yolov7

垃圾分类智能分析系统应用pythonyolov7网络模型深度学习识别技术&#xff0c;自动识别违规投放行为并现场进行语音提示实时预警。如垃圾满溢抓拍预警、人脸识别、工服识别、厨余垃圾混投未破袋识别预警、垃圾落地识别预警、人来扔垃圾语音提醒等。我们选择当下YOLO最新的卷积神…

数组去重的七种方法

数组去重的七种方法1. 双重for循环2. forindexOf3.es6 set4.filter5.includes6.创建一个新的object7.new Map()1. 双重for循环 第1种是定义一个新的空数组&#xff0c;再执行嵌套双循环&#xff0c;监测空数组中如果没有的元素&#xff0c;push进空数组中。这个方法考察了conti…

AcWing - 寒假每日一题2023(DAY 16——DAY 20)

文章目录一、AcWing 4455. 出行计划&#xff08;简单&#xff09;1. 实现思路2. 实现代码二、AcWing 4510. 寻宝&#xff01;大冒险&#xff01;&#xff08;简单&#xff09;1. 实现思路2. 实现代码三、AcWing 3422. 左孩子右兄弟&#xff08;中等&#xff09;1. 实现思路2. 实…

【MySQL】过年没有回老家,在出租屋里整理了一些思维导图

Xmind导图知识点Mysql知识点SQL知识点Mybatis知识点面试题分享MySQL部分Mybatis部分Mysql知识点 通过下面的图片可以看出&#xff0c;MySQL基础语法分为四部分&#xff1a;连接数据库&#xff0c;对数据库的操作&#xff0c;对表中的数据操作&#xff0c;对表操作等等。 SQL…

python exe程序注册为window系统服务

1、使用pyinstaller将py打包成exe 1、安装 pip install pyinstaller2、打包成exe可执行文件 pyinstaller -F packTest.py #packTest.py为待打包的py文件打包成功后会在同级目录中生成两个文件夹和一个文件&#xff0c;分别为dist和build文件夹&#xff0c;以及一份与.py文件同…

Java——最大子数组和

题目链接 leetcode在线oj题——最大子数组和 题目描述 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 题目示例 输入&#xff1a;…

Vulnhub DC-4靶机渗透

环境准备DC-4靶机 ip&#xff1a;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;kali攻击机 ip&#xff1a;192.168.153.128一、信息收集kali攻击机中&#xff0c;使用 arp-scan -l 扫描c段&#xff08;-l为扫描c段&#xff09;确定靶…

自动驾驶——智能配电

一、汽车配电 汽车配电&#xff08;Power Distrubition Unit&#xff0c;PDU&#xff09;分为低压配电与高压配电&#xff0c;即低压PDU与高压PDU。 二、传统控制方式——PCB式电器盒 传统配电盒&#xff08;机电器件&#xff09;&#xff1a; &#xff08;1&#xff09;继…

为什么要做黑盒测试?黑盒测试有什么作用?

对于软件测试的从业者来说&#xff0c;黑盒测试是十分重要的测试方式&#xff0c;它可以弥补白盒测试检查不到的部分。可能刚刚入门的测试小白&#xff0c;对于为什么要做黑盒测试&#xff1f;黑盒测试有什么作用&#xff1f;仍然抱有很大的疑问。下面小编就来从黑盒测试的概念…

QT入门Buttons之QPushButton

目录 一、界面布局介绍 1、布局器中的位置及使用 2、控件的界面属性 3、常用基本属性介绍 3.1控件名称 3.2控件大小属性 3.3按钮上的文字设置 3.4设置按钮的样式 二、属性功能介绍 1、常用方法介绍 2、基本信号介绍 三、Demo展示 一、界面布局介绍 1、布局器中的位…

丰田埃尔法商务租车价格是多少,它的性能到底有多好呢

丰田埃尔法作为MPV之王。埃尔法的高腰线和深色玻璃也使内部更具神秘感&#xff0c;惹眼闪烁的进气格栅&#xff0c;类似盔甲一般的全镀铬饰条构成的霸道前脸和富于设计感的车身曲线&#xff0c;细节处采用36颗闪亮镀铬装饰点缀&#xff0c;有着很高的辨识性。保持了典型的MPV风…

需要代理上网的linux服务器,无法使用NTP同步时间,只需要这一行指令即可。

这将会是一篇让你对时间同步受益匪浅的文章&#xff01;如果你看完之后有收获&#xff0c;希望你能加个关注&#xff0c;如果你看完之后没有收获&#xff0c;希望你能留下你路过的痕迹。 由于工作需要&#xff0c;我们使用了一款神奇的调度框架&#xff0c;叫powerjob&#xff…