/**
|
* 自定义绘图图形模板:矩形、三角形、平行四边形
|
* 供 klinecharts addShapeTemplate 使用
|
*/
|
|
// 矩形:两点为对角线端点,totalStep=3 表示点击2次完成
|
export const rectShape = {
|
name: 'rect',
|
totalStep: 3,
|
checkEventCoordinateOnShape: ({ dataSource, eventCoordinate }) => {
|
if (!dataSource || dataSource.length < 1 || !dataSource[0].length) return false
|
const points = dataSource[0]
|
if (points.length < 4) return false
|
const xs = points.map(p => p.x)
|
const ys = points.map(p => p.y)
|
const minX = Math.min(...xs)
|
const maxX = Math.max(...xs)
|
const minY = Math.min(...ys)
|
const maxY = Math.max(...ys)
|
return eventCoordinate.x >= minX - 4 && eventCoordinate.x <= maxX + 4 &&
|
eventCoordinate.y >= minY - 4 && eventCoordinate.y <= maxY + 4
|
},
|
createShapeDataSource: ({ coordinates }) => {
|
if (coordinates.length < 2) return []
|
const [c1, c2] = coordinates
|
const minX = Math.min(c1.x, c2.x)
|
const maxX = Math.max(c1.x, c2.x)
|
const minY = Math.min(c1.y, c2.y)
|
const maxY = Math.max(c1.y, c2.y)
|
const polygon = [
|
{ x: minX, y: minY },
|
{ x: maxX, y: minY },
|
{ x: maxX, y: maxY },
|
{ x: minX, y: maxY }
|
]
|
return [{
|
type: 'polygon',
|
isDraw: true,
|
isCheck: true,
|
dataSource: [polygon]
|
}]
|
}
|
}
|
|
// 三角形:三个顶点,totalStep=4 表示点击3次完成
|
export const triangleShape = {
|
name: 'triangle',
|
totalStep: 4,
|
checkEventCoordinateOnShape: ({ dataSource, eventCoordinate }) => {
|
if (!dataSource || dataSource.length < 1 || !dataSource[0].length) return false
|
const points = dataSource[0]
|
if (points.length < 3) return false
|
const getTriangleSquare = (p1, p2, p3) => {
|
const x1 = Math.abs(p2.x - p1.x)
|
const y1 = Math.abs(p2.y - p1.y)
|
const x2 = Math.abs(p3.x - p1.x)
|
const y2 = Math.abs(p3.y - p1.y)
|
return Math.abs(x1 * y2 - x2 * y1) / 2
|
}
|
const square = getTriangleSquare(points[0], points[1], points[2])
|
const compareSquare = getTriangleSquare(points[0], points[1], eventCoordinate) +
|
getTriangleSquare(points[0], points[2], eventCoordinate) +
|
getTriangleSquare(points[1], points[2], eventCoordinate)
|
return Math.abs(square - compareSquare) < 4
|
},
|
createShapeDataSource: ({ coordinates }) => {
|
if (coordinates.length < 3) return []
|
const polygon = coordinates.slice(0, 3)
|
return [{
|
type: 'polygon',
|
isDraw: true,
|
isCheck: true,
|
dataSource: [polygon]
|
}]
|
}
|
}
|
|
function getTriangleSquare(p1, p2, p3) {
|
const x1 = Math.abs(p2.x - p1.x)
|
const y1 = Math.abs(p2.y - p1.y)
|
const x2 = Math.abs(p3.x - p1.x)
|
const y2 = Math.abs(p3.y - p1.y)
|
return Math.abs(x1 * y2 - x2 * y1) / 2
|
}
|
|
function pointInTriangle(p1, p2, p3, pt) {
|
const square = getTriangleSquare(p1, p2, p3)
|
const sum = getTriangleSquare(p1, p2, pt) + getTriangleSquare(p1, p3, pt) + getTriangleSquare(p2, p3, pt)
|
return Math.abs(square - sum) < 4
|
}
|
|
// 平行四边形:前三点确定,第四点 = p2 + (p3 - p1)
|
export const parallelogramShape = {
|
name: 'parallelogram',
|
totalStep: 4,
|
checkEventCoordinateOnShape: ({ dataSource, eventCoordinate }) => {
|
if (!dataSource || dataSource.length < 1 || !dataSource[0].length) return false
|
const points = dataSource[0]
|
if (points.length < 4) return false
|
return pointInTriangle(points[0], points[1], points[2], eventCoordinate) ||
|
pointInTriangle(points[0], points[2], points[3], eventCoordinate)
|
},
|
createShapeDataSource: ({ coordinates }) => {
|
if (coordinates.length < 3) return []
|
const [p1, p2, p3] = coordinates
|
const p4 = {
|
x: p2.x + (p3.x - p1.x),
|
y: p2.y + (p3.y - p1.y)
|
}
|
const polygon = [p1, p2, p4, p3]
|
return [{
|
type: 'polygon',
|
isDraw: true,
|
isCheck: true,
|
dataSource: [polygon]
|
}]
|
}
|
}
|
|
export const customShapeTemplates = [rectShape, triangleShape, parallelogramShape]
|