test: 🚨 add getMatrixOfElement test demo
This commit is contained in:
346
examples/x6-example-features/src/pages/performance/matrix.tsx
Normal file
346
examples/x6-example-features/src/pages/performance/matrix.tsx
Normal file
@ -0,0 +1,346 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, Dom, Rectangle } from '@antv/x6'
|
||||
import { Button } from 'antd'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
private graph: Graph
|
||||
private source: Node
|
||||
|
||||
componentDidMount() {
|
||||
this.graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
resizing: true,
|
||||
rotating: true,
|
||||
panning: true,
|
||||
mousewheel: true,
|
||||
})
|
||||
|
||||
this.source = this.graph.addNode({
|
||||
shape: 'rect',
|
||||
x: 80,
|
||||
y: 80,
|
||||
width: 160,
|
||||
height: 160,
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'shape1',
|
||||
},
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'shape2',
|
||||
},
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'shape3',
|
||||
},
|
||||
{
|
||||
tagName: 'circle',
|
||||
selector: 'shape4',
|
||||
},
|
||||
{
|
||||
tagName: 'circle',
|
||||
selector: 'shape5',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'shape6',
|
||||
},
|
||||
{
|
||||
tagName: 'g',
|
||||
selector: 'g1',
|
||||
children: [
|
||||
{
|
||||
tagName: 'g',
|
||||
selector: 'g2',
|
||||
children: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'shape7',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
shape1: {
|
||||
id: 's1',
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
stroke: 'black',
|
||||
},
|
||||
shape2: {
|
||||
id: 's2',
|
||||
x: 10,
|
||||
y: 100,
|
||||
width: 50,
|
||||
height: 50,
|
||||
stroke: 'green',
|
||||
fill: 'transparent',
|
||||
},
|
||||
shape3: {
|
||||
id: 's3',
|
||||
refX: '50%',
|
||||
refY: '50%',
|
||||
refWidth: '50%',
|
||||
refHeight: '50%',
|
||||
stroke: 'green',
|
||||
fill: 'transparent',
|
||||
},
|
||||
shape4: {
|
||||
id: 's4',
|
||||
cx: 40,
|
||||
cy: 40,
|
||||
r: 40,
|
||||
stroke: 'red',
|
||||
fill: 'white',
|
||||
},
|
||||
shape5: {
|
||||
id: 's5',
|
||||
refCx: '50%',
|
||||
refCy: '50%',
|
||||
refR: '20%',
|
||||
stroke: 'red',
|
||||
fill: 'white',
|
||||
},
|
||||
shape6: {
|
||||
id: 's6',
|
||||
text: 'text',
|
||||
},
|
||||
g1: {
|
||||
transform: 'matrix(1.2,0,0,1.2,80,80)',
|
||||
},
|
||||
g2: {
|
||||
transform: 'matrix(1,0,0,1,100,100)',
|
||||
},
|
||||
shape7: {
|
||||
id: 's7',
|
||||
x: 30,
|
||||
y: 30,
|
||||
width: 50,
|
||||
height: 50,
|
||||
fill: 'yellow',
|
||||
},
|
||||
},
|
||||
ports: {
|
||||
groups: {
|
||||
top: {
|
||||
position: {
|
||||
name: 'top',
|
||||
args: {
|
||||
dx: 10,
|
||||
dy: -10,
|
||||
angle: 20,
|
||||
},
|
||||
},
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 8,
|
||||
magnet: true,
|
||||
stroke: 'red',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
id: 's8',
|
||||
},
|
||||
},
|
||||
},
|
||||
right: {
|
||||
position: {
|
||||
name: 'absolute',
|
||||
args: { x: 50, y: 50 },
|
||||
},
|
||||
markup: {
|
||||
tagName: 'rect',
|
||||
selector: 'shape9',
|
||||
attrs: {
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 30,
|
||||
height: 30,
|
||||
fill: '#fff',
|
||||
stroke: 'blue',
|
||||
id: 's9',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: {
|
||||
name: 'line',
|
||||
args: {
|
||||
start: { x: 10, y: 10 },
|
||||
end: { x: 210, y: 10 },
|
||||
},
|
||||
},
|
||||
attrs: {
|
||||
circle: {
|
||||
id: 's10',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
items: [
|
||||
{
|
||||
id: '1',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
group: 'right',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
getMatrixOfElement = (elem: Element, target: Element) => {
|
||||
let matrix = Dom.createSVGMatrix()
|
||||
let node = elem
|
||||
const matrixList = []
|
||||
while (node && node !== target) {
|
||||
const transform = node.getAttribute('transform') || null
|
||||
const nodeMatrix = Dom.transformStringToMatrix(transform)
|
||||
matrixList.push(nodeMatrix)
|
||||
node = node.parentElement as Element
|
||||
}
|
||||
matrixList.reverse().forEach((m) => {
|
||||
matrix = matrix.multiply(m)
|
||||
})
|
||||
return matrix
|
||||
}
|
||||
|
||||
getBoundingRectOfElement = (elem: Element) => {
|
||||
let node = elem
|
||||
let tagName = elem.tagName.toLowerCase()
|
||||
|
||||
if (tagName === 'g') {
|
||||
node = elem.firstElementChild as Element
|
||||
tagName = node.tagName.toLowerCase()
|
||||
}
|
||||
|
||||
const attr = (name: string) => {
|
||||
const s = node.getAttribute(name)
|
||||
const v = s ? parseFloat(s) : 0
|
||||
return Number.isNaN(v) ? 0 : v
|
||||
}
|
||||
|
||||
let x, y, r, width, height, bbox
|
||||
switch (tagName) {
|
||||
case 'rect':
|
||||
x = attr('x')
|
||||
y = attr('y')
|
||||
width = attr('width')
|
||||
height = attr('height')
|
||||
bbox = new Rectangle(x, y, width, height)
|
||||
break
|
||||
case 'circle':
|
||||
x = attr('cx')
|
||||
y = attr('cy')
|
||||
r = attr('r')
|
||||
bbox = new Rectangle(x - r, y - r, 2 * r, 2 * r)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return bbox
|
||||
}
|
||||
|
||||
test = () => {
|
||||
const view = this.graph.findViewByCell(this.source)
|
||||
const container = view?.container
|
||||
const q = [
|
||||
container?.querySelector('#s1')!,
|
||||
container?.querySelector('#s2')!,
|
||||
container?.querySelector('#s3')!,
|
||||
container?.querySelector('#s4')!,
|
||||
container?.querySelector('#s5')!,
|
||||
container?.querySelector('#s6')!,
|
||||
container?.querySelector('#s7')!,
|
||||
container?.querySelector('#s8')!,
|
||||
container?.querySelector('#s9')!,
|
||||
container?.querySelector('#s10')!,
|
||||
]
|
||||
const fix = (num: number) => num.toFixed(1)
|
||||
const isSameMatrix = (matrix1: DOMMatrix, matrix2: DOMMatrix) => {
|
||||
return (
|
||||
fix(matrix1.a) === fix(matrix2.a) &&
|
||||
fix(matrix1.b) === fix(matrix2.b) &&
|
||||
fix(matrix1.c) === fix(matrix2.c) &&
|
||||
fix(matrix1.d) === fix(matrix2.d) &&
|
||||
fix(matrix1.e) === fix(matrix2.e) &&
|
||||
fix(matrix1.f) === fix(matrix2.f)
|
||||
)
|
||||
}
|
||||
const isSameBounding = (rect1: Rectangle, rect2: Rectangle) => {
|
||||
return (
|
||||
fix(rect1.x) === fix(rect2.x) &&
|
||||
fix(rect1.y) === fix(rect2.y) &&
|
||||
fix(rect1.width) === fix(rect2.width) &&
|
||||
fix(rect1.height) === fix(rect2.height)
|
||||
)
|
||||
}
|
||||
|
||||
// matrix
|
||||
let s = performance.now()
|
||||
const oldMatrixList = q.map((item) => view?.getMatrixOfElement(item))
|
||||
console.log('old getMatrixOfElement spend:', performance.now() - s)
|
||||
s = performance.now()
|
||||
const newMatrixList = q.map((item) =>
|
||||
this.getMatrixOfElement(item, container!),
|
||||
)
|
||||
console.log('new getMatrixOfElement spend:', performance.now() - s)
|
||||
|
||||
let isSame = oldMatrixList.every((item, index) => {
|
||||
const martix = newMatrixList[index]
|
||||
if (item && martix) {
|
||||
return isSameMatrix(item, martix)
|
||||
}
|
||||
return true
|
||||
})
|
||||
console.log(`getMatrixOfElement test ${isSame ? 'success' : 'failed'}`)
|
||||
|
||||
// bounding
|
||||
s = performance.now()
|
||||
const oldBoundingList = q.map((item) =>
|
||||
view?.getBoundingRectOfElement(item),
|
||||
)
|
||||
console.log('old getBoundingRectOfElement spend:', performance.now() - s)
|
||||
s = performance.now()
|
||||
const newBoundingList = q.map((item) => this.getBoundingRectOfElement(item))
|
||||
console.log('new getBoundingRectOfElement spend:', performance.now() - s)
|
||||
|
||||
isSame = oldBoundingList.every((item, index) => {
|
||||
const bounding = newBoundingList[index]
|
||||
if (item && bounding) {
|
||||
return isSameBounding(item, bounding)
|
||||
}
|
||||
return true
|
||||
})
|
||||
console.log(
|
||||
`getBoundingRectOfElement test ${isSame ? 'success' : 'failed'}`,
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
<Button onClick={this.test}>Test</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user