My contribution to the Google Summer of Code 2016
August 21st, 2016
At first I was given raw source code code of ccNetViz so I created the whole project ecosystem from scratch. This included:
- Separating library classes into different namespaces and making the build system using webpack under the node.js
- Creating live examples of all the supported features (see Advanced styling, Complex graphs, User definied layout)
- Creating an ecosystem for unit and performance testing
Then I was given the task to implement a performance-optimized search of nodes and edges (see find() and findArea() methods in the project github page). I implemented it over the wonderful spatialsearch library RBush written by Vladimir Agafonkin. The whole idea about efficiency is to use the library efficiency for all searched nodes based on a rectangular bounding box (calculated for each element in the space of nodes and edges). At the end I had to do precise computations for each discovered element to see if it is in the desired area. This computations was the hardest part of work do because it involved simulation of all mathematic operations done in the WebGL shaders. It also involved some analytic-geometry skills to compute intersections between objects (which were not so easy for bezier curves :) ).
The next part of work was to create unit tests for search functions. It also involved creating perfomance tests for testing the efficiency of the whole library.
After that I implemented the support of interactivity to the library. Because of the performance-oriented origin of the library, everything has to be fast. We decided to separate the library into two layers which would be drawn over each other. We call those two the main layer and the temporary layer. When you remove a node, it is removed from the main just by updating a small part of memory in GPU so everything is fast. Adding new nodes is also fast because every new node is inserted into the relatively small temporary layer. Update functions are implemented in the way, that they are removed and after that inserted into graph. I also implemented the reflow() method to convert and save dynamic changes into the static graph. If the user knows that there will not be any significant changes in the graph, they can call this method which allows them to keep time-complexity of interactivity functions small.
As the creation of layer allowed us to separate graph displaying and functionality, I decided to create the support for multiple levels of graph (dephtness).
see the live example
In the end I impelemented the support of edges-to-edges. This involved a lot of modifications inside the WebGL shaders. It also affected the searching functions so I had to add support of this functionality into search too.
see the live example
There were also many other small tasks. For example the support of different styles (dashed / dotted / straight) of lines. Bugfixes :) , etc...