@knotx/render
v0.5.8
Published
Render for Knotx
Downloads
180
Readme
@knotx/render
一个专为 Knotx 图形编辑器提供边缘(Edge)渲染功能的 React 组件库。
📦 安装
npm install @knotx/renderyarn add @knotx/renderpnpm add @knotx/render🚀 基本概述
@knotx/render 是 Knotx 生态系统中的渲染层组件库,专门用于渲染图形编辑器中的边缘(连接线)。它提供了多种边缘类型(直线、贝塞尔曲线)和丰富的自定义选项,支持箭头标记、标签、样式定制等功能。
主要特性
- 🎨 多种边缘类型: 支持直线、贝塞尔曲线等多种连接线类型
- 🎯 箭头标记: 内置多种箭头标记样式,支持自定义标记
- 🏷️ 标签支持: 支持在边缘上添加文本标签
- 🎛️ 高度可定制: 支持样式、颜色、宽度等各种属性自定义
- 🔧 扩展性强: 基于抽象路径构建器设计,可轻松扩展新的边缘类型
- ⚡ 性能优化: 采用 SVG 渲染,支持交互区域优化
📋 API 文档
组件
BaseEdge<TPathBuilderContext>
基础边缘组件,所有其他边缘组件的基础。
Props
interface BaseEdgeProps<TPathBuilderContext = void> extends EdgeProps {
className?: string // 自定义 CSS 类名
style?: Record<string, any> // 自定义样式对象
interactionWidth?: number // 交互区域宽度,默认 20
label?: string // 边缘标签文本
markerEnd?: string | MarkerProps // 终点标记
markerStart?: string | MarkerProps // 起点标记
pathBuilder: PathBuilderType<any, TPathBuilderContext> // 路径构建器
context: TPathBuilderContext // 路径构建器上下文
}使用示例
import { BaseEdge, StraightPathBuilder } from '@knotx/render'
function CustomEdge() {
return (
<BaseEdge
sourceX={0}
sourceY={0}
targetX={100}
targetY={100}
pathBuilder={StraightPathBuilder}
context={undefined}
label="连接线"
style={{ stroke: '#1890ff', strokeWidth: 2 }}
/>
)
}BezierEdge
贝塞尔曲线边缘组件,适用于需要平滑曲线连接的场景。
Props
interface BezierEdgeProps extends Omit<BaseEdgeProps, 'pathBuilder' | 'context'> {}使用示例
import { BezierEdge, getArrowMarker } from '@knotx/render'
function CurvedConnection() {
const arrowMarker = getArrowMarker('#ff4d4f')
return (
<BezierEdge
sourceX={50}
sourceY={50}
targetX={250}
targetY={150}
markerEnd={arrowMarker}
style={{ stroke: '#ff4d4f', strokeWidth: 2 }}
label="贝塞尔曲线"
/>
)
}StraightEdge
直线边缘组件,适用于简单的直线连接。
Props
interface StraightEdgeProps extends Omit<BaseEdgeProps, 'pathBuilder' | 'context'> {}使用示例
import { getArrowClosedMarker, StraightEdge } from '@knotx/render'
function DirectConnection() {
const arrowMarker = getArrowClosedMarker('#52c41a')
return (
<StraightEdge
sourceX={0}
sourceY={0}
targetX={200}
targetY={100}
markerEnd={arrowMarker}
markerStart={arrowMarker}
style={{ stroke: '#52c41a', strokeWidth: 3 }}
interactionWidth={30}
/>
)
}MarkerDefinitions
标记定义组件,用于集中管理和重用标记。
Props
interface MarkerDefinitionsProps {
markers: MarkerProps[]
}使用示例
import { getArrowClosedMarker, getArrowMarker, MarkerDefinitions } from '@knotx/render'
function EdgeContainer() {
const markers = [
getArrowMarker('#1890ff'),
getArrowClosedMarker('#ff4d4f'),
getArrowMarker('#52c41a')
]
return (
<svg>
<MarkerDefinitions markers={markers} />
{/* 你的边缘组件 */}
</svg>
)
}路径构建器
PathBuilder<TType, TContext>
抽象路径构建器基类,用于创建自定义边缘类型。
抽象方法
abstract class PathBuilder<TType extends string, TContext = never> {
constructor(
readonly sourceX: number,
readonly sourceY: number,
readonly targetX: number,
readonly targetY: number
) {}
abstract type: TType
abstract buildPath(context: TContext): string
abstract interpolate(t: number, context: TContext): { x: number, y: number }
}创建自定义路径构建器示例
class CustomPathBuilder extends PathBuilder<'custom'> {
type = 'custom' as const
buildPath(): string {
// 创建自定义的 SVG 路径
const midX = (this.sourceX + this.targetX) / 2
const midY = (this.sourceY + this.targetY) / 2
return `M ${this.sourceX} ${this.sourceY}
Q ${midX} ${midY - 50} ${this.targetX} ${this.targetY}`
}
interpolate(t: number): { x: number, y: number } {
// 实现路径上点的插值计算
const x = this.sourceX + t * (this.targetX - this.sourceX)
const y = this.sourceY + t * (this.targetY - this.sourceY)
return { x, y }
}
}StraightPathBuilder
直线路径构建器,生成直线路径。
class StraightPathBuilder extends PathBuilder<'straight'> {
type = 'straight' as const
buildPath(): string
interpolate(t: number): { x: number, y: number }
}BezierPathBuilder
贝塞尔曲线路径构建器,生成平滑的曲线路径。
class BezierPathBuilder extends PathBuilder<'bezier'> {
type = 'bezier' as const
buildPath(): string
interpolate(t: number): { x: number, y: number }
}标记工具函数
getArrowMarker(color?: string)
创建标准箭头标记。
参数
color(可选): 标记颜色,默认为currentColor
返回值
MarkerProps: 箭头标记配置对象
使用示例
import { getArrowMarker, StraightEdge } from '@knotx/render'
function EdgeWithArrow() {
const marker = getArrowMarker('#1890ff')
return (
<StraightEdge
sourceX={0}
sourceY={0}
targetX={100}
targetY={100}
markerEnd={marker}
/>
)
}getArrowClosedMarker(color?: string)
创建实心箭头标记。
参数
color(可选): 标记颜色,默认为currentColor
返回值
MarkerProps: 实心箭头标记配置对象
使用示例
import { BezierEdge, getArrowClosedMarker } from '@knotx/render'
function EdgeWithClosedArrow() {
const marker = getArrowClosedMarker('#ff4d4f')
return (
<BezierEdge
sourceX={50}
sourceY={50}
targetX={200}
targetY={150}
markerEnd={marker}
style={{ stroke: '#ff4d4f' }}
/>
)
}getCustomMarker(type: string, options?: Partial<MarkerProps>)
创建自定义标记。
参数
type: 标记类型标识符options(可选): 自定义标记选项
返回值
MarkerProps: 自定义标记配置对象
使用示例
import { BaseEdge, getCustomMarker, StraightPathBuilder } from '@knotx/render'
function EdgeWithCustomMarker() {
const marker = getCustomMarker('diamond', {
color: '#722ed1',
width: 12,
height: 12,
strokeWidth: 2
})
return (
<BaseEdge
sourceX={0}
sourceY={0}
targetX={150}
targetY={100}
pathBuilder={StraightPathBuilder}
context={undefined}
markerEnd={marker}
/>
)
}getArrowHeadMarkers(color?: string)
创建两个实心箭头作为起点和终点的标记。
参数
color(可选): 标记颜色
返回值
- 包含
markerStart和markerEnd的对象
使用示例
import { getArrowHeadMarkers, StraightEdge } from '@knotx/render'
function DoubleArrowEdge() {
const { markerStart, markerEnd } = getArrowHeadMarkers('#13c2c2')
return (
<StraightEdge
sourceX={0}
sourceY={0}
targetX={200}
targetY={100}
markerStart={markerStart}
markerEnd={markerEnd}
style={{ stroke: '#13c2c2', strokeWidth: 2 }}
/>
)
}类型定义
MarkerType
enum MarkerType {
Arrow = 'arrow',
ArrowClosed = 'arrowclosed'
}MarkerProps
interface MarkerProps {
id: string // 标记唯一标识符
type: MarkerType | string // 标记类型
color?: string // 标记颜色
width?: number // 标记宽度
height?: number // 标记高度
markerUnits?: string // 标记单位
orient?: string // 标记方向
strokeWidth?: number // 描边宽度
}PathBuilderType
type PathBuilderType<T extends string = any, TContext = void> =
new (...args: ConstructorParameters<typeof PathBuilder<T, TContext>>) =>
PathBuilder<T, TContext>🗂️ 文件目录结构
packages/render/
├── src/
│ ├── edges/
│ │ ├── base-edge.tsx # 基础边缘组件
│ │ ├── bezier.tsx # 贝塞尔曲线边缘
│ │ ├── straight.tsx # 直线边缘
│ │ ├── markers.tsx # 标记相关功能
│ │ ├── path-builder.ts # 路径构建器
│ │ └── index.ts # 边缘模块导出
│ └── index.ts # 主入口文件
├── dist/ # 构建输出目录
├── package.json # 包配置文件
├── tsconfig.json # TypeScript 配置
├── build.config.ts # 构建配置
└── README.md # 文档文件🎯 完整使用示例
基础使用
import {
BezierEdge,
getArrowClosedMarker,
getArrowMarker,
StraightEdge
} from '@knotx/render'
import React from 'react'
function GraphEditor() {
return (
<div style={{ position: 'relative', width: 800, height: 600 }}>
{/* 直线连接 */}
<StraightEdge
sourceX={50}
sourceY={50}
targetX={200}
targetY={100}
markerEnd={getArrowMarker('#1890ff')}
style={{ stroke: '#1890ff', strokeWidth: 2 }}
label="直线连接"
/>
{/* 贝塞尔曲线连接 */}
<BezierEdge
sourceX={50}
sourceY={150}
targetX={250}
targetY={200}
markerEnd={getArrowClosedMarker('#ff4d4f')}
style={{ stroke: '#ff4d4f', strokeWidth: 2 }}
label="曲线连接"
/>
</div>
)
}自定义边缘类型
import { BaseEdge, PathBuilder } from '@knotx/render'
// 创建自定义路径构建器
class StepPathBuilder extends PathBuilder<'step'> {
type = 'step' as const
buildPath(): string {
const midX = (this.sourceX + this.targetX) / 2
return `M ${this.sourceX} ${this.sourceY}
L ${midX} ${this.sourceY}
L ${midX} ${this.targetY}
L ${this.targetX} ${this.targetY}`
}
interpolate(t: number): { x: number, y: number } {
const midX = (this.sourceX + this.targetX) / 2
if (t <= 0.33) {
const localT = t / 0.33
return {
x: this.sourceX + localT * (midX - this.sourceX),
y: this.sourceY
}
}
else if (t <= 0.66) {
const localT = (t - 0.33) / 0.33
return {
x: midX,
y: this.sourceY + localT * (this.targetY - this.sourceY)
}
}
else {
const localT = (t - 0.66) / 0.34
return {
x: midX + localT * (this.targetX - midX),
y: this.targetY
}
}
}
}
// 使用自定义路径构建器
function StepEdge(props: Omit<BaseEdgeProps, 'pathBuilder' | 'context'>) {
return (
<BaseEdge
{...props}
pathBuilder={StepPathBuilder}
context={undefined}
/>
)
}高级标记管理
import { getArrowMarker, getCustomMarker, MarkerDefinitions } from '@knotx/render'
function AdvancedGraph() {
// 预定义标记
const markers = [
getArrowMarker('#1890ff'),
getArrowMarker('#ff4d4f'),
getCustomMarker('circle', {
color: '#52c41a',
width: 8,
height: 8
})
]
return (
<svg width="800" height="600">
<MarkerDefinitions markers={markers} />
{/* 使用预定义标记 */}
<StraightEdge
sourceX={100}
sourceY={100}
targetX={300}
targetY={200}
markerEnd={markers[0]}
style={{ stroke: '#1890ff' }}
/>
<BezierEdge
sourceX={100}
sourceY={200}
targetX={400}
targetY={150}
markerEnd={markers[1]}
style={{ stroke: '#ff4d4f' }}
/>
</svg>
)
}📄 许可证
MIT
🤝 贡献
欢迎提交问题和拉取请求。详见 CONTRIBUTING.md
📞 支持
如果您遇到任何问题或需要帮助,请在 GitHub Issues 中提交问题。
