summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas F. K. Jorna <[email protected]>2021-10-15 20:46:04 +0200
committerThomas F. K. Jorna <[email protected]>2021-10-15 20:46:15 +0200
commit35dd8336b5a56ee95e54700df322d53df2f56e85 (patch)
tree1c38cc6a4d734b1c49bc0332a7e4bce2a3698e5f
parentad692d23912a82778a15974e11f578422037b0c1 (diff)
feat(labels): separate labeldrawing
-rw-r--r--components/Graph/drawLabels.ts104
-rw-r--r--pages/index.tsx84
2 files changed, 118 insertions, 70 deletions
diff --git a/components/Graph/drawLabels.ts b/components/Graph/drawLabels.ts
new file mode 100644
index 0000000..d2d84f8
--- /dev/null
+++ b/components/Graph/drawLabels.ts
@@ -0,0 +1,104 @@
+import { OrgRoamNode } from '../../api'
+import { NodeObject } from 'force-graph'
+import { initialVisuals } from '../config'
+import { hexToRGBA } from '../../pages'
+import wrap from 'word-wrap'
+
+export interface drawLabelsProps {
+ labelBackgroundColor: string
+ labelTextColor: string
+ node: NodeObject
+ ctx: any
+ globalScale: number
+ highlightedNodes: { [id: string]: {} }
+ previouslyHighlightedNodes: { [id: string]: {} }
+ visuals: typeof initialVisuals
+ opacity: number
+ nodeSize: (node: NodeObject) => number
+}
+export function drawLabels(props: drawLabelsProps) {
+ const {
+ labelBackgroundColor,
+ labelTextColor,
+ node,
+ ctx,
+ globalScale,
+ highlightedNodes,
+ previouslyHighlightedNodes,
+ visuals,
+ opacity,
+ nodeSize,
+ } = props
+
+ if (!node) {
+ return
+ }
+ //if (dragging) {
+ // return
+ //}
+
+ if (!visuals.labels) {
+ return
+ }
+ const wasHighlightedNode = previouslyHighlightedNodes[node.id!]
+
+ if (
+ (globalScale <= visuals.labelScale || visuals.labels === 1) &&
+ !highlightedNodes[node.id!] &&
+ !wasHighlightedNode
+ ) {
+ return
+ }
+
+ const nodeTitle = (node as OrgRoamNode).title!
+ const label = nodeTitle.substring(0, visuals.labelLength)
+ const fontSize = visuals.labelFontSize / (0.75 * Math.min(Math.max(0.5, globalScale), 3))
+ const textWidth = ctx.measureText(label).width
+ const bckgDimensions = [textWidth * 1.1, fontSize].map((n) => n + fontSize * 0.5) as [
+ number,
+ number,
+ ] // some padding
+
+ const fadeFactor = Math.min((3 * (globalScale - visuals.labelScale)) / visuals.labelScale, 1)
+
+ // draw label background
+ const getLabelOpacity = () => {
+ if (visuals.labels === 1) {
+ return opacity
+ }
+ if (globalScale <= visuals.labelScale) {
+ return opacity
+ }
+ return highlightedNodes[node.id!] || previouslyHighlightedNodes[node.id!]
+ ? Math.max(fadeFactor, opacity)
+ : 1 * fadeFactor * (-1 * (visuals.highlightFade * opacity - 1))
+ }
+ const nodeS = 8 * Math.cbrt(nodeSize(node) * visuals.nodeRel)
+ if (visuals.labelBackgroundColor && visuals.labelBackgroundOpacity) {
+ const backgroundOpacity = getLabelOpacity() * visuals.labelBackgroundOpacity
+ const labelBackground = hexToRGBA(labelBackgroundColor, backgroundOpacity)
+ ctx.fillStyle = labelBackground
+ ctx.fillRect(
+ node.x! - bckgDimensions[0] / 2,
+ node.y! - bckgDimensions[1] / 2 + nodeS,
+ ...bckgDimensions,
+ )
+ }
+
+ // draw label text
+ const textOpacity = getLabelOpacity()
+ ctx.textAlign = 'center'
+ ctx.textBaseline = 'middle'
+ const labelText = hexToRGBA(labelTextColor, textOpacity)
+ ctx.fillStyle = labelText
+ ctx.font = `${fontSize}px Sans-Serif`
+ const wordsArray = wrap(label, { width: visuals.labelWordWrap }).split('\n')
+
+ const truncatedWords =
+ nodeTitle.length > visuals.labelLength
+ ? [...wordsArray.slice(0, -1), `${wordsArray.slice(-1)}...`]
+ : wordsArray
+ truncatedWords.forEach((word, index) => {
+ ctx.fillText(word, node.x!, node.y! + nodeS + visuals.labelLineSpace * fontSize * index)
+ })
+}
diff --git a/pages/index.tsx b/pages/index.tsx
index 2b8b6c7..ab4a96d 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -52,6 +52,7 @@ import { Tweaks } from '../components/Tweaks'
import { usePersistantState } from '../util/persistant-state'
import { ThemeContext, ThemeContextProps } from '../util/themecontext'
import { openNodeInEmacs } from '../util/webSocketFunctions'
+import { drawLabels } from '../components/Graph/drawLabels'
const d3promise = import('d3-force-3d')
@@ -1217,76 +1218,19 @@ export const Graph = function (props: GraphProps) {
return nodeSize(node) / Math.pow(scaleRef.current, visuals.nodeZoomSize)
},
nodeCanvasObject: (node, ctx, globalScale) => {
- if (!node) {
- return
- }
- if (dragging) {
- return
- }
-
- if (!visuals.labels) {
- return
- }
- const wasHighlightedNode = previouslyHighlightedNodes[node.id!]
-
- if (
- (globalScale <= visuals.labelScale || visuals.labels === 1) &&
- !highlightedNodes[node.id!] &&
- !wasHighlightedNode
- ) {
- return
- }
-
- const nodeTitle = (node as OrgRoamNode).title!
- const label = nodeTitle.substring(0, visuals.labelLength)
- const fontSize = visuals.labelFontSize / (0.75 * Math.min(Math.max(0.5, globalScale), 3))
- const textWidth = ctx.measureText(label).width
- const bckgDimensions = [textWidth * 1.1, fontSize].map((n) => n + fontSize * 0.5) as [
- number,
- number,
- ] // some padding
-
- const fadeFactor = Math.min((3 * (globalScale - visuals.labelScale)) / visuals.labelScale, 1)
-
- // draw label background
- const getLabelOpacity = () => {
- if (visuals.labels === 1) {
- return opacity
- }
- if (globalScale <= visuals.labelScale) {
- return opacity
- }
- return highlightedNodes[node.id!] || previouslyHighlightedNodes[node.id!]
- ? Math.max(fadeFactor, opacity)
- : 1 * fadeFactor * (-1 * (visuals.highlightFade * opacity - 1))
- }
- const nodeS = 8 * Math.cbrt(nodeSize(node) * visuals.nodeRel)
- if (visuals.labelBackgroundColor && visuals.labelBackgroundOpacity) {
- const backgroundOpacity = getLabelOpacity() * visuals.labelBackgroundOpacity
- const labelBackground = hexToRGBA(labelBackgroundColor, backgroundOpacity)
- ctx.fillStyle = labelBackground
- ctx.fillRect(
- node.x! - bckgDimensions[0] / 2,
- node.y! - bckgDimensions[1] / 2 + nodeS,
- ...bckgDimensions,
- )
- }
-
- // draw label text
- const textOpacity = getLabelOpacity()
- ctx.textAlign = 'center'
- ctx.textBaseline = 'middle'
- const labelText = hexToRGBA(labelTextColor, textOpacity)
- ctx.fillStyle = labelText
- ctx.font = `${fontSize}px Sans-Serif`
- const wordsArray = wrap(label, { width: visuals.labelWordWrap }).split('\n')
-
- const truncatedWords =
- nodeTitle.length > visuals.labelLength
- ? [...wordsArray.slice(0, -1), `${wordsArray.slice(-1)}...`]
- : wordsArray
- truncatedWords.forEach((word, index) => {
- ctx.fillText(word, node.x!, node.y! + nodeS + visuals.labelLineSpace * fontSize * index)
+ drawLabels({
+ ...{
+ node,
+ ctx,
+ globalScale,
+ highlightedNodes,
+ previouslyHighlightedNodes,
+ visuals,
+ opacity,
+ nodeSize,
+ labelTextColor,
+ labelBackgroundColor,
+ },
})
},
nodeCanvasObjectMode: () => 'after',