Skip to content

Commit

Permalink
update examples with zoom controls
Browse files Browse the repository at this point in the history
  • Loading branch information
jameslaneconkling committed Oct 14, 2020
1 parent 2f7568e commit d08c03c
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 89 deletions.
2 changes: 1 addition & 1 deletion examples/hierarchy/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<canvas id="graph"></canvas>
<div id="graph"></div>
<script src="./index.ts"></script>
</body>
</html>
76 changes: 41 additions & 35 deletions examples/hierarchy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Stats from 'stats.js'
import * as Hierarchy from '../../src/layout/hierarchy'
import * as Force from '../../src/layout/force'
import * as Graph from '../../src/'
import * as Zoom from '../../src/controls/zoom'
import { NodeStyle, Renderer, RendererOptions } from '../../src/renderers/pixi'
import graphData from '../../tmp-data'

Expand All @@ -24,15 +25,15 @@ const russianLabel = 'ВИКТОР ФЕЛИКСОВИЧ ВЕКСЕЛЬБЕРГ'
const createCompanyStyle = (radius: number): Partial<NodeStyle> => ({
color: '#FFAF1D',
stroke: [{ color: '#FFF' }, { color: '#F7CA4D' }],
icon: { type: 'textIcon' as const, family: 'Material Icons', text: 'business', color: '#fff', size: radius * 1.25 },
icon: { type: 'textIcon' as const, family: 'Material Icons', text: 'business', color: '#fff', size: radius * 1.2 },
badge: [{
position: 45,
color: '#FFAF1D',
stroke: '#FFF',
icon: {
type: 'textIcon',
family: 'Helvetica',
size: 18,
size: 10,
color: '#FFF',
text: '15',
}
Expand All @@ -43,7 +44,7 @@ const createCompanyStyle = (radius: number): Partial<NodeStyle> => ({
icon: {
type: 'textIcon',
family: 'Helvetica',
size: 18,
size: 10,
color: '#FFF',
text: '!',
}
Expand All @@ -53,15 +54,15 @@ const createCompanyStyle = (radius: number): Partial<NodeStyle> => ({
const createPersonStyle = (radius: number): Partial<NodeStyle> => ({
color: '#7CBBF3',
stroke: [{ color: '#90D7FB' }],
icon: { type: 'textIcon' as const, family: 'Material Icons', text: 'person', color: '#fff', size: radius * 1.25 },
icon: { type: 'textIcon' as const, family: 'Material Icons', text: 'person', color: '#fff', size: radius * 1.2 },
badge: [{
position: 45,
color: '#7CBBF3',
stroke: '#FFF',
icon: {
type: 'textIcon',
family: 'Helvetica',
size: 18,
size: 10,
color: '#FFF',
text: '8',
}
Expand All @@ -76,11 +77,11 @@ let nodes = Object.values(graphData.nodes)
.map<Node>(({ id, label, type }) => ({
id,
label,
radius: 32,
radius: 18,
type,
style: type === 'company' ?
createCompanyStyle(32) :
createPersonStyle(32)
createCompanyStyle(18) :
createPersonStyle(18)
}))

let edges = Object.entries<{ field: string, source: string, target: string }>(graphData.edges)
Expand All @@ -104,35 +105,11 @@ let hierarchyEdges: Graph.Edge[] = []
let forceNodes: Node[] = []
let forceEdges: Graph.Edge[] = []

// let nodes = [
// { id: 'a', label: 'A' }, { id: 'b', label: 'B' }, { id: 'c', label: 'C' }, { id: 'd', label: 'D' }, { id: 'e', label: 'E' }, { id: 'f', label: 'F' }, { id: 'g', label: 'G' },
// { id: 'h', label: 'H' }, { id: 'i', label: 'I' }, { id: 'j', label: 'J' }, { id: 'k', label: 'K' }, { id: 'l', label: 'L' }, { id: 'm', label: 'M' }, { id: 'n', label: 'N' },
// { id: 'o', label: 'O' }, { id: 'p', label: 'P' }, { id: 'q', label: 'Q' },
// ]
// .map<Node>(({ id, label }) => ({
// id,
// label,
// radius: 48,
// type: id === 'a' ? 'company' : 'person',
// style: id === 'a' ? createCompanyStyle(48) : createPersonStyle(48)
// }))

// let edges: Graph.Edge[] = [
// { id: 'ba', source: 'a', target: 'b', label: 'None' }, { id: 'ca', source: 'a', target: 'c', label: 'None' }, { id: 'da', source: 'a', target: 'd', label: 'None' },
// { id: 'ea', source: 'a', target: 'e', label: 'A to E', style: { arrow: 'forward' } }, { id: 'fa', source: 'a', target: 'f', label: 'A to F', style: { arrow: 'forward' } },
// { id: 'ga', source: 'a', target: 'g', label: 'A to G', style: { arrow: 'forward' } }, { id: 'ha', source: 'a', target: 'h', label: 'A to H', style: { arrow: 'forward' } },
// { id: 'ia', source: 'a', target: 'i', label: 'A to I', style: { arrow: 'forward' } }, { id: 'ja', source: 'b', target: 'j', label: 'B to J', style: { arrow: 'forward' } },
// { id: 'ka', source: 'b', target: 'k', label: 'K to B', style: { arrow: 'reverse' } }, { id: 'la', source: 'b', target: 'l', label: 'L to B', style: { arrow: 'reverse' } },
// { id: 'ma', source: 'l', target: 'm', label: 'M to L', style: { arrow: 'reverse' } }, { id: 'na', source: 'c', target: 'n', label: 'N to C', style: { arrow: 'reverse' } },
// { id: 'oa', source: 'c', target: 'o', label: 'Both', style: { arrow: 'both' } }, { id: 'pa', source: 'c', target: 'p', label: 'Both', style: { arrow: 'both' } },
// { id: 'qa', source: 'c', target: 'q', label: 'Both', style: { arrow: 'both' } },
// ]


/**
* Initialize Layout and Renderer Options
*/
const container: HTMLCanvasElement = document.querySelector('canvas#graph')
const container: HTMLDivElement = document.querySelector('#graph')

const layoutOptions: Partial<Hierarchy.LayoutOptions> = {
y: container.offsetHeight,
Expand All @@ -142,6 +119,11 @@ const layoutOptions: Partial<Hierarchy.LayoutOptions> = {
const renderOptions: Partial<RendererOptions<Node, Graph.Edge>> = {
width: container.offsetWidth,
height: container.offsetHeight,
x: 0,
y: 0,
zoom: 1,
minZoom: 0.1,
maxZoom: 2.5,
onNodePointerDown: (_, { id }, x, y) => {
nodes = nodes.map((node) => (node.id === id ? { ...node, x, y } : node))
renderer({ nodes, edges, options: renderOptions })
Expand All @@ -166,8 +148,8 @@ const renderOptions: Partial<RendererOptions<Node, Graph.Edge>> = {
nodes = nodes.map((node) => (node.id === id ? {
...node,
style: node.type === 'company' ?
createCompanyStyle(32) :
createPersonStyle(32)
createCompanyStyle(18) :
createPersonStyle(18)
} : node))
renderer({ nodes, edges, options: renderOptions })
},
Expand All @@ -192,6 +174,17 @@ const renderOptions: Partial<RendererOptions<Node, Graph.Edge>> = {

renderer({ nodes, edges, options: renderOptions })
}
},
onContainerDrag: (_, x, y) => {
renderOptions.x = x
renderOptions.y = y
renderer({ nodes, edges, options: renderOptions })
},
onWheel: (_, x, y, zoom) => {
renderOptions.x = x
renderOptions.y = y
renderOptions.zoom = zoom
renderer({ nodes, edges, options: renderOptions })
}
}

Expand All @@ -201,6 +194,7 @@ const renderOptions: Partial<RendererOptions<Node, Graph.Edge>> = {
*/
const hierarchy = Hierarchy.Layout()
const force = Force.Layout()
const zoomControl = Zoom.Control({ container })
const renderer = Renderer<Node, Graph.Edge>({
container,
debug: { stats, logPerformance: false }
Expand All @@ -210,6 +204,18 @@ const renderer = Renderer<Node, Graph.Edge>({
/**
* Layout and Render Graph
*/
zoomControl({
top: 80,
onZoomIn: () => {
renderOptions.zoom = Zoom.clampZoom(renderOptions.minZoom, renderOptions.maxZoom, renderOptions.zoom / 0.6)
renderer({ nodes, edges, options: renderOptions })
},
onZoomOut: () => {
renderOptions.zoom = Zoom.clampZoom(renderOptions.minZoom, renderOptions.maxZoom, renderOptions.zoom * 0.6)
renderer({ nodes, edges, options: renderOptions })
},
})

let layout = 'hierarchy'
const hierarchyData = hierarchy(nodes[0].id, { nodes, edges, options: layoutOptions })
nodes = hierarchyNodes = hierarchyData.nodes
Expand Down
2 changes: 1 addition & 1 deletion examples/pixi-render-perf/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<canvas id="graph"></canvas>
<div id="graph"></div>
<script src="./index.ts"></script>
</body>
</html>
69 changes: 41 additions & 28 deletions examples/pixi-render-perf/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Stats from 'stats.js'
import { Layout, LayoutOptions } from '../../src/layout/force'
import * as Zoom from '../../src/controls/zoom'
import * as Graph from '../../src'
import { Renderer, RendererOptions } from '../../src/renderers/pixi'
import graphData from '../../tmp-data'
Expand Down Expand Up @@ -63,13 +64,13 @@ let nodes = Object.values(graphData.nodes)
.map<Node>(({ id, label, type }) => ({
id,
// label,
radius: 32,
radius: 16,
type,
style: {
color: type === 'company' ? '#ffaf1d' : '#7CBBF3',
stroke: type === 'company' ?
[{ color: '#F7CA4D', width: 4 }] :
[{ color: '#90D7FB', width: 4 }],
[{ color: '#F7CA4D', width: 2 }] :
[{ color: '#90D7FB', width: 2 }],
// icon: { type: 'textIcon' as const, family: 'Material Icons', text: 'person', color: '#fff', size: 32 * 0.6 },
}
}))
Expand Down Expand Up @@ -123,45 +124,47 @@ const layoutOptions: Partial<LayoutOptions> = {
tick: 50,
}

const container: HTMLCanvasElement = document.querySelector('canvas#graph')
const container: HTMLDivElement = document.querySelector('#graph')
const renderOptions: Partial<RendererOptions> = {
width: container.offsetWidth,
height: container.offsetHeight,
x: 0,
y: 0,
zoom: 1,
minZoom: 0.1,
maxZoom: 2.5,
nodesEqual: () => false,
edgesEqual: () => false,
onNodeDrag: throttleAnimationFrame((_, { id }, x, y) => {
nodesById[id].x = x
nodesById[id].y = y
renderOptions.nodesEqual = () => false
renderOptions.edgesEqual = () => false
render({ nodes, edges, options: renderOptions })
}),
// onNodePointerEnter: throttleAnimationFrame((_, { id }) => {
// nodesById[id].radius = 100
// nodesById[id].style.stroke = [{ color: '#CCC', width: 4 }]
// render({ nodes, edges, options: renderOptions })
// }),
// onNodePointerLeave: throttleAnimationFrame((_, { id }) => {
// nodesById[id].radius = 32
// nodesById[id].style.stroke = nodesById[id].type === 'company' ?
// [{ color: '#F7CA4D', width: 4 }] :
// [{ color: '#90D7FB', width: 4 }]
// render({ nodes, edges, options: renderOptions })
// }),
// onEdgePointerEnter: throttleAnimationFrame((_, { id }) => {
// if (edgesById[id].style === undefined) edgesById[id].style = {}
// edgesById[id].style.width = 3
// render({ nodes, edges, options: renderOptions })
// }),
// onEdgePointerLeave: throttleAnimationFrame((_, { id }) => {
// if (edgesById[id].style === undefined) edgesById[id].style = {}
// edgesById[id].style.width = 1
// render({ nodes, edges, options: renderOptions })
// }),
onContainerDrag: (_, x, y) => {
renderOptions.x = x
renderOptions.y = y
renderOptions.nodesEqual = () => true
renderOptions.edgesEqual = () => true
render({ nodes, edges, options: renderOptions })
},
onWheel: (_, x, y, zoom) => {
renderOptions.x = x
renderOptions.y = y
renderOptions.zoom = zoom
renderOptions.nodesEqual = () => true
renderOptions.edgesEqual = () => true
render({ nodes, edges, options: renderOptions })
}
}


/**
* Initialize Layout and Renderer
*/
const layout = Layout()

const zoomControl = Zoom.Control({ container })
const render = throttleAnimationFrame(Renderer({
container,
debug: { stats, logPerformance: true }
Expand All @@ -172,7 +175,17 @@ const render = throttleAnimationFrame(Renderer({
* Layout and Render Graph
*/
console.log(`node count: ${nodes.length} \nedge count ${edges.length}`)

zoomControl({
top: 80,
onZoomIn: () => {
renderOptions.zoom = Zoom.clampZoom(renderOptions.minZoom, renderOptions.maxZoom, renderOptions.zoom / 0.6)
render({ nodes, edges, options: renderOptions })
},
onZoomOut: () => {
renderOptions.zoom = Zoom.clampZoom(renderOptions.minZoom, renderOptions.maxZoom, renderOptions.zoom * 0.6)
render({ nodes, edges, options: renderOptions })
},
})

layout({
nodes,
Expand Down
42 changes: 18 additions & 24 deletions examples/pixi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,33 +126,27 @@ const renderOptions: Partial<RendererOptions> = {
renderer({ nodes, edges, options: renderOptions })
},
onNodePointerEnter: (_, { id }) => {
nodes = nodes.map((node) => (node.id === id ?
{
...node,
style: {
...node.style,
stroke: node.id === 'a' ?
node.style.stroke.map((stroke, idx) => ({ ...stroke, color: idx % 2 === 0 ? '#FFF' : '#CCC' })) :
node.style.stroke.map((stroke) => ({ ...stroke, color: '#CCC' }))
}
} :
node
))
nodes = nodes.map((node) => (node.id === id ? {
...node,
style: {
...node.style,
stroke: node.id === 'a' ?
node.style.stroke.map((stroke, idx) => ({ ...stroke, color: idx % 2 === 0 ? '#FFF' : '#CCC' })) :
node.style.stroke.map((stroke) => ({ ...stroke, color: '#CCC' }))
}
} : node))
renderer({ nodes, edges, options: renderOptions })
},
onNodePointerLeave: (_, { id }) => {
nodes = nodes.map((node) => (node.id === id ?
{
...node,
style: {
...node.style,
stroke: node.id === 'a' ?
createCompanyStyle(48).stroke :
createPersonStyle(48).stroke
}
} :
node
))
nodes = nodes.map((node) => (node.id === id ? {
...node,
style: {
...node.style,
stroke: node.id === 'a' ?
createCompanyStyle(48).stroke :
createPersonStyle(48).stroke
}
} : node))
renderer({ nodes, edges, options: renderOptions })
},
onEdgePointerEnter: (_, { id }) => {
Expand Down

0 comments on commit d08c03c

Please sign in to comment.