-
Notifications
You must be signed in to change notification settings - Fork 0
/
about.html
235 lines (220 loc) · 12.3 KB
/
about.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
<html>
<head>
<title>Google Drive Realtime quickstart</title>
<meta http-equiv="X-UA-Compatible" content="IE=9">
<script type="text/javascript" src="https://apis.google.com/js/api.js"></script>
<script>
// called by controller.js
function onFileLoaded(doc) {printAll()}
function printAll() {
var keys = controller.graph.keys() ; document.querySelector("#textarea1").value = ""
for (i in keys) {
console.log(keys[i] + " => " + controller.graph.get(keys[i]))
document.querySelector("#textarea1").value += keys[i] + " => " + controller.graph.get(keys[i]) + "\n"
}
}
var refreshTimer
function onMapValueChanged(evt) {
//console.log("event = " + showAll(evt))
// null => "" when created
// "something" => null when deleted
if (evt.newValue == null) console.log("remote event: deleted " + evt.property)
else if (evt.oldValue == null) console.log("remote event: created " + evt.property)
else console.log("remote event: model updated " + evt.property + ": " + evt.oldValue + " => " + evt.newValue)
clearTimeout(refreshTimer) ; refreshTimer = setTimeout(printAll, 300);
}
</script>
</head>
<!-- Start Realtime when the body has loaded. -->
<body onLoad='controller = new Controller()'>
<script type="text/javascript" src="realtime-client-utils.js"></script>
<script type="text/javascript" src="controller.js"></script>
<button id="authorizeButton" disabled>You must authorize</button>
<button id="pick" onclick="rtclient.selectOrCreateNew()">Pick another file</button>
<!-- Undo and redo buttons. -->
<button id="undoButton" disabled>Undo</button>
<button id="redoButton" disabled>Redo</button>
<p>
<button onclick="control('createNode')">New Node</button>
<button onclick="control('deleteNode')">Delete Node</button>
<button onclick="control('renameNode')">Rename Node</button>
<button onclick="control('connect')">Connect</button>
<button onclick="control('disconnectNodes')">Disconnect</button>
<input id="a_input" size="4"/><input id="b_input" size="4"/>
<button onclick="printAll()">Show all</button>
<p>
<textarea id="textarea1" disabled rows=7 cols=50 align="right" style="float:left;margin:0px 10px 0px 0px;"></textarea>
<script>
function control(func) {
controller[func](a_input.value, b_input.value)
}
function redirect(url) {
window.open(url + location.hash)
}
</script>
This is a project to replace <a href="https://translate.google.com">
google.translate phrasebook</a> with decent editor, which
allows to place related words closely next to each other.
Result should look like <a href="http://www.visuwords.com">visuwords.com</a> but editable.
<p>
Graphs were <a href="http://www.spanishdict.com/answers/216673/mind-maps-for-increasing-vocabulary/blog/feed#a567676">
recommended for language learning</a> but no <a href="http://ell.stackexchange.com/questions/26060/obtaining-the-mind-maps-and-mapping-them-to-the-other-language">
english learners</a> are aware of such tool. I have discovered
that mind maps are actually tree builders whereas real word connections
admit cycles. I have was inflamed to build such tool myself.
</p>
You can edit the graph using the buttons on this page. Yet, <a style="font-size:200%" href="javascript:redirect('almende-vis.html?mode=normal')">
visual editor</a> was started. It is based on Almende example 21,
see below. I think that it has reached usable stage and
<a href="https://www.youtube.com/watch?v=PzOmyxiEnsI">
this video demonstrates what you should see</a>. Yet, it becomes
a mess (it is difficult to say where edge is connected to)
and drag at several hundred words.
<p>
I tried to overcome the difficulty exploiting a simple fact:
you can see only a limited amount of words on the screen.
There is no need to draw the full graph therefore. Rendering
only a small part of full dictionary should dramatically
reduce the mess and improve performance. Linguists address
this issue introducing the notion of <a href="http://en.wikipedia.org/wiki/Synonym_ring">
synonym ring or synset</a>.
<p>
Almende exploits this idea by <a href="http://visjs.org/examples/network/19_scale_free_graph_clustering.html">
clustering</a>. It basically collapses connected words into a group node.
See <a style="font-size:150%" href="javascript:redirect('almende-vis.html?mode=cluster')">
Clustered VisualDict</a> with clustered mode on. Almende
<a href="https://github.com/almende/vis/issues/696">
clusterting prevents navigating to specific words, though</a>.
That is, we insert words into the graph and maintain the list
of inserted words to enable text lookup of the words. Clicking
a word in the list navigates to the word in the graph. If Almende collapses
however the words into cluster, the words are removed from the
graph and this crucial functionality is broken. It is not even possible
to navigate to the word manually expanding the clusters --
you have no idea which cluster you need to open, likewise
you do not know which folder path to take to reach your goal
file.
<p>
I therefore have an idea to autoexpand nodes on (in place of) <a href="http://www.w3schools.com/tags/att_global_title.asp">
title/tooltip</a> event. You start with single node word, connected to expandable proxies/
placeholders. Once expanded, proxy is converted into normal nodes and
its connections show up as proxies. This way, you can unwind whole graph.
Here is the demo, <a style="font-size:150%" href="javascript:redirect('almende-vis.html?mode=partial')">
Partial VisualDict</a>. It was easy to achieve with Almende fortunately supporting
the title events on the nodes.
This idea of incremental graph visualization is similar to <a href="http://arborjs.org"> arborjs.org</a>
and <a href="http://maxdemarzi.com/2013/05/29/visualizing-the-news-with-vivagraph-js/">
VivaGraph (example below)</a> proposals. However, in contrast with them, displayed nodes
persist and you need to reload the page for restart.
<p>
Another planned feature is language differentiation (node color?).
Currently, related words are
enumerated through comma in the DB (comma is forbidden in
the words, therefore, though this may be wrong idea if we
are building a phrasebook rather than ordinary dictionary).
Nevertheless, so far, I think that words could
be stored with language prefix, like en:word and et:sõna
making
semicolon forbidden as well. Anyway, I have started the
<a href="javascript:redirect('options.html')">options</a>
page.
Might
be some integration with google translate is also required.
Supporting import of google-exported prasebook is required
for sure.
<hr>
Unlike most graph models, current graph model avoids
node/edge ids. Nodes are identified with words/labels. This
complicates renaming and might inflate DB size. Yet,
<a href="http://stackoverflow.com/questions/28196581/locking-in-google-realtime-db">
not all identifiers are shorter than natural words.</a>
<p>
Thanks to Google Drive Realtime API (<a href="http://valjok.blogspot.com/2015/01/cloud-storage.html">
how I have picked it</a>), you can
<a target="_blank" href="#">produce word nets collaboratively.</a>
Though, this might be an overkill and is not reliable at all
(can be corrupted due to concurrency, see link above) but
unavoidable with Google RT and enableds undo/redo for free.
The database is stored in VisualDict file your google drive.
You may rename it or copy it for backup and switch files
(trashed files are not visible for picking). Actually,
because <a href="http://stackoverflow.com/a/22362913/4275251">
Google realtime documents are not garbage-collected</a> and
there is 10 MB limit on document, we need app-generated
backup file which would export current graph into a fresh
file.
<p>
Alternatively,
we could use <a href="https://coderwall.com/p/duapqq/use-a-google-spreadsheet-as-your-json-backend">
Google Speadsheets as JSON backed</a>.
<hr>
Here is mine analysis of graph-drawing engines.<p>
<li>
<a href="javascript:redirect('cytoscape.html')">Cytoscape</a>
loads realtime data but fails to make connections. Cytoscape
seems good visualizer (now, I think it is not) and can layout
new nodes but it is unsatisfactory editor.</li><li>
<a href="javascript:redirect('graph-creator.html')">Graph Creator</a>
Thoug it does support "make connections" facility, it does not support automatic layout and
Integration with Realtime Model was not even started.</li>
<li>
I have later realized that I can connect nodes like this
https://dl.dropboxusercontent.com/u/4189520/GraphJS/graphjs.html
-- simply by selecting two nodes. It also worth to try web-cola
and <a href="javascript:redirect('vivagraph.html')">VivaGraphJS</a> in place of cytoscape. They seem to provide better
and be more "dynamic" layout with less verbose API.
<p> VivaGraph looks very nice and allows a lot of freedom
in drawing the objects. You can specify connections (links)
without nodes (nodes are added automatically).
However, events, eg. "hover" areachieved
by manual drawing of the objects, which I do not like.
This issue is further aggraviated by stupid API, where we have
to write Viva.Graph.svg('circle').attr('r', 10).attr("fill", "red")
<a href="https://github.com/anvaka/VivaGraphJS/issues/121#issue-55491353">
instead of Viva.Graph.svg('circle', {r:1, color:"red"})</a>.
<p>VivoGraph maintains <a href="http://anvaka.github.io/graph-drawing-libraries/#/all">
a list of graphical libraries</a>. <a href="http://anvaka.github.io/graph-drawing-libraries/#/library/dhotson_springy">
Springy</a> example seems the thing that we are lookig for. It howerver
drwas arrows (which might be confusing) and seems too dynamic
(<a href="https://github.com/anvaka/VivaGraphJS/issues/121#issuecomment-71645340">
use too much CPU resources</a>). But more static Cytoscape
is hardly a solution because its layout is too dumb.
</li>
<li>
<a href="javascript:redirect('almende-vis.html')">
almende_vis</a> and <a href="alchemy.html">Graph Alchemist</a>
address multiselect and stabilization in the examples: they
consuming CPU cycles) after a while. Almende network has
terrible multiselect behaviour: you must keep your finger on a node
to add it to selection. This is mobile-friendly but mine shift+click
is much more agile. Initially, I was also terrified with the <a href="view-source:http://almende.github.io/chap-links-library/js/network/examples/example12_adding_nodes.html">
API to add a node, which demanded creating intermediate tables
</a>. Yet, thanks to rich examples<a href="http://almende.github.io/vis/examples/network/16_dynamic_data.html">
(16 manual graph editor)</a> and <a href="http://almende.github.io/vis/examples/network/21_data_manipulation.html">
(21 visual graph editor)</a>, I have realized how they achieved
that and started using it as primary editor.
<p>
As alternative, for large graphs I considered Vivagraph with its blazing WebGL
performance. The stupid API is not the issue (<a href="https://github.com/anvaka/VivaGraphJS/issues/121#issuecomment-71645340">I could add the API myself</a>)
The API is more complex than Almende for another reason: I see
no way to render text nodes (let's ignore the ugly linear
edges, unlike truly physical Almende's ribbons). This <a href="https://github.com/anvaka/VivaGraphJS/issues/86#issuecomment-73383520">
seems plainly impossible. Although, <a href="http://stackoverflow.com/questions/28373796">
asking this at Stackexchange is banned</a>. <a href="http://meta.stackoverflow.com/questions/285545">
As usually.</a> Furthermore, even if I will be able to draw the whole graph,
it will be a mess on the screen. I therefore preferred the partial graph (or clustering)
as primary solution.
<p>
GrphAlchemist on the other hand might be a great library
but <a href="https://github.com/GraphAlchemist/Alchemy/issues/543">
it is impossible to start with</a>. The docs <a hre="https://github.com/GraphAlchemist/Alchemy/issues/343#issuecomment-71804741">
suck from the very beginning</a> and describe some inexisting
configuraion properties. At least I could not find what
<a href="http://graphalchemist.github.io/Alchemy/#/docs">
nodeCaption</a> applies to. When I try to pan my example,
it fails with Cannot read property 'conf' of undefined and
"Cannot read property 'vis' of undefined" in alchemy.min.js.
</li>
<p>
</body>
</html>