Skip to content

Commit

Permalink
Merge pull request #69 from sayari-analytics/feature/0.7.0.rc.1
Browse files Browse the repository at this point in the history
enable custom placement for node label
  • Loading branch information
mggower authored Sep 14, 2023
2 parents 0bf0452 + 5508052 commit 3405ea8
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 11 deletions.
56 changes: 46 additions & 10 deletions src/renderers/webgl/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import {
clientPositionFromEvent,
pointerKeysFromEvent
} from './utils'
import { Node, Edge, NodeStyle, equals } from '../../trellis'
import { Node, Edge, NodeStyle, equals, Placement } from '../../trellis'
import { interpolate } from '../../utils'
import { CircleSprite } from './sprites/circleSprite'

const LABEL_Y_PADDING = 2
const LABEL_PADDING = 4
const VERTICAL_ANCHOR = { x: 0.5, y: 0 }
const HORIZONTAL_ANCHOR = { x: 0, y: 0.5 }
const DEFAULT_NODE_FILL = colorToNumber('#666')
const DEFAULT_NODE_STROKE = colorToNumber('#aaa')
const DEFAULT_NODE_STROKE_WIDTH = 2
Expand Down Expand Up @@ -51,6 +53,7 @@ export class NodeRenderer<N extends Node, E extends Edge> {
private labelWordWrap?: number
private labelBackground?: string
private labelBackgroundOpacity?: number
private labelPlacement: Placement = 'bottom'
private stroke?: NodeStyle['stroke']
private icon?: NodeStyle['icon']
private badge?: NodeStyle['badge']
Expand Down Expand Up @@ -175,6 +178,7 @@ export class NodeRenderer<N extends Node, E extends Edge> {
const labelWordWrap = node.style?.label?.wordWrap
const labelBackground = node.style?.label?.background
const labelBackgroundOpacity = node.style?.label?.backgroundOpacity
const labelPlacement = node.style?.label?.placement ?? 'bottom'

if (
node.label !== this.label ||
Expand All @@ -183,7 +187,8 @@ export class NodeRenderer<N extends Node, E extends Edge> {
labelSize !== this.labelSize ||
labelWordWrap !== this.labelWordWrap ||
labelBackground !== this.labelBackground ||
labelBackgroundOpacity !== this.labelBackgroundOpacity
labelBackgroundOpacity !== this.labelBackgroundOpacity ||
labelPlacement !== this.labelPlacement
) {
this.label = node.label
this.labelFamily = labelFamily
Expand All @@ -192,6 +197,7 @@ export class NodeRenderer<N extends Node, E extends Edge> {
this.labelWordWrap = labelWordWrap
this.labelBackground = labelBackground
this.labelBackgroundOpacity = labelBackgroundOpacity
this.labelPlacement = labelPlacement
this.labelContainer.removeChildren()
this.labelSprite?.destroy()
this.labelSprite = undefined
Expand All @@ -207,18 +213,28 @@ export class NodeRenderer<N extends Node, E extends Edge> {
this.dirty = true
this.renderer.dirty = true

const anchor =
this.labelPlacement === 'left' || this.labelPlacement === 'right'
? HORIZONTAL_ANCHOR
: VERTICAL_ANCHOR

this.labelSprite = new PIXI.Text(this.label, {
fontFamily: this.labelFamily,
fontSize: (this.labelSize ?? DEFAULT_LABEL_SIZE) * 2.5,
fill: this.labelColor,
lineJoin: 'round',
stroke: this.labelBackground === undefined ? '#fff' : undefined,
strokeThickness: this.labelBackground === undefined ? 2.5 * 2.5 : 0,
align: 'center',
align:
this.labelPlacement === 'left'
? 'right'
: this.labelPlacement === 'right'
? 'left'
: 'center',
wordWrap: labelWordWrap !== undefined,
wordWrapWidth: labelWordWrap
})
this.labelSprite.anchor.set(0.5, 0)
this.labelSprite.anchor.set(anchor.x, anchor.y)
this.labelSprite.scale.set(0.4)
this.labelContainer.addChild(this.labelSprite)

Expand All @@ -228,7 +244,7 @@ export class NodeRenderer<N extends Node, E extends Edge> {
this.labelBackgroundSprite.height = this.labelSprite.height
this.labelBackgroundSprite.tint = colorToNumber(this.labelBackground)
this.labelBackgroundSprite.alpha = this.labelBackgroundOpacity ?? 1
this.labelBackgroundSprite.anchor.set(0.5, 0)
this.labelBackgroundSprite.anchor.set(anchor.x, anchor.y)
this.labelContainer.addChild(this.labelBackgroundSprite)
}

Expand Down Expand Up @@ -511,11 +527,31 @@ export class NodeRenderer<N extends Node, E extends Edge> {
this.nodeContainer.hitArea = new PIXI.Circle(0, 0, this.radius + this.strokeWidth)

if (this.labelSprite) {
this.labelSprite.y = this.radius + this.strokeWidth + LABEL_Y_PADDING
}
const labelPadding = this.radius + this.strokeWidth + LABEL_PADDING

if (this.labelBackgroundSprite) {
this.labelBackgroundSprite.y = this.radius + this.strokeWidth + LABEL_Y_PADDING
if (this.labelPlacement === 'left') {
const x = -labelPadding - (this.labelBackgroundSprite?.width ?? this.labelSprite.width)
this.labelSprite.x = x
if (this.labelBackgroundSprite) {
this.labelBackgroundSprite.x = x
}
} else if (this.labelPlacement === 'right') {
this.labelSprite.x = labelPadding
if (this.labelBackgroundSprite) {
this.labelBackgroundSprite.x = labelPadding
}
} else if (this.labelPlacement === 'top') {
const y = -labelPadding - (this.labelBackgroundSprite?.height ?? this.labelSprite.height)
this.labelSprite.y = y
if (this.labelBackgroundSprite) {
this.labelBackgroundSprite.y = y
}
} else {
this.labelSprite.y = labelPadding
if (this.labelBackgroundSprite) {
this.labelBackgroundSprite.y = labelPadding
}
}
}

for (const subgraphNodeId in this.subgraphNodes) {
Expand Down
5 changes: 4 additions & 1 deletion src/trellis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,16 @@ export type ImageIcon = {
offsetY?: number
}

type LabelStyle = Partial<{
export type Placement = 'top' | 'bottom' | 'left' | 'right'

export type LabelStyle = Partial<{
color: string
fontFamily: string
fontSize: number
wordWrap: number
background: string
backgroundOpacity: number
placement: Placement
}>

export type NodeStyle = {
Expand Down

0 comments on commit 3405ea8

Please sign in to comment.