123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /**
- * Networkgraph series
- *
- * (c) 2010-2019 Paweł Fus
- *
- * License: www.highcharts.com/license
- */
- 'use strict';
- import H from '../../parts/Globals.js';
- var QuadTreeNode = H.QuadTreeNode = function (box) {
- this.box = box;
- this.nodes = []; // Array of 4 -> quad
- this.children = []; // Deferred leafs
- this.mass = 1;
- this.centerX = 0;
- this.centerY = 0;
- };
- H.extend(
- QuadTreeNode.prototype,
- {
- insert: function (node) {
- this.mass++;
- if (!this.centerX) {
- this.centerX = node.plotX;
- this.centerY = node.plotY;
- } else {
- this.centerX = (this.centerX + node.plotX) / 2;
- this.centerY = (this.centerY + node.plotY) / 2;
- }
- if (this.nodes.length) {
- this.nodes[this.getBoxPosition(node)].insert(node);
- } else {
- if (this.children.length < 3) {
- this.children.push(node);
- } else {
- this.divideBox();
- this.children.forEach(function (child) {
- this.insert(child);
- }, this);
- this.insert(node);
- }
- }
- },
- divideBox: function () {
- var halfWidth = this.box.width / 2,
- halfHeight = this.box.height / 2;
- this.nodes[0] = new QuadTreeNode({
- left: this.box.left,
- top: this.box.top,
- width: halfWidth,
- height: halfHeight
- });
- this.nodes[1] = new QuadTreeNode({
- left: this.box.left + halfWidth,
- top: this.box.top,
- width: halfWidth,
- height: halfHeight
- });
- this.nodes[2] = new QuadTreeNode({
- left: this.box.left + halfWidth,
- top: this.box.top + halfHeight,
- width: halfWidth,
- height: halfHeight
- });
- this.nodes[3] = new QuadTreeNode({
- left: this.box.left,
- top: this.box.top + halfHeight,
- width: halfWidth,
- height: halfHeight
- });
- },
- getBoxPosition: function (node) {
- var left = node.plotX < this.box.left + this.box.width / 2,
- top = node.plotY < this.box.top + this.box.height / 2,
- index;
- if (left) {
- if (top) {
- // Top left
- index = 0;
- } else {
- // Bottom left
- index = 3;
- }
- } else {
- if (top) {
- // Top right
- index = 1;
- } else {
- // Bottom right
- index = 2;
- }
- }
- return index;
- }
- }
- );
- var QuadTree = H.QuadTree = function (x, y, width, height) {
- // Boundary rectangle:
- this.rect = {
- left: x,
- top: y,
- width: width,
- height: height
- };
- this.root = new QuadTreeNode(this.rect);
- };
- H.extend(
- QuadTree.prototype,
- {
- insertNodes: function (nodes) {
- nodes.forEach(function (node) {
- this.root.insert(node);
- }, this);
- },
- clear: function (chart) {
- this.render(chart, true);
- },
- visitNodeRecursive: function (node, chart, clear) {
- node.nodes.forEach(
- function (qtNode) {
- if (qtNode.children.length) {
- this.renderBox(qtNode, chart, clear);
- this.visitNodeRecursive(qtNode, chart, clear);
- }
- },
- this
- );
- },
- render: function (chart, clear) {
- this.visitNodeRecursive(this.root, chart, clear);
- },
- renderBox: function (qtNode, chart, clear) {
- if (!qtNode.graphic) {
- qtNode.graphic = chart.renderer
- .rect(
- qtNode.box.left + chart.plotLeft,
- qtNode.box.top + chart.plotTop,
- qtNode.box.width,
- qtNode.box.height
- )
- .attr({
- stroke: 'red',
- 'stroke-width': 2
- })
- .add();
- } else if (clear) {
- qtNode.graphic = qtNode.graphic.destroy();
- }
- if (qtNode.graphic) {
- qtNode.graphic.animate({
- x: qtNode.box.left + chart.plotLeft,
- y: qtNode.box.top + chart.plotTop,
- width: qtNode.box.width,
- height: qtNode.box.height
- });
- }
- }
- }
- );
|