From 4a47e4ff0fd09bfe1086921563f817a7d4aa7264 Mon Sep 17 00:00:00 2001 From: saaj Date: Sun, 2 Nov 2025 12:41:21 +0100 Subject: [PATCH] Proofread --- Graph.md | 223 ++++++++++-------- ...lt-set-suitable-for-graph-visualisation.md | 72 +++--- 2 files changed, 161 insertions(+), 134 deletions(-) diff --git a/Graph.md b/Graph.md index b576b93..28b73d6 100644 --- a/Graph.md +++ b/Graph.md @@ -1,32 +1,34 @@ # Graph -Sqliteviz allows building a graph. To build a graph, run a query to get data. +Sqliteviz supports graph (network) visualisation. To build a graph, first run a query to get data. Then open the visualisation panel by clicking ![](./img/visualisation.svg) -in any of the two side toolbars and choose a graph mode by clicking ![](./img/graph.svg). +in any of the two-side toolbars and choose the graph mode by clicking ![](./img/graph.svg). ## Requirements for result set To build a graph, a result set must follow the following requirements: -- the first column must contain JSONs (the rest columns in the result set will be ignored) -- each JSON has a common key indicating if the record represents a node (value 0) or an edge (value 1) -- each JSON representing a node has a common key with a node id -- each JSON representing an edge has a common key with the edge source and a common key with the edge target +- the first column must contain JSON documents (subsequent columns in the result set are ignored) +- each JSON document has a key indicating whether the document represents a node/vertex (value `0`) + or an edge (value `1`) +- each JSON document representing a node has a key with the node/vertex id +- each JSON document representing an edge has a key with the edge source node/vertex and a key with + the edge target node/vertex -That is the minimum required for a graph, but each JSON can have more fields used in graph styling -(read [Graph styling](#graph-styling)). +That is what is the minimum required for a graph, but the JSON documents can have more fields used +in graph styling (read [Graph styling](#graph-styling)). See also an example in [How to get result set suitable for graph visualisation][1]. ## Graph structure -Start building a graph by setting a mapping from your records to nodes and edge properties. +Start building a graph by setting a mapping from your documents to node and edge properties. Go to `Structure` > `Graph` and set the following fields: -- Object type – a field containing 0 for node records and 1 for edge records. +- Object type – a field containing `0` for node documents and `1` for edge documents. - Node Id – a field containing the node identifier -- Edge source - a field keeping a node identifier where the edge starts. -- Edge target - a field keeping a node identifier where the edge ends. +- Edge source – a field keeping a node identifier where the edge begins. +- Edge target – a field keeping a node identifier where the edge ends. This is already enough to build a graph with default styling and circular layout. @@ -42,93 +44,105 @@ Set a background color of the graph in `Style` > `General` panel. There are the following settings in `Style` > `Nodes` panel: -- Label - a field containing a node label. Note that if the graph has too many nodes or the node size - is too small, some labels can be visible only at a certain zoom level. +- Label - a field containing the node label. Note that if the graph has too many nodes or the node + size is too small, some labels can be visible only at a certain zoom level. - Label Color - a color of node labels - Size - set a node size. There are 3 modes of node sizing: constant, variable and calculated. - `Constant` means that all nodes have the same size. - - `Variable` allows you to choose a field where the node size will be taken. - - `Calculated` allows to choose a method that will be used to calculate the node size. - Currently, 3 methods are available: total node degree, degree by in-edges and degree by out-edges. + * `Constant` means that all nodes have the same given size. + * `Variable` allows you to choose a field where the node size is taken from. + * `Calculated` allows you to choose a method that is used to calculate the node size. - For variable and calculated sizing it's also possible to set scale, the minimum size and the sizing mode - area or diameter. - In the diameter mode the difference between node sizes will be more noticeable. + Currently, 3 methods are available: total node degree, degree by in-edges and + degree by out-edges. + + For variable and calculated sizing it's also possible to set the scale, the minimum + size and the sizing mode - area or diameter. In the diameter mode the difference + between node sizes is more noticeable. - Color - set a node color. There are 3 modes of node color: constant, variable and calculated. - `Constant` means that all nodes have the same color. + * `Constant` means that all nodes have the same color. + * `Variable` allows you to choose a field by which the color is determined. + With this option you can also choose if the color value should be taken directly or mapped to a + color palette. + * `Direct` mode means that in the JSON document representing the node, the value in the selected + field is used as a color. The color value in the JSON document can be set in [different + ways][2]: + + 1. As Hex, 8-digit (RGBA) Hex: + + ``` + #000 + 000 + #369C + 369C + #f0f0f6 + f0f0f6 + #f0f0f688 + f0f0f688 + ``` + + 2. RGB, RGBA: + + ``` + rgb (255, 0, 0) + rgb 255 0 0 + rgba (255, 0, 0, .5) + { "r": 255, "g": 0, "b": 0 } + ``` + + 3. HSL, HSLA: + + ``` + hsl(0, 100%, 50%) + hsla(0, 100%, 50%, .5) + hsl(0, 100%, 50%) + hsl 0 1.0 0.5 + { "h": 0, "s": 1, "l": .5 } + ``` + + 4. HSV, HSVA: + + ``` + hsv(0, 100%, 100%) + hsva(0, 100%, 100%, .5) + hsv (0 100% 100%) + hsv 0 1 1 + { "h": 0, "s": 100, "v": 100 } + ``` + + 5. Named colors: - `Variable` allows you to choose a field by which the color will be determined. - With this option you can also choose if the color value should be taken directly or mapped to a color palette. - `Direct` mode means that in JSON representing a node, the value available by the selected field will be used as a color. - The color value in the JSON can be set in different ways: + Case insensitive names are accepted, using the list of [colors in the CSS + spec][3]. + + ``` + RED + blanchedalmond + darkblue + ``` - **As Hex, 8-digit (RGBA) Hex** - ``` - "#000" - "000" - "#369C" - "369C" - "#f0f0f6" - "f0f0f6" - "#f0f0f688" - "f0f0f688" - ``` - **RGB, RGBA** - ``` - "rgb (255, 0, 0)" - "rgb 255 0 0" - "rgba (255, 0, 0, .5)" - { "r": 255, "g": 0, "b": 0 } - ``` - - **HSL, HSLA** - ``` - "hsl(0, 100%, 50%)" - "hsla(0, 100%, 50%, .5)" - "hsl(0, 100%, 50%)" - "hsl 0 1.0 0.5" - { "h": 0, "s": 1, "l": .5 } - ``` - - **HSV, HSVA** - ``` - "hsv(0, 100%, 100%)" - "hsva(0, 100%, 100%, .5)" - "hsv (0 100% 100%)" - "hsv 0 1 1" - { "h": 0, "s": 100, "v": 100 } - ``` - - **Named colors** - - Case insenstive names are accepted, using the list of [colors in the CSS spec][3]. - ``` - "RED" - "blanchedalmond" - "darkblue" - ``` - - When `Map to` option is selected, the value by the selected field can be anything because it won't be used directly as a color. - In this case each distinct value will be mapped to a certain color, so nodes with the same value will have the same color. - Click on a color palette to open a palette selector. + When `Map to` option is selected, the value by the selected field can be anything because it + won't be used directly as a color. In this case each distinct value will be mapped to a certain + color, so nodes with the same value will have the same color. Click on a color palette to open a + palette selector. `Calculated` color mode allows to choose a method that will be used to determine a color. - Currently, 3 methods are available: total node degree, degree by in-edges and degree by out-edges. You can also choose a color palette - that will be used in a mapping of calculated values into an actual color. + Currently, 3 methods are available: total node degree, degree by in-edges and degree by + out-edges. You can also choose a color palette that will be used in a mapping of calculated + values into an actual color. - Color As - defines how color mapping should work - continuously or categorically. - Continuous mode is more suitable when the mapped values have a meaningful order. It looks more informative with sequential palettes. - In that case the lowest value corresponds to the first color in the palette and the highest value - to the last color. - The color of each intermediate value reflects the position of that value in the range. + Continuous mode is more suitable when the mapped values have a meaningful order. It looks more + informative with sequential palettes. In that case the lowest value corresponds to the first + color in the palette and the highest value - to the last color. The color of each intermediate + value reflects the position of that value in the range. - Categorical mode just uses the next color in the palette for each new distinct value. + Categorical mode just uses the next color in the palette for each new distinct value. -- Colorscale Direction - use a selected palette as is or reverse it. +- Colorscale Direction - use the selected palette as is or reverse it. ### Edges @@ -140,46 +154,51 @@ There are the following settings in `Style` > `Edges` panel: - Label Color - a color of edge labels - Size - set an edge thickness. There are 2 modes of edge sizing: constant and variable. - `Constant` means that all edges have the same thickness. + * `Constant` means that all edges have the same thickness. + * `Variable` allows you to choose a field where the edge size is taken from. + + For variable sizing it's also possible to set the scale and the minimum size. - `Variable` allows you to choose a field where the edge size will be taken. +- Color - set an edge color. There are 2 modes of edge color: constant and variable. They work + similar to the node color modes. - For variable sizing it's also possible to set scale and the minimum size. - -- Color - set an edge color. There are 2 modes of edge color: constant and variable. They work similar to node color modes. +- Color As - defines how color mapping should work - continuously or categorically, similar to the + node color setting. -- Color As - defines how color mapping should work - continuously or categorically, similar to the same node color setting. - -- Colorscale Direction - use a selected palette as is or reverse it. +- Colorscale Direction - use the selected palette as is or reverse it. ### Layout #### Circular + In this layout all nodes are just placed along a circle. #### Random -This layout places nodes randomly for each seed value. The seed value allows you to restore the random layout you liked -when you open the inquiry and run the query next time. + +This layout places nodes randomly for each seed value. The seed value allows you to restore the +random layout you liked when you open the inquiry and run the query next time. ![Fig. 2: Random layout](./img/Screenshot_graph_random.png) #### Circle pack -Arranges nodes as a bubble chart according to specified attributes. You can choose multiple hierarchy attributes used to group nodes. + +Arranges nodes as a bubble chart according to specified attributes. You can choose multiple +hierarchy attributes to group nodes. ![Fig. 3: Circle pack layout](./img/Screenshot_graph_circle_pack.png) #### ForceAtlas2 -A continuous graph layout algorithm. Read more details about the algorithm and its settings in the [article][4]. -The algorithm works in iterations. When you choose ForceAtlas2 layout or run the query, it will automatically run 50 iterations of the algorithm. -You can change the amount of steps run automatically in `Initial Iterations`. -You can also run and stop the algorithm manually by clicking `Start`/`Stop` button. + +A continuous graph layout algorithm. Read more details about the algorithm and its settings in the +[article][4]. The algorithm works iteratively. When you choose ForceAtlas2 layout or run the query, +it is automatically run 50 iterations of the algorithm. You can change the amount of steps run +automatically in `Initial Iterations`. You can also run and stop the algorithm manually by +clicking `Start`/`Stop` button. ![Fig. 3: ForceAtlas2 layout](./img/Screenshot_graph_force_atlas2.png) -[How to build a pivot table in SQL(ite)][1] explores two options with static -(or beforehand-known) and dynamic columns. + [1]: ./How-to-get-result-set-suitable-for-graph-visualisation -[2]: https://github.com/bgrins/TinyColor?tab=readme-ov-file#accepted-string-input +[2]: https://github.com/bgrins/TinyColor/blob/d5ad0c6/README.md#accepted-string-input [3]: https://www.w3.org/TR/css-color-4/#named-colors [4]: https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0098679 - diff --git a/How-to-get-result-set-suitable-for-graph-visualisation.md b/How-to-get-result-set-suitable-for-graph-visualisation.md index 02b7df2..414a831 100644 --- a/How-to-get-result-set-suitable-for-graph-visualisation.md +++ b/How-to-get-result-set-suitable-for-graph-visualisation.md @@ -1,33 +1,37 @@ -# How to get result set suitable for graph visualisation +# How to get a result set suitable for graph visualisation -There are some [requirements for result sets][1] if you want to build a graph. -Here is an example of building a query that returns a result set appropriate for graph visualisation. +There are some [requirements for result sets][1] if you want to make a graph. +Here is an example of building a query that returns a result set appropriate for graph +visualisation. Let's say, you have 2 tables: -house: -| name | points | -| ---------- | ------ | -| Gryffindor | 100 | -| Hufflepuff | 90 | -| Ravenclaw | 95 | -| Slytherin | 80 | +1. `house`: -student: -| id | name | house | -| -- | -------------- | ---------- | -| 1 | Harry Potter | Gryffindor | -| 2 | Ron Weasley | Gryffindor | -| 3 | Draco Malfoy' | Slytherin | -| 4 | Luna Lovegood | Ravenclaw | -| 5 | Cedric Diggory | Hufflepuff | + | name | points | + | ---------- | ------ | + | Gryffindor | 100 | + | Hufflepuff | 90 | + | Ravenclaw | 95 | + | Slytherin | 80 | + +2. `student`: + + | id | name | house | + | -- | -------------- | ---------- | + | 1 | Harry Potter | Gryffindor | + | 2 | Ron Weasley | Gryffindor | + | 3 | Draco Malfoy' | Slytherin | + | 4 | Luna Lovegood | Ravenclaw | + | 5 | Cedric Diggory | Hufflepuff | Each student belongs to a certain house. -Let's say you want to build a graph with houses and students as nodes, where each house is linked with its students. +Let's say you want to build a graph with houses and students as nodes, where each house is linked +with its students. -We are going to use [json_object][2] function to form JSONs. The result set should contain both nodes and edges -and we have to provide a field indicating if the record represents a node (0) or and edge (1). -Let's provide it as 'object_type': +We are going to use [json_object][2] function to form JSON documents. The result set should contain +both nodes and edges and we have to provide a field indicating if the document represents a node +(0) or and edge (1). Let's provide it as `object_type`: ```sql SELECT json_object('object_type', 0) @@ -39,11 +43,13 @@ UNION ALL SELECT json_object('object_type', 1) FROM student ``` -Note that we included `student` table twice. That is because the table contains not only students but also their relationship to houses. -So the records from the first union of `student` will be used as nodes and from the second one - as edges. -Then we need to provide an ID for each node. Let's put it in `node_id` field. -The `node_id` value for students is taken from `id` column and for houses - from `name`: +Note that we included `student` table twice. That is because the table contains not only students +but also their relationship to houses. So the records from the first union of `student` are used +as nodes and from the second one - as edges. + +Then we need to provide an ID for each node. Let's put it in `node_id` field. The `node_id` value +for students is taken from `id` column and for houses - from `name`: ```sql SELECT json_object('object_type', 0, 'node_id', name) @@ -56,7 +62,8 @@ SELECT json_object('object_type', 1) FROM student ``` -Each edge record must provide a node id where the edge starts and where it ends. Let's put it in `source` and `target`: +Each edge document must provide a node id where the edge begins and where it ends. Let's put it in +`source` and `target`: ```sql SELECT json_object('object_type', 0, 'node_id', name) @@ -68,12 +75,13 @@ UNION ALL SELECT json_object('object_type', 1, 'source', house, 'target', id) FROM student ``` -Basically, that is enough to build a graph. But it won't be meaningful without labels. + +Basically, that is enough to build a graph. But it is not very meaningful without labels. Also, it would be nice to distinguish house nodes from student nodes by color. Let's put additional fields `label` and `type` that can be used in graph styling. ```sql -SELECT json_object('object_type', 0, 'node_id', name, 'label', name, 'type', 'house') +SELECT json_object('object_type', 0, 'node_id', name, 'label', name, 'type', 'house') AS graph_object FROM house UNION ALL SELECT json_object('object_type', 0, 'node_id', id, 'label', name, 'type', 'student') @@ -85,7 +93,7 @@ FROM student Run the query, the result set will look like this: -| json_object('object_type', 0, 'node_id', name, 'label', name, 'type', 'house') | +| graph_object | | ------------------------------------------------------------------------------ | | {"object_type":0,"node_id":"Gryffindor","label":"Gryffindor","type":"house"} | | {"object_type":0,"node_id":"Hufflepuff","label":"Hufflepuff","type":"house"} | @@ -102,8 +110,8 @@ Run the query, the result set will look like this: | {"object_type":1,"node_source":"Ravenclaw","target":4} | | {"object_type":1,"node_source":"Hufflepuff","target":5} | -Now in the graph editor, we can set mapping of the result set records into node and edge properties, -set graph styles and get the following visualisation: +Now in the graph editor, we can set mapping of the result set documents into node and edge +properties, set graph styles and get the following visualisation: ![Fig. 1: Graph visualisation example](./img/Screenshot_potter_example.png)