@zakkzhang/tw5-graph 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +65 -0
  2. package/package.json +39 -0
  3. package/plugins/graph/DefaultColourMappings.multids +8 -0
  4. package/plugins/graph/ViewTemplateBodyFilter/graph.tid +5 -0
  5. package/plugins/graph/ViewTemplateBodyFilter/properties.tid +5 -0
  6. package/plugins/graph/edges/fields/list.tid +7 -0
  7. package/plugins/graph/edges/fields/tags.tid +7 -0
  8. package/plugins/graph/edges/functions/links.tid +8 -0
  9. package/plugins/graph/edges/functions/transcludes.tid +8 -0
  10. package/plugins/graph/fieldtypes/filter.js +212 -0
  11. package/plugins/graph/fieldtypes/list.js +31 -0
  12. package/plugins/graph/fieldtypes/title.js +27 -0
  13. package/plugins/graph/filterrunprefixes/cache.js +118 -0
  14. package/plugins/graph/filters/gettyped.js +26 -0
  15. package/plugins/graph/graphengine.js +38 -0
  16. package/plugins/graph/icon.tid +16 -0
  17. package/plugins/graph/images/drag.tid +13 -0
  18. package/plugins/graph/macros/action.addedge.tid +16 -0
  19. package/plugins/graph/macros/edges.typed.tid +54 -0
  20. package/plugins/graph/macros/graph.view.tid +24 -0
  21. package/plugins/graph/macros/node.default.tid +9 -0
  22. package/plugins/graph/macros/nodes.neighbors.tid +62 -0
  23. package/plugins/graph/macros/nodes.writable.tid +37 -0
  24. package/plugins/graph/macros/properties.persistent.tid +27 -0
  25. package/plugins/graph/macros/properties.popup.tid +76 -0
  26. package/plugins/graph/macros/properties.river.tid +27 -0
  27. package/plugins/graph/macros/properties.settings.tid +56 -0
  28. package/plugins/graph/macros/properties.stack.tid +17 -0
  29. package/plugins/graph/macros/tiddlywiki.files +17 -0
  30. package/plugins/graph/plugin.info +14 -0
  31. package/plugins/graph/presettypes/edges/fields.tid +18 -0
  32. package/plugins/graph/presettypes/edges/functions.tid +5 -0
  33. package/plugins/graph/presettypes/nodes/stack.tid +6 -0
  34. package/plugins/graph/propertytypes/actions.js +15 -0
  35. package/plugins/graph/propertytypes/boolean.js +23 -0
  36. package/plugins/graph/propertytypes/enum.js +25 -0
  37. package/plugins/graph/propertytypes/image.js +140 -0
  38. package/plugins/graph/propertytypes/number.js +24 -0
  39. package/plugins/graph/propertytypes/string.js +13 -0
  40. package/plugins/graph/propertytypes/tiddlywiki.files +17 -0
  41. package/plugins/graph/readme.tid +5 -0
  42. package/plugins/graph/relink/attributes.js +52 -0
  43. package/plugins/graph/relink/attributes.multids +19 -0
  44. package/plugins/graph/relink/configprefix.js +76 -0
  45. package/plugins/graph/relink/fieldedgeprefix.js +39 -0
  46. package/plugins/graph/relink/fields.multids +11 -0
  47. package/plugins/graph/relink/graphprefix.js +28 -0
  48. package/plugins/graph/relink/operators.multids +3 -0
  49. package/plugins/graph/relink/propertyfields.js +81 -0
  50. package/plugins/graph/relink/utils.js +99 -0
  51. package/plugins/graph/settings.tid +13 -0
  52. package/plugins/graph/startup/messages.js +46 -0
  53. package/plugins/graph/stylesheets/base.css.tid +263 -0
  54. package/plugins/graph/stylesheets/fullscreen/core.css +11 -0
  55. package/plugins/graph/stylesheets/fullscreen/core.css.meta +3 -0
  56. package/plugins/graph/stylesheets/fullscreen.css.tid +46 -0
  57. package/plugins/graph/stylesheets/popup.css.tid +107 -0
  58. package/plugins/graph/subfilters.tid +23 -0
  59. package/plugins/graph/tags/GraphToolbar.tid +2 -0
  60. package/plugins/graph/tags/SettingsTab.tid +2 -0
  61. package/plugins/graph/tags/Template.tid +2 -0
  62. package/plugins/graph/tags/ViewEditTemplate.tid +2 -0
  63. package/plugins/graph/templates/live-graph.tid +34 -0
  64. package/plugins/graph/templates/standard-graph.tid +40 -0
  65. package/plugins/graph/ui/Buttons/center.tid +38 -0
  66. package/plugins/graph/ui/Buttons/export.tid +65 -0
  67. package/plugins/graph/ui/Buttons/fullscreen.tid +35 -0
  68. package/plugins/graph/ui/Buttons/settings.tid +28 -0
  69. package/plugins/graph/ui/Buttons/tiddlywiki.files +16 -0
  70. package/plugins/graph/ui/EditTemplate/Edges.tid +22 -0
  71. package/plugins/graph/ui/EditTemplate/Neighbors.tid +35 -0
  72. package/plugins/graph/ui/EditTemplate/Nodes.tid +12 -0
  73. package/plugins/graph/ui/EditTemplate/Popups.tid +27 -0
  74. package/plugins/graph/ui/EditTemplate/Properties.tid +21 -0
  75. package/plugins/graph/ui/EditTemplate/tiddlywiki.files +16 -0
  76. package/plugins/graph/ui/Modals/NewPropertySet.tid +20 -0
  77. package/plugins/graph/ui/Modals/NewView.tid +20 -0
  78. package/plugins/graph/ui/Modals/Select.tid +72 -0
  79. package/plugins/graph/ui/Modals/SelectField.tid +21 -0
  80. package/plugins/graph/ui/Modals/SelectTiddler.tid +15 -0
  81. package/plugins/graph/ui/Modals/Tiddler.tid +22 -0
  82. package/plugins/graph/ui/Modals/TiddlerHeader.tid +15 -0
  83. package/plugins/graph/ui/PropertyTypes/boolean.tid +11 -0
  84. package/plugins/graph/ui/PropertyTypes/color.tid +5 -0
  85. package/plugins/graph/ui/PropertyTypes/enum.tid +15 -0
  86. package/plugins/graph/ui/PropertyTypes/number.tid +17 -0
  87. package/plugins/graph/ui/Settings/Engine.tid +23 -0
  88. package/plugins/graph/ui/Settings/Graphs/EditTemplate.tid +52 -0
  89. package/plugins/graph/ui/Settings/Graphs.tid +49 -0
  90. package/plugins/graph/ui/Settings/Properties/ObjectsTypeTemplate.tid +44 -0
  91. package/plugins/graph/ui/Settings/Properties.tid +14 -0
  92. package/plugins/graph/ui/Settings/Toolbar.tid +5 -0
  93. package/plugins/graph/ui/SideBar/Graph.tid +77 -0
  94. package/plugins/graph/ui/Toolbars/GraphToolbar.tid +15 -0
  95. package/plugins/graph/ui/ViewTemplate/graph-object.tid +13 -0
  96. package/plugins/graph/ui/ViewTemplate/graph.tid +11 -0
  97. package/plugins/graph/ui/ViewTemplate/properties.tid +80 -0
  98. package/plugins/graph/ui/grouped-tabs.tid +109 -0
  99. package/plugins/graph/ui/selector.tid +74 -0
  100. package/plugins/graph/utils.js +148 -0
  101. package/plugins/graph/widgets/action-delay.js +72 -0
  102. package/plugins/graph/widgets/action-modal.js +121 -0
  103. package/plugins/graph/widgets/action-typed.js +56 -0
  104. package/plugins/graph/widgets/action-with.js +70 -0
  105. package/plugins/graph/widgets/boundingbox.js +126 -0
  106. package/plugins/graph/widgets/fieldTranscriber.js +98 -0
  107. package/plugins/graph/widgets/fieldtranscriber/filter.js +93 -0
  108. package/plugins/graph/widgets/fieldtranscriber/json.js +34 -0
  109. package/plugins/graph/widgets/fieldtranscriber/plain.js +11 -0
  110. package/plugins/graph/widgets/graphobject.js +120 -0
  111. package/plugins/graph/widgets/messagerelay.js +115 -0
  112. package/plugins/graph/widgets/properties.js +131 -0
  113. package/plugins/graph/widgets/subclass/edge.js +47 -0
  114. package/plugins/graph/widgets/subclass/graph.js +424 -0
  115. package/plugins/graph/widgets/subclass/node.js +44 -0
  116. package/plugins/graph/widgets/tiddlywiki.files +43 -0
@@ -0,0 +1,54 @@
1
+ \widget $edges.typed($editable:no)
2
+ \whitespace trim
3
+ <$parameters
4
+ $$functions={{{ [<functionsFilter>!is[blank]] ~"[all[]]" }}}
5
+ $$fields={{{ [<fieldsFilter>!is[blank]] ~"[all[]]" }}}
6
+ $$tiddler=<<currentTiddler>> >
7
+
8
+ <!-- First create edges for field types -->
9
+
10
+ <$list variable=fieldName filter="+[subfilter{$:/plugins/flibbles/graph/subfilters##edgetypes.fields}subfilter<$fields>]">
11
+
12
+ <$let
13
+ dataTiddler=`$:/config/flibbles/graph/edges/fields/$(fieldName)$` >
14
+
15
+ <$properties $for=edges
16
+ $tiddler=<<dataTiddler>>
17
+ delete={{{ [<$editable>!match[no]then[<$action-removetyped $tiddler=<<fromTiddler>> $field=<<fieldName>> $value=<<toTiddler>> />]] }}} >
18
+
19
+
20
+ <$list variable=toTiddler counter=index filter="[<$tiddler>] :map:flat[gettyped<fieldName>] +[!is[blank]]">
21
+
22
+ <$vars id=`$:/edge/fields/$($tiddler)$
23
+ $(fieldName)$-$(index)$`>
24
+
25
+ <$slot $name=ts-raw>
26
+
27
+ <$edge $from=<<$tiddler>> $id=<<id>> />
28
+
29
+ </$slot></$vars></$list></$properties></$let></$list>
30
+
31
+ <!-- Now create edges for function types -->
32
+
33
+ <$list variable=functionName filter="[subfilter{$:/plugins/flibbles/graph/subfilters##edgetypes.functions}subfilter<$functions>]">
34
+
35
+ <$let
36
+ dataTiddler=`$:/config/flibbles/graph/edges/functions/$(functionName)$`
37
+ function={{{ [<dataTiddler>get[filter]] }}} >
38
+
39
+ <$properties $for=edges
40
+ $tiddler=<<dataTiddler>> >
41
+
42
+ <$list variable=toTiddler counter=index filter="[<$tiddler>] :map:flat[subfilter<function>] +[!is[blank]]">
43
+
44
+ <$vars id=`$:/edge/functions/$($tiddler)$
45
+ $(functionName)$-$(index)$`>
46
+
47
+ <$slot $name=ts-raw>
48
+
49
+ <$edge $from=<<$tiddler>> $id=<<id>> />
50
+
51
+ </$slot></$vars></$list></$properties></$let></$list>
52
+ \end
53
+
54
+ \relink $edges.typed $functions:filter $fields:filter $tiddler:title
@@ -0,0 +1,24 @@
1
+ \widget $graph.view($tiddler:"$:/graph/Default", $mode)
2
+ \whitespace trim
3
+ <$parameters
4
+ $params=viewParams
5
+ $parseMode=$defaultMode
6
+ $$template={{{ [<$tiddler>get[template]] ~[[$:/tags/flibbles/graph/Template]tagging[]first[]] }}}
7
+ $$engine={{{ [<$tiddler>get[engine]] ~[<graphengine>] }}} >
8
+
9
+ <$vars
10
+ currentTiddler=<<$tiddler>>
11
+ graphengine=<<$engine>> >
12
+
13
+ <$genesis
14
+ $type="$transclude"
15
+ $$tiddler=<<$template>>
16
+ $$fillignore=yes
17
+ $$mode={{{ [<$mode>!is[blank]else<$defaultMode>] }}}
18
+ $names="[<viewParams>jsonindexes[]!prefix[$]]"
19
+ $values="[<viewParams>jsonindexes[]!prefix[$]] :map[<viewParams>jsonget{!!title}]" />
20
+
21
+ </$vars></$parameters>
22
+ \end
23
+
24
+ \relink $graph.view $tiddler
@@ -0,0 +1,9 @@
1
+ \widget $node.default()
2
+ <$wikify name=label
3
+ mode=inline
4
+ text={{{ [{!!title}get[caption]else[<$text text={{!!title}} />]] }}} >
5
+
6
+ <$node $pos=<<pos>> label=<<label>> color={{!!color}} image={{!!icon}} />
7
+
8
+ </$wikify>
9
+ \end
@@ -0,0 +1,62 @@
1
+ \widget $nodes.neighbors($filter, $fields:'[all[]]', $functions:'[all[]]', $interedges, $whitelist:'[!is[system]]')
2
+
3
+ <!-- None of these \procedures are \functions because that mucks with caching. -->
4
+ \procedure filter.cached() [{!!title}] :cache[all[tiddlers]subfilter<$filter>]
5
+
6
+ <!-- Holy nuts this is getting complicated, but we need to :map:flat twice
7
+ in order to switch ..currentTiddler and currentTiddler, as the fields
8
+ and functions will expect it. -->
9
+ \procedure edges.fields.flipped() [<..currentTiddler>] :map:flat[<currentTiddler>gettyped<..currentTiddler>]
10
+ \procedure edges.functions.flipped() [<..currentTiddler>] :map:flat[<currentTiddler>subfilter<..currentTiddler>]
11
+
12
+ \procedure edges.fields() :cache[subfilter{$:/plugins/flibbles/graph/subfilters##edgetypes.fields}subfilter<$fields>] :map:flat[<..currentTiddler>subfilter<edges.fields.flipped>]
13
+ \procedure edges.functions() :cache[subfilter{$:/plugins/flibbles/graph/subfilters##edgetypes.functions}subfilter<$functions>addprefix[$:/config/flibbles/graph/edges/functions/]get[filter]] :map:flat[<..currentTiddler>subfilter<edges.functions.flipped>]
14
+
15
+ \procedure neighbors.for() [subfilter<edges.fields>] [subfilter<edges.functions>] +[!is[blank]unique[]]
16
+ \procedure neighbors.cached() [all[]] :cache[subfilter<neighbors.for>]
17
+
18
+ \procedure incoming.raw() [all[tiddlers]subfilter<$whitelist>!search:title:regexp,casesensitive<regexp>] :filter[subfilter<neighbors.cached>search:title:regexp,casesensitive<regexp>]
19
+ \procedure incoming.cached() :cache[subfilter<incoming.raw>]
20
+ \whitespace trim
21
+
22
+ <$vars
23
+ regexp={{{ [subfilter<filter.cached>escaperegexp[]join[|]addprefix[^(?:]addsuffix[)$]] }}}
24
+ functionsFilter=<<$functions>>
25
+ fieldsFilter=<<$fields>> >
26
+
27
+ <!-- incoming neighbors -->
28
+
29
+ <$list filter=<<incoming.cached>> >
30
+
31
+ <$slot $name=ts-raw>
32
+
33
+ <$node.default />
34
+
35
+ </$slot>
36
+
37
+ <$edges.typed>
38
+
39
+ <%if [<$interedges>match[yes]] ~[<toTiddler>search:title:regexp,casesensitive<regexp>] %>
40
+
41
+ <$edge $id=<<id>> />
42
+
43
+ <%endif%></$edges.typed></$list>
44
+
45
+ <!-- outgoing neighbors -->
46
+
47
+ <$list filter="[subfilter<filter.cached>subfilter<neighbors.cached>subfilter<$whitelist>!search:title:regexp,casesensitive<regexp>] -[subfilter<incoming.cached>]">
48
+
49
+ <$slot $name=ts-raw>
50
+
51
+ <$node.default />
52
+
53
+ </$slot>
54
+
55
+ <%if [<$interedges>match[yes]] %>
56
+
57
+ <$edges.typed />
58
+
59
+ <%endif%></$list>
60
+ \end
61
+
62
+ \relink $nodes.neighbors $filter:filter $fields:filter $functions:filter $whitelist:filter
@@ -0,0 +1,37 @@
1
+ \widget $nodes.writable($field, $variable:currentTiddler)
2
+
3
+ \procedure actionAddnode()
4
+ \whitespace trim
5
+ <$action-modal $tiddler="$:/plugins/flibbles/graph/ui/Modals/SelectTiddler">
6
+ <% if [<selection>!is[tiddler]] %>
7
+ <$action-createtiddler $basetitle=<<selection>> />
8
+ <% endif %>
9
+ <% if [<$field>!match[]] %>
10
+ <$action-addtyped $tiddler=<<$tiddler>> $field=<<$field>> $value=<<selection>> />
11
+ <% endif %>
12
+ <$transclude $variable=recordPosition title=<<selection>> />
13
+ </$action-modal>
14
+ <$action-sendmessage $message=tm-focus-selector $param="input.graph-select" />
15
+ \end actionAddnode
16
+
17
+ \whitespace trim
18
+ <$parameters $$tiddler={{!!title}}>
19
+
20
+ <$properties $for=graph
21
+ doubleclick=<<actionAddnode>>
22
+ addNode=<<actionAddnode>>
23
+ drop="""<$action-addtyped $tiddler=<<$tiddler>> $field=<<$field>> $value=<<dropTiddler>> />"""
24
+ addEdge="""<$action.addedge/>"""
25
+ />
26
+
27
+ <$properties delete="<$action-removetyped $tiddler=<<$tiddler>> $field=<<$field>> $value=<<nodeTiddler>> />">
28
+
29
+ <$list variable=<<$variable>> filter="[<$tiddler>gettyped<$field>!is[draft]]">
30
+
31
+ <$slot $name=ts-raw>
32
+
33
+ <$node.default />
34
+
35
+ \end
36
+
37
+ \relink $nodes.writable $field:fieldname $tiddler:title
@@ -0,0 +1,27 @@
1
+ \widget $properties.persistent($dataTiddler)
2
+ \whitespace trim
3
+
4
+ \function pos() [<$dataTiddler>getindex{!!title}]
5
+
6
+ \procedure recordPosition(title)
7
+ \whitespace trim
8
+ <$action-setfield
9
+ $tiddler=<<$dataTiddler>>
10
+ $index=<<title>>
11
+ $value=`$(x)$,$(y)$`/>
12
+ <%if [<$dataTiddler>!prefix[$:/graph/]] %>
13
+ <$fieldmangler tiddler=<<$dataTiddler>> >
14
+ <$action-sendmessage $message=tm-add-tag $param="$:/tags/flibbles/graph/TiddlerData" />
15
+ </$fieldmangler>
16
+ <%endif%>
17
+ \end recordPosition
18
+
19
+ <$properties
20
+ free="<$transclude $variable=recordPosition title=<<nodeTiddler>> />"
21
+ delete="<$action-setfield $tiddler=<<$dataTiddler>> $index=<<nodeTiddler>>/>">
22
+
23
+ <$slot $name=ts-raw />
24
+
25
+ \end
26
+
27
+ \relink $properties.persistent $dataTiddler:title
@@ -0,0 +1,76 @@
1
+ \widget $properties.popup($enabled:yes $ms:600, $width, $height:50%, $for:nodes)
2
+ \whitespace trim
3
+
4
+ <$parameters $state={{{ [<qualify "$:/state/graph/tooltip">addsuffix[-]addsuffix<$for>] }}} >
5
+
6
+ <$let state=<<$state>>
7
+ delayState=`$(state)$-delay`
8
+ blurringState=`$(state)$-interrupt`
9
+ draggingState=`$(state)$-dragging`
10
+ $msLinger=0>
11
+
12
+ <$properties $for={{{ [<$enabled>match[yes]then<$for>] }}}
13
+ hover="""\whitespace trim
14
+ <%if [<draggingState>] [<state>] +[is[tiddler]count[]match[0]] %>
15
+ <$action-delay $state=<<delayState>> $ms=<<$ms>> >
16
+ <$action-with $offset="mouse" $canvas=canvas>
17
+ <$vars
18
+ lr={{{ [<mouse-x>multiply[2]compare:number:gt<canvas-width>then[right]else[left]] }}}
19
+ tb={{{ [<mouse-y>multiply[2]compare:number:gt<canvas-height>then[bottom]else[top]] }}} >
20
+ <$action-popup $state=<<$state>> $coords="(0,0,0,0)"/>
21
+ <$genesis $type=$action-setfield $$tiddler=<<$state>>
22
+ $names="[<$for>subfilter{$:/plugins/flibbles/graph/subfilters##actioncontext}addprefix[context.]]"
23
+ $values="[<$for>subfilter{$:/plugins/flibbles/graph/subfilters##actioncontext}getvariable[]]"
24
+ x={{{ [<lr>match[left]then<mouse-x>] ~[<canvas-width>subtract<mouse-x>] }}}
25
+ y={{{ [<tb>match[top]then<mouse-y>] ~[<canvas-height>subtract<mouse-y>] }}}
26
+ lr=<<lr>>
27
+ tb=<<tb>> />
28
+ </$vars>
29
+ </$action-pointer>
30
+ </$action-delay>
31
+ <%endif%>
32
+ <$action-deletetiddler $tiddler=<<blurringState>> />"""
33
+ blur="""\whitespace trim
34
+ <$action-delay $state=<<blurringState>> $ms=<<$msLinger>> >
35
+ <$action-deletetiddler $tiddler=<<delayState>> />
36
+ <$action-popup $state=<<state>> />"""
37
+ drag="""\whitespace trim
38
+ <$action-deletetiddler $tiddler=<<delayState>> />
39
+ <$action-popup $state=<<state>> />
40
+ <$action-setfield $tiddler=<<draggingState>> text=dragging />"""
41
+ free='<$action-deletetiddler $tiddler=<<draggingState>> />' >
42
+
43
+ <$slot $name="ts-raw" />
44
+
45
+ </$properties>
46
+
47
+ <$vars
48
+ x={{{ [<$state>get[x]] }}}
49
+ y={{{ [<$state>get[y]] }}}
50
+ lr={{{ [<$state>get[lr]] }}}
51
+ tb={{{ [<$state>get[tb]] }}}
52
+ width={{{ [<$width>!is[blank]addprefix[max-width:]addsuffix[;]] }}} >
53
+
54
+ <!-- We aren't using the popup type because we need to be more dynamic about placing the popup in different directions. The text must be a coord because of $action-popup, but we don't use it. -->
55
+
56
+ <%if [<$enabled>match[yes]] %>
57
+
58
+ <$reveal
59
+ type=match
60
+ text="(0,0,0,0)"
61
+ state=<<$state>>
62
+ positionAllowNegative=yes
63
+ class="graph-popup tc-popup tc-popup-keep"
64
+ style=`$(width)$max-height:$($height)$;$(lr)$:$(x)$px;$(tb)$:$(y)$px;`>
65
+
66
+ <$genesis $type=$vars
67
+ $names="[<$state>fields[]removeprefix[context.]]"
68
+ $values="[<$state>fields[]prefix[context.]] :map[<$state>get{!!title}]" >
69
+
70
+ <$slot $name=tooltip>
71
+
72
+ <$transclude $tiddler=<<nodeTiddler>> />
73
+
74
+ \end
75
+
76
+ \relink $properties.popup $state:title
@@ -0,0 +1,27 @@
1
+ \widget $properties.river()
2
+ \parameters ($state: "$:/state/flibbles/graph/river")
3
+ \whitespace trim
4
+
5
+ <%if [<graph-sidebar>!match[yes]] %>
6
+
7
+ <$qualify name=state title=<<$state>> >
8
+
9
+ <$properties $for=graph
10
+ blur="<$action-deletetiddler $tiddler=<<state>> />"
11
+ focus="<$action-setfield $tiddler=<<state>> text=focused />"
12
+ zoom={{{ [<state>get[text]match[focused]then[yes]else[no]] }}} />
13
+
14
+ <$slot $name="ts-raw" />
15
+
16
+ <$properties $for=graph navigation={{{ [<state>get[text]match[focused]then[]else[no]] }}} />
17
+
18
+ </$qualify><%else%>
19
+
20
+ <$properties $for=graph zoom=yes />
21
+
22
+ <$slot $name="ts-raw" />
23
+
24
+ <%endif%>
25
+ \end
26
+
27
+ \relink $properties.river $state:title
@@ -0,0 +1,56 @@
1
+ \widget $properties.settings()
2
+ \whitespace trim
3
+
4
+ <$properties.popup
5
+ $enabled={{!!popup}}
6
+ $ms={{{ [{!!title}get[popup.ms]else[600]] }}}
7
+ $width={{{ [{!!title}get[popup.width]else[300px]] }}}
8
+ $height={{{ [{!!title}get[popup.height]else[200px]] }}} >
9
+
10
+ <$fill $name=tooltip>
11
+
12
+ <$let
13
+ currentGraph=<<currentTiddler>>
14
+ currentTiddler=<<nodeTiddler>> >
15
+
16
+ <%if [<currentGraph>has[popup.template]] %>
17
+
18
+ <$transclude $tiddler=<<currentGraph>> $field="popup.template" />
19
+
20
+ <%else%>
21
+
22
+ {{}}
23
+ <%endif%></$let></$fill>
24
+
25
+ <$properties.river>
26
+
27
+ <$properties $tiddler={{!!title}} $field="graph.edges" $for=edges >
28
+
29
+ <$properties $tiddler={{!!title}} $field="graph.nodes" $for=nodes >
30
+
31
+ <$properties.stack>
32
+
33
+ <$let
34
+ fieldsFilter={{{ [{!!edges.fields}!is[blank]] ~"[all[]]" }}}
35
+ functionsFilter={{{ [{!!edges.functions}!is[blank]] ~"[all[]]" }}}>
36
+
37
+ <$slot $name="ts-raw" $depth=4 />
38
+
39
+ <%if [{!!neighbors.incoming}] =[{!!neighbors.outgoing}] +[match[1]count[]match[2]] %>
40
+
41
+ <$wikify name=muted text="<<colour muted-foreground>>">
42
+
43
+ <$properties color=<<muted>> >
44
+
45
+ <$nodes.neighbors
46
+ $filter={{!!filter}}
47
+ $functions=<<functionsFilter>>
48
+ $fields=<<fieldsFilter>>
49
+ $interedges={{!!neighbors.interedges}}
50
+ $whitelist={{{ [{!!title}get[neighbors.whitelist]] ~"[!is[system]]" }}} />
51
+
52
+ </$properties></$wikify><%endif%></$let></$properties.stack></$properties></$properties>
53
+ <$properties $tiddler={{!!title}} $field="graph.graph" $for=graph />
54
+
55
+ </$properties.river></$properties.popup>
56
+ \end
@@ -0,0 +1,17 @@
1
+ \widget $properties.stack()
2
+ \procedure $properties.stack.recurse(zth)
3
+ \procedure node.stack() [list[$:/config/flibbles/graph/nodes/stack]] =[all[shadows+tiddlers]prefix[$:/config/flibbles/graph/nodes/stack/]sort[]] +[unique[]is[tiddler]]
4
+ \whitespace trim
5
+ <%if :cache[subfilter<node.stack>] +[zth<zth>] %>
6
+ <$properties $filter={{{ [<condition>get[filter]] }}} $tiddler=<<condition>> >
7
+ <$transclude $variable=$properties.stack.recurse $fillignore=yes zth={{{ [<zth>add[1]] }}} />
8
+ </$properties>
9
+ <%else%>
10
+ <$slot $name=ts-raw />
11
+ <%endif%>
12
+ \end $properties.stack.recurse
13
+ \whitespace trim
14
+
15
+ <$transclude $variable=$properties.stack.recurse zth=0 $fillignore=yes />
16
+
17
+ \end
@@ -0,0 +1,17 @@
1
+ {
2
+ "directories": [
3
+ {
4
+ "path": ".",
5
+ "filesRegExp": "^.*\\.tid$",
6
+ "isTiddlerFile": false,
7
+ "fields": {
8
+ "title": {
9
+ "source": "basename",
10
+ "prefix": "$:/plugins/flibbles/graph/macros/"
11
+ },
12
+ "tags": "$:/tags/Global",
13
+ "code-body": "yes"
14
+ }
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "Graph",
3
+ "title": "$:/plugins/flibbles/graph",
4
+ "description": "Lightweight and programmable graphing for Tiddlywiki",
5
+ "author": "Flibbles",
6
+ "version": "1.6.4",
7
+ "stability": "STABILITY_2_STABLE",
8
+ "core-version": ">=5.3.7",
9
+ "source": "https://github.com/flibbles/tw5-graph",
10
+ "demo": "http://flibbles.github.io/tw5-graph/",
11
+ "list": "readme settings",
12
+ "dependents": "",
13
+ "plugin-type": "plugin"
14
+ }
@@ -0,0 +1,18 @@
1
+ title: $:/plugins/flibbles/graph/presettypes/edges/fields
2
+
3
+ \procedure typeSelector()
4
+ \whitespace trim
5
+ <$select tiddler=`$:/config/flibbles/relink/fields/$(fieldName)$` default=list>
6
+ <$list filter="[[$:/plugins/flibbles/relink]is[tiddler]then[relinkfieldtype]else[fieldtype]modules[]moduleproperty[name]]">
7
+ <option>
8
+ <$text text={{!!title}} />
9
+ </option>
10
+ </$list>
11
+ </$select>
12
+ \end
13
+
14
+ "Fields" presets define the edge properties for edges corresponding to tiddler fields. These types of edges can be easily added to a node using the <<.link EdgesAllWidget>> widget, or the more inclusive `$edges.typed` widget, which encompasses all other types of preset edge types.
15
+
16
+ <$vars fieldName={{{ [<currentTiddler>removeprefix[$:/config/flibbles/graph/edges/fields/]] }}}>
17
+
18
+ Field type: <<typeSelector>>
@@ -0,0 +1,5 @@
1
+ title: $:/plugins/flibbles/graph/presettypes/edges/functions
2
+
3
+ "Function" edges define properties for edges generated from input nodes //individually// into a filter, and then creating an edge from that node to each of the filter's output.
4
+
5
+ Filter: <$edit-text field=filter />
@@ -0,0 +1,6 @@
1
+ title: $:/plugins/flibbles/graph/presettypes/nodes/stack
2
+ orderable: yes
3
+
4
+ "stack" nodes define the node properties that can be applied as a stack to contained nodes, such as nodes contained within `$properties.stack`. For each node, the stack of node properties are applied one after another, each depending on if that node matches any given stack property's filter.
5
+
6
+ Filter: <$edit-text field=filter />
@@ -0,0 +1,15 @@
1
+ /*\
2
+
3
+ Defines behavior to be taken in the event that particular action is called.
4
+
5
+ \*/
6
+
7
+ "use strict";
8
+
9
+ exports.name = "actions";
10
+
11
+ exports.type = "wikitext";
12
+
13
+ exports.toProperty = function(info, value) {
14
+ return value? true: null;
15
+ };
@@ -0,0 +1,23 @@
1
+ /*\
2
+
3
+ Defines behavior for boolean types in graph engine properties.
4
+
5
+ \*/
6
+
7
+ "use strict";
8
+
9
+ exports.name = "boolean";
10
+
11
+ var falses = {
12
+ no: true,
13
+ "false": true,
14
+ "0": true,
15
+ n: true,
16
+ f: true,
17
+ '': true,
18
+ ' ': true
19
+ };
20
+
21
+ exports.toProperty = function(info, value) {
22
+ return !falses[value.toLowerCase()];
23
+ };
@@ -0,0 +1,25 @@
1
+ /*\
2
+
3
+ Defines behavior for enum types in graph engine properties.
4
+
5
+ \*/
6
+
7
+ "use strict";
8
+
9
+ exports.name = "enum";
10
+
11
+ exports.toProperty = function(info, value) {
12
+ if (info.multiple) {
13
+ var values = $tw.utils.parseStringArray(value);
14
+ if (values.length === 0) {
15
+ return values;
16
+ }
17
+ var filtered = values.filter(v => info.values.indexOf(v) >= 0);
18
+ if (filtered.length > 0) {
19
+ return filtered;
20
+ }
21
+ } else if (value && info.values.indexOf(value) >= 0) {
22
+ return value;
23
+ }
24
+ return null;
25
+ };
@@ -0,0 +1,140 @@
1
+ /*\
2
+
3
+ Defines images types, and manages fetching a url from titles.
4
+
5
+ \*/
6
+
7
+ "use strict";
8
+
9
+ exports.name = "image";
10
+
11
+ exports.type = "title";
12
+
13
+ exports.toProperty = function(info, value, options) {
14
+ var tiddler = options.widget.wiki.getTiddler(value);
15
+ if (!tiddler) {
16
+ // It does not appear to be a real tiddler,
17
+ // so let's treat it like a real URL.
18
+ return value;
19
+ }
20
+ var cache = options.widget.wiki.getGlobalCache("graph-image", function() {
21
+ return Object.create(null);
22
+ });
23
+ if (!cache[value]) {
24
+ var output = getTiddlerUri(value, options.widget);
25
+ if (output.uri === undefined && output.widget) {
26
+ var container = $tw.fakeDocument.createElement("div");
27
+ output.widget.render(container, null);
28
+ var svg = findSVGElement(container);
29
+ if (!svg) {
30
+ // Not an image as far as we can tell. Ignore the input.
31
+ output.uri = null;
32
+ } else {
33
+ injectNamespace(svg);
34
+ // wikitext images may benefit from colors. svg images should too, but let's
35
+ // not worry about that right now.
36
+ output.widget.color = options.widget.getColor("nodeColor");
37
+ injectStyle(svg, output.widget);
38
+ output.uri = "data:image/svg+xml," + encodeURIComponent(container.innerHTML);
39
+ }
40
+ }
41
+ cache[value] = output;
42
+ }
43
+ return cache[value].uri;
44
+ };
45
+
46
+ exports.refresh = function(info, value, changedTiddlers, widget) {
47
+ if (changedTiddlers[value]) {
48
+ return true;
49
+ }
50
+ var graphWidget = getGraphWidget(widget);
51
+ var tiddler = graphWidget.wiki.getTiddler(value);
52
+ if (tiddler) {
53
+ var output = getTiddlerUri(value, graphWidget);
54
+ if (output.widget && output.widget.refresh(changedTiddlers)) {
55
+ output.uri = undefined;
56
+ return true;
57
+ }
58
+ }
59
+ // Now we need to check whether the color for this image has changed
60
+ if (output && output.widget) {
61
+ var newColor = graphWidget.getColor("nodeColor");
62
+ if (newColor !== output.widget.color) {
63
+ output.color = newColor;
64
+ return true;
65
+ }
66
+ }
67
+ return false;
68
+ };
69
+
70
+ function getGraphWidget(widget) {
71
+ while (widget && !widget.getColor) {
72
+ widget = widget.parentWidget;
73
+ }
74
+ return widget;
75
+ };
76
+
77
+ function getTiddlerUri(title, widget) {
78
+ var wiki = widget.wiki;
79
+ var tiddler = wiki.getTiddler(title);
80
+ var output = {};
81
+ if(wiki.isImageTiddler(title)) {
82
+ // Check if it is an image tiddler
83
+ var type = tiddler.fields.type,
84
+ text = tiddler.fields.text,
85
+ _canonical_uri = tiddler.fields._canonical_uri,
86
+ typeInfo = $tw.config.contentTypeInfo[type] || {},
87
+ deserializerType = typeInfo.deserializerType || type;
88
+ if(text) {
89
+ // Render the appropriate element for the image type by looking up the encoding in the content type info
90
+ var encoding = typeInfo.encoding || "utf8";
91
+ if (encoding === "base64") {
92
+ // .pdf .png .jpg etc.
93
+ output.uri = "data:" + deserializerType + ";base64," + text;
94
+ } else {
95
+ // .svg .tid .xml etc.
96
+ output.uri = "data:" + deserializerType + ";" + encoding + "," + encodeURIComponent(text);
97
+ }
98
+ } else if(_canonical_uri) {
99
+ output.uri = _canonical_uri;
100
+ } else {
101
+ // This must be a lazily loaded tiddler. We don't suppor those yet.
102
+ output.uri = null;
103
+ }
104
+ } else {
105
+ // We assume it is wikitext trying to make an svg
106
+ output.widget = wiki.getCacheForTiddler(title, "graph-image", function() {
107
+ var parser = wiki.parseTiddler(title, {parseAsInline: true});
108
+ return wiki.makeWidget(parser, {parentWidget: widget});
109
+ });
110
+ }
111
+ return output;
112
+ };
113
+
114
+ function findSVGElement(element) {
115
+ if (element.tag === "svg") {
116
+ return element;
117
+ }
118
+ if (element.children) {
119
+ for (var i = 0; i < element.children.length; i++) {
120
+ var found = findSVGElement(element.children[i]);
121
+ if (found) {
122
+ return found;
123
+ }
124
+ }
125
+ }
126
+ return null;
127
+ };
128
+
129
+ function injectNamespace(svg) {
130
+ // wikitext svg does not need namespacing, but data URIs do
131
+ svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
132
+ };
133
+
134
+ function injectStyle(svg, widget) {
135
+ if (widget.color) {
136
+ var style = $tw.fakeDocument.createElement("style");
137
+ style.textContent = ":root{fill:" + widget.color + ";}";
138
+ svg.insertBefore(style, svg.children[0]);
139
+ }
140
+ };