├── .gitignore
├── README.md
├── docs
├── composition.md
├── data.md
├── genome-builds.md
├── getting-started.md
├── mark.md
├── public-datasets.md
├── semantic-zoom.md
├── user-interaction.md
└── visual-channel.md
├── images
├── alignment.png
├── area_example.png
├── bar_example.png
├── layout_demo.png
├── line_example.png
├── linear_circular.png
├── link_example.png
├── logo.png
├── multi_views.png
├── point_example.png
├── rect_example.png
├── semantic_zoom_0.png
├── semantic_zoom_1.png
├── semantic_zoom_2.png
├── semantic_zoom_3.png
├── text_example.png
├── tutorial
│ ├── tutorial_0.gif
│ ├── tutorial_0.png
│ ├── tutorial_circular.png
│ ├── tutorial_dataTransform.png
│ ├── tutorial_detail_view1.png
│ ├── tutorial_multi_track.png
│ ├── tutorial_multi_views.gif
│ ├── tutorial_overlay.png
│ ├── tutorial_style.png
│ └── tutorial_text_label.png
├── with_row.png
├── without_row.png
└── x_x1_example.png
└── tutorials
├── create-multi-track-visualization.md
├── create-multi-view-visualization.md
└── create-single-track-visualization.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pptx
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Gosling.js Documentation
2 |
3 |
4 |
5 | [Gosling.js](https://github.com/gosling-lang/gosling.js) is a declarative grammar for interactive (epi)genomics visualization on the Web.
6 |
7 | ### The Docs and Interactive Tutorials are now hosted at http://gosling-lang.org/
8 |
25 |
26 |
--------------------------------------------------------------------------------
/docs/composition.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Composition
3 | ---
4 |
5 |
6 | A **track** is a unit building block in Gosling which can be represented as a bar chart, a line chart, or an ideogram. For the concurrent analysis of multiple datasets, multiple tracks can be grouped into **views** and navigated synchronously. In other words, a view defines the genomic location for all the tracks it contains, and the tracks define the data to be visualized.
7 |
8 |
9 |
10 |
11 |
12 |
13 | In Gosling, you can compose multiple tracks and views in diverse ways using the following properties:
14 |
15 | 1. You can display genomic positions of a view either in Cartesian coordinates (**linear**) or in polar coordinates (**circular**) using the `layout` property.
16 | 2. You can determine to either **overlay** or **stack** multiple tracks when composing them into a view using a `alignment` property.
17 | 3. You use juxtapose multiple views in four different ways (i.e., **parallel**, **serial**, **vertical**, **horizontal**) using the `arrangement` property.
18 |
19 | ```javascript
20 | {
21 | "arrangement": "parallel"// how to arrange multiple views
22 | "views": [
23 | {
24 | // a single view can contain multiple tracks
25 | "layout": "circular", // specify the layout of a view
26 | "alignment": "stack", // specify how to align several tracks
27 | "tracks": [
28 | {/** track 1 **/},
29 | {/** track 2 **/},
30 | ...
31 | ]
32 | },
33 | {
34 | /** another view **/
35 | }
36 | ...
37 | ]
38 | }
39 | ```
40 |
41 |
42 | - [Specify the View Layout](#specify-the-view-layout)
43 | - [Align Multiple Tracks in One View](#align-multiple-tracks-in-one-view)
44 | - [Arrange Multiple Views](#arrange-multiple-views)
45 | - [Inherit Property in Nested Structure](#inherit-property-in-nested-structure)
46 |
47 |
48 | ## Specify the View Layout
49 |
50 | In each view, genomic coordinate can be represented in either a **circular** or **linear** layout.
51 |
52 | In the following figure the upper track is using a linear layout while the bottom one is a circular layout.
53 |
54 |
55 |
56 | Users can either specify the layout of all views in the root level
57 |
58 | ```javascript
59 | {
60 | "layout": "linear", //specify the layout of all views
61 | "views":[...]
62 | }
63 | ```
64 |
65 | or specify/override the layout of a certain view in its own definition
66 |
67 | ```javascript
68 | {
69 | "layout": "linear", //specify the layout of all tracks in this view
70 | "tracks":[...]
71 | }
72 | ```
73 |
74 | To enable an easy switch, both `linear` and `circular` layout can be specified through `width` and `height`.
75 | **Note:** the meaning of `height` is different in `circular` and `linear` layout.
76 | A `linear` layout is controlled by the following properties:
77 |
78 | | property | type | description |
79 | | -------- | ------ | ----------------------------- |
80 | | width | number | width (in pixel) of the view |
81 | | height | number | height (in pixel) of the view |
82 |
83 | A `circular` layout is controlled by the following properties:
84 |
85 | | property | type | description |
86 | | ------------ | ------ | ------------------------------------------------------------------------------- |
87 | | width | number | width (in pixel) of the view |
88 | | height | number | you need to specify the height of each track to control the ratio of their ticknesses |
89 | | centerRadius | number | `radius of the center white space` / `radius of the whole view`. default = 0.3 |
90 |
91 |
98 |
99 |
100 | ## Align Multiple Tracks in One View
101 |
102 |
103 | The `alignment` propoerty allow users to either `"overlay"` or `"stack"` several tracks.
104 |
105 |
106 | When setting `alignment` as `"overlay"`, multiple `tracks` are overlaid on top of others.
107 | When setting `alignment` as `"stack"`, multiple `tracks` are vertically concantenated.
108 | The default value of `alignment` is `"stack"`.
109 |
110 |
111 |
112 | Multiple `tracks` can compose one single `view`, which has the following properties:
113 |
114 | | property | type | description |
115 | | ------------ | ------- | ------------|
116 | | layout | string | specify the layout type of all tracks, either "linear" or "circular" |
117 | | alignment | string | specify how to align tracks, either "stack" or "overlay". default="stack"|
118 | | spacing | number | specify the space between tracks in pixels (if `layout` is `linear`) or in percentage ranging from `0` to `100` (if `layout` is `circular`) |
119 | | static | boolean | whether to disable [Zooming and Panning](https://github.com/gosling-lang/gosling-docs/blob/master/docs/user-interaction.md#zooming-and-panning), default=false. |
120 | | assembly | string | currently support "hg38", "hg19", "hg18", "hg17", "hg16", "mm10", "mm9" |
121 | | linkingId | string | specify an ID for [linking multiple views](https://github.com/gosling-lang/gosling-docs/blob/master/docs/user-interaction.md#linking-views) |
122 | | centerRadius | number | specify the proportion of the radius of the center white space. A number between [0,1], default=0.3 |
123 | | width | number | required when setting `alignment: overlay` |
124 | | height | number | required when setting `alignment: overlay` |
125 |
126 |
127 |
128 | ## Arrange Multiple Views
129 | Goslings supports multi-view visualizations. How multiple views are arranged is controlled by the `arrangement` property.
130 | ```javascript
131 | {
132 | "arrangement": "parallel",
133 | "views": [
134 | // one view is composed of tracks that share the same layout property (linear or circular)
135 | {
136 | "layout": "linear",
137 | "tracks": [...]
138 | },
139 | // One view can have a hierarchical structure.
140 | // For example, the view below is composed of two sub-views
141 | {
142 | "arrangement": "serial",
143 | "views": [
144 | {
145 | "tracks": [...]
146 | },
147 | {
148 | "tracks": [...]
149 | }
150 | ]
151 | }
152 | ]
153 | }
154 | ```
155 |
156 | Gosling supports four types of arrangemet: `"parallel"`, `"serial"`, `"vertical"`, `"horizontal"`.
157 |
158 |
159 |
160 | ## Inherit Property in Nested Structure
161 |
162 | Both `view` and `track` supports nested structures: One `view` can have several children `views`, and one `track` can have several children `tracks`. Properties can be inherited from upper-level specifications or overwritten locally.
163 |
164 | ```javascript
165 | // nested structures in views
166 | {
167 | "arrangement": "parallel",
168 | "views": [
169 | {/** view **/ },
170 | {/** view **/ },
171 | {
172 | // a view with children views
173 | "arrangement": "parallel",
174 | "views": [...]
175 | }
176 | ]
177 | }
178 | ```
179 |
180 | ```javascript
181 | // nested structures in tracks
182 | {
183 | "alignment":"overlay",
184 | "tracks": [
185 | {
186 | // the parent track
187 | "data": ... , // specify data
188 | "x": ...,
189 | "y": ...,
190 | "color":...,
191 | "alignment": "overlay",
192 | "tracks": [
193 | // the children tracks
194 | // point mark and line mark have the same data, x, y, color encoding
195 | {
196 | "mark": "line",
197 | },
198 | {
199 | "mark": "point",
200 | // specify the size of point mark
201 | "size": {"field": "peak", "type": "quantitative", "range": [0, 6]}
202 | }
203 | ]
204 | }
205 | ]
206 | }
207 | ```
208 |
209 | Use the nested structure if you want to use overlaid tracks inside stacked tracks.
210 |
211 |
212 | Try examples in the online editor:
213 |
214 | [Line chart (line + point)]()
215 |
216 | [Lollipop plot (bar + point)]()
217 |
218 | [Ideogram (text + rect + triangle)]()
219 |
--------------------------------------------------------------------------------
/docs/data.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Data
3 | ---
4 | Users can specify the data of each visualization (i.e., `track`) through a `track.data` property.
5 | ```javascript
6 | {
7 | "tracks":[{
8 | "data": {...}, // specify the data used in this track
9 | "mark": "rect",
10 | "color": ...,
11 | ...
12 | }]
13 | }
14 | ```
15 |
16 | - [Supported Data Formats](#supported-data-formats)
17 | - [Plain Datasets (No HiGlass Server)](#plain-datasets-no-higlass-server)
18 | - [CSV](#csv)
19 | - [JSON](#json)
20 | - [BigWig](#bigwig)
21 | - [Pre-aggregated Datasets (HiGlass Server)](#pre-aggregated-datasets-higlass-server)
22 | - [Vector](#vector)
23 | - [Multivec](#multivec)
24 | - [BEDDB](#beddb)
25 | - [Data Transform](#data-transform)
26 |
27 | ## Supported Data Formats
28 |
29 | For the flexible data exploration, Gosling supports two different kinds of datasets:
30 |
31 | 1. **Plain Datasets** (No HiGlass Server): These datasets can be directly used in Gosling without requiring any data preprocessing.
32 |
33 | 2. **Pre-aggregated Datasets** (HiGlass Server): These datasets are preprocessed for the scalable data exploration and require a HiGlass server to access them in Gosling. To learn more about preprocessing your data and setting up the server, please visit the [HiGlass website](https://docs.higlass.io/).
34 |
35 | ### Plain Datasets (No HiGlass Server)
36 | These datasets can be directly used in Gosling without requiring any data preprocessing.
37 |
38 | #### CSV
39 |
40 | Any small enough tabular data files, such as tsv, csv, BED, BEDPE, and GFF, can be loaded using `"csv"` data specification.
41 |
42 | ```javascript
43 | {
44 | "tracks": [
45 | {
46 | "data": {
47 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
48 | "type": "csv",
49 | "chromosomeField": "Chromosome",
50 | "genomicFields": ["chromStart", "chromEnd"]
51 | },
52 | ...,
53 | }]
54 | }
55 |
56 | ```
57 |
58 |
59 | | property | type | description |
60 | | ------------------ | -------- | ------------------------------------------------------------ |
61 | | type | string | **required**, `"csv"` for CSV files |
62 | | url | string | **required**, specify the URL address of the data file |
63 | | separator | string | specify file separator, default=',' |
64 | | sampleLength | number | specify the number of rows loaded from the url. default=1000 |
65 | | chromosomeField | string | specify the name of chromosome data fields |
66 | | quantitativeFields | string[] | specify the name of quantitative data fields |
67 | | genomicFields | string[] | specify the name of genomic data fields |
68 | | headerNames | string[] | specify the names of data fields if a CSV file is headerless |
69 |
70 | #### JSON
71 |
72 | This format allows to include data directly in the Gosling's JSON specification.
73 |
74 | ```javascript
75 | {
76 | "tracks":[{
77 | "data": {
78 | "type": "json",
79 | "chromosomeField": "Chromosome",
80 | "genomicFields": [
81 | "chromStart",
82 | "chromEnd"
83 | ]
84 | "values": [
85 | {
86 | "Chromosome": "chr1",
87 | "chromStart": 0,
88 | "chromEnd": 2300000,
89 | "Name": "p36.33",
90 | "Stain": "gneg"
91 | },
92 | {
93 | "Chromosome": "chr1",
94 | "chromStart": 2300000,
95 | "chromEnd": 5300000,
96 | "Name": "p36.32",
97 | "Stain": "gpos25"
98 | }
99 | .....
100 | ]
101 | },
102 | ... // other configurations of this track
103 | }]
104 | }
105 | ```
106 |
107 | | property | type | description |
108 | | ------------------ | --------------------------------- | ------------------------------------------------------------ |
109 | | type | string | **required**, `"json"` for JSON files |
110 | | values | {[key:string]:number \| string}[] | **required**, values in the form of JSON |
111 | | sampleLength | number | specify the number of rows loaded from the url. default=1000 |
112 | | quantitativeFields | string[] | specify the name of quantitative data fields |
113 | | chromosomeField | string | specify the name of chromosome data fields |
114 | | genomicFields | string[] | specify the name of genomic data fields |
115 |
116 | #### BigWig
117 |
118 | ```javascript
119 | {
120 | "tracks":[{
121 | "data": {
122 | "url": 'https://s3.amazonaws.com/gosling-lang.org/data/4DNFIMPI5A9N.bw',
123 | "type": "bigwig",
124 | "column": "position",
125 | "value": "peak"
126 | },
127 | ... // other configurations of this track
128 | }]
129 | }
130 | ```
131 |
132 |
133 | | property | type | description |
134 | | -------- | ------ | ------------------------------------------------------ |
135 | | type | string | **required**, `"bigwig"` |
136 | | url | string | **required**, specify the URL address of the data file |
137 | | column | string | **required**, assign a field name of the middle position of genomic intervals |
138 | | value | string | **required**, assign a field name of quantitative values |
139 | | binSize | number | specifiy the genomic interval |
140 | | start | string | assign a field name of the start position of genomic intervals |
141 | | end | string | assign a field name of the end position of genomic intervals |
142 |
143 | ### Pre-aggregated Datasets (HiGlass Server)
144 | These datasets are preprocessed for the scalable data exploration and require a HiGlass server to access them in Gosling. To learn more about preprocessing your data and setting up the server, please visit the [HiGlass website](https://docs.higlass.io/).
145 |
146 |
147 | #### Vector
148 |
149 | One-dimensional quantitative values along genomic position (e.g., bigwig) can be converted into HiGlass' `"vector"` format data. Find out more about this format at [HiGlass Docs](https://docs.higlass.io/data_preparation.html#bigwig-files).
150 |
151 | ```javascript
152 | {
153 | "tracks":[{
154 | "data": {
155 | "url": 'https://resgen.io/api/v1/tileset_info/?d=VLFaiSVjTjW6mkbjRjWREA',
156 | "type": "vector",
157 | "column": "position",
158 | "value": "peak"
159 | },
160 | ... // other configurations of this track
161 | }]
162 | }
163 | ```
164 |
165 |
166 | | property | type | description |
167 | | -------- | ------ | ------------------------------------------------------ |
168 | | type | string | **required**, `"vector"` |
169 | | url | string | **required**, specify the URL address of the data file |
170 | | column | string | **required**, assign a field name of the middle position of genomic intervals |
171 | | value | string | **required**, assign a field name of quantitative values |
172 | | binSize | number | specify the genomic interval |
173 | | start | string | assign a field name of the start position of genomic intervals |
174 | | end | string | assign a field name of the end position of genomic intervals |
175 |
176 | #### Multivec
177 |
178 | Two-dimensional quantitative values, one axis for genomic coordinate and the other for different samples, can be converted into HiGlass' `"multivec"` data. For example, multiple BigWig files can be converted into a single multivec file. You can also convert sequence data (FASTA) into this format where rows will be different nucleotide bases (e.g., A, T, G, C) and quantitative values represent the frequency. Find out more about this format at [HiGlass Docs](https://docs.higlass.io/data_preparation.html#multivec-files).
179 |
180 | ```javascript
181 | {
182 | "tracks":[{
183 | "data": {
184 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
185 | "type": "multivec",
186 | "row": "sample",
187 | "column": "position",
188 | "value": "peak",
189 | "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
190 | },
191 | ...// other configurations of this track
192 | }]
193 | }
194 | ```
195 |
196 | | property | type | description |
197 | | ---------- | -------- | ------------------------------------------------------ |
198 | | type | string | **required**, `"multivec"` |
199 | | url | string | **required**, specify the URL address of the data file |
200 | | column | string | **required**, assign a field name of the middle position of genomic intervals |
201 | | value | string | **required**, assign a field name of quantitative values |
202 | | row | string | **required**, assign a field name of samples |
203 | | categories | string[] | **required**, assign names of individual samples |
204 | | binSize | number | specify the genomic interval |
205 | | start | string | assign a field name of the start position of genomic intervals |
206 | | end | string | assign a field name of the end position of genomic intervals |
207 |
208 | #### BEDDB
209 | Regular BED, or similar, files can be pre-aggregated for the scalable data exploration. Find our more about this format at [HiGlass Docs](https://docs.higlass.io/data_preparation.html#bed-files).
210 |
211 | ```javascript
212 | {
213 | "tracks":[{
214 | "data": {
215 | "url": "https://higlass.io/api/v1/tileset_info/?d=OHJakQICQD6gTD7skx4EWA",
216 | "type": "beddb",
217 | "genomicFields": [
218 | {"index": 1, "name": "start"},
219 | {"index": 2, "name": "end"}
220 | ],
221 | "valueFields": [
222 | {"index": 5, "name": "strand", "type": "nominal"},
223 | {"index": 3, "name": "name", "type": "nominal"}
224 | ],
225 | "exonIntervalFields": [
226 | {"index": 12, "name": "start"},
227 | {"index": 13, "name": "end"}
228 | ]
229 | },
230 | ... // other configurations of this track
231 | }]
232 | }
233 | ```
234 |
235 | | property | type | description |
236 | | ------------------ | -------------------------------------------------------------------- | ------------------------------------------------------ |
237 | | type | string | **required**, `"beddb"` |
238 | | url | string | **required**, specify the URL address of the data file |
239 | | genomicFields | { index: number; name: string }[] | **required**, specify the name of genomic data fields |
240 | | valueFields | { index: number; name: string; type: 'nominal' \| 'quantitative' }[] | specify the column indexes, field names to assign, and field types |
241 |
242 |
243 |
244 | ## Data Transform
245 | Gosling supports data transform through a set of data filters.
246 | Only data points that pass the tests in all filters will be visualized.
247 |
248 |
249 | ```javascript
250 | {
251 | "tracks":[{
252 | "data": ...,
253 | // only use data whose type is 'gene' and whose strand is NOT '+'
254 | "dataTransform": {
255 | "filter": [
256 | { "field": "type", "oneOf": ["gene"] },
257 | { "field": "strand", "oneOf": ["+"], "not": true }
258 | ]
259 | },
260 | "mark": "rect",
261 | ...,
262 | }]
263 | }
264 | ```
265 |
266 | Users can apply three types of filters: `oneOf`, `inRange`, `include`.
267 | One filter has the following properties:
268 |
269 | | property | type | description |
270 | | -------- | -------------------- | ------------------------------------------------------------------------------------ |
271 | | field | string | **required**, a filter is applied based on the values of the specified data field |
272 | | inRange | number[] | check whether the value is in a number range |
273 | | oneOf | string[] \| number[] | check whether the value is an element in the provided list |
274 | | include | string | check whether the value includes a substring |
275 | | not | boolean | when `not = true`, apply a NOT logical operation to the filter test. default = false |
276 |
277 | Apart from filters, users can aggregate data values (min, max, bin, mean, and count). [Read more about data aggregation](#x)
278 |
--------------------------------------------------------------------------------
/docs/genome-builds.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Genome Builds
3 | ---
4 | You can specify genome builds through an `assembly` property (default: `"hg38"`).
5 |
6 | ```typescript
7 | {
8 | "assembly": "hg38", // Globally define assembly to all tracks except ones that specify a certain assembly
9 | "tracks": [{
10 | ..., "assembly": "hg19" // Use a different assembly for this track
11 | }],
12 | ...
13 | }
14 | ```
15 |
16 | Gosling currently supports the following six genome builds: `hg38`, `hg19`, `hg17`, `hg16`, `mm10`, and `mm9`.
--------------------------------------------------------------------------------
/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Getting Started
3 | slug: /
4 | ---
5 | We currently support the following ways of using Gosling.
6 | - [Create Your Visualization in Gosling Online Editor](#create-your-visualization-in-gosling-online-editor)
7 | - [Load a Gosling Spec From Your Github Gist](#load-a-gosling-spec-from-your-github-gist)
8 | - [Embed Gosling Component in a HTML File](#embed-gosling-component-in-a-html-file)
9 | - [Use Gosling.js in React App](#use-goslingjs-in-react-app)
10 | - [Resources](#resources)
11 |
12 | ## Create Your Visualization in Gosling Online Editor
13 | You can visit [Online Editor](https://gosling.js.org) to visualize your data directly in the website.
14 |
15 | ## Load a Gosling Spec From Your Github Gist
16 | 1. To load a spec you first have to create a gist with a file named gosling.js* that specifies the spec.
17 | 1. You can additionally specify a readme.md file to describe your spec.
18 | 1. Also be sure to give your gist a fabulous title. It'll be shown in the gosling editor.
19 | You can then open your visualization at http:///?gist=/.
20 | For example, https://gosling.js.org/?gist=flekschas/e6e388332814886d4d714efd0e88093b
21 |
22 | ## Embed Gosling Component in a HTML File
23 | ```html
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
59 |
60 | ```
61 |
62 | ## Use Gosling.js in React App
63 |
64 | Install `gosling.js` and its dependent libraries:
65 |
66 | ```sh
67 | yarn add gosling.js pixi.js react@16.13.1 react-dom@16.13.1
68 | ```
69 |
70 | Add the following style sheets to your base `html` file:
71 | ```html
72 |
73 | ...
74 |
75 |
76 |
77 | ```
78 |
79 | Use the Gosling.js' react component to visualize your data:
80 |
81 | ```js
82 | import { validateGoslingSpec, GoslingComponent } from "gosling.js";
83 |
84 | ...
85 |
86 | // validate the spec
87 | const validity = validateGoslingSpec(EXMAPLE_GOSLING_SPEC);
88 |
89 | if(validity.state === 'error') {
90 | console.warn('Gosling spec is invalid!', validity.message);
91 | return;
92 | }
93 |
94 | ...
95 |
96 | function App() {
97 |
98 | ...
99 |
100 | return (
101 | { /* Callback function when compiled */ }}
104 | />
105 | );
106 | }
107 | ```
108 |
109 | Please visit [gosling-react](https://github.com/gosling-lang/gosling-react) for more detailed instruction. Also, visit [gosling-api-example](https://github.com/gosling-lang/gosling-api-example) to learn more about Gosling.js APIs, such as quick navigation to particular genes with animated transition.
110 |
111 | ## Resources
112 | - How to set up your own HiGlass server for private data exploration?
113 | - HiGlass Server: https://github.com/higlass/higlass-server
114 | - HiGlass Docker: https://github.com/higlass/higlass-docker
115 | - How to prepare your own HiGlass data?
116 | - HiGlass docs for data preparation: https://docs.higlass.io/data_preparation.html
117 |
--------------------------------------------------------------------------------
/docs/mark.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Mark
3 | ---
4 | Visual marks (e.g., points, lines, and bars) are the basic graphical elements of a visualization. Note here that we call one visualization a `track` in Gosling.
5 | The core of constructing a visualization is to bind selected **data fields** to the **visual channels** (e.g., size, color, and position) of a chosen **mark type**.
6 |
7 | The `mark` property of a track is defined by a string that describes the mark type.
8 | ```javascript
9 | {
10 | "tracks":[
11 | {
12 | "mark": "rect",
13 | ... // other track properties
14 | },
15 | {
16 | "mark": "line",
17 | ... // other track properties
18 | }
19 | ],
20 | ... // other visualization properties
21 | }
22 | ```
23 | Gosling supports the following primitive `mark` types: `point`, `line`, `area`, `bar`, `rect`, `text`, `link`, `rule`, `triangle`. Composite mark (i.e., glyph) is also supported through the [`alignment`](https://github.com/gosling-lang/gosling-docs/blob/master/docs/composition.md#overlaid-tracks)) property.
24 |
25 | - [Point](#point)
26 | - [Line](#line)
27 | - [Area](#area)
28 | - [Bar](#bar)
29 | - [Rect](#rect)
30 | - [Text](#text)
31 | - [Link](#link)
32 | - [Triangle](#triangle)
33 |
34 | ## Point
35 | [:link: source code](https://github.com/gosling-lang/gosling.js/blob/master/src/core/mark/point.ts)
36 |
37 | The mark `point` represents one data point using a circular shape. Visual channels of the circle, such as radius, color, and vertical/horizontal position, are used to represent values of the data point. Popular charts such as scatter plots and bubble charts use `point` mark.
38 |
39 |
40 |
41 | [Try it in the online editor]()
42 |
43 | ```javascript
44 | // an example of point marks
45 | {
46 | "tracks":[{
47 | "data": {
48 | "url": ...,
49 | "type": ...
50 | },
51 | // mark type
52 | "mark": "point",
53 | // mark visual channels
54 | "x": {
55 | "field": "position", // data field
56 | "type": "genomic", // type of data field
57 | "axis": "top"
58 | },
59 | "y": {
60 | "field": "peak",
61 | "type": "quantitative"
62 | },
63 | ... // other encodings and styles
64 | }]
65 | }
66 | ```
67 | ## Line
68 |
69 | The mark `line` represents a set of data points using a line that connects these points.
70 |
71 |
72 |
73 | [Try it in the online editor]()
74 |
75 | ```javascript
76 | // an example of using line marks
77 | {
78 | "tracks":[{
79 | "data": {
80 | "url": ...,
81 | "type": ...
82 | },
83 | // specify mark type
84 | "mark": "line",
85 | // specify mark visual channels
86 | "x": {
87 | "field": "position", // data field
88 | "type": "genomic", // type of data field
89 | "axis": "top" // position of the x axis
90 | },
91 | "y": {
92 | "field": "peak",
93 | "type": "quantitative"
94 | },
95 | ... // other encodings and styles
96 | }]
97 | }
98 | ```
99 | ## Area
100 | The mark `area` represents a set of data points as an area shape. The upper edge of the area shape is a line that connects all the points and the bottom edge is the x axis.
101 |
102 |
103 |
104 | [Try it in the online editor]()
105 |
106 | ```javascript
107 | // an example of area marks
108 | {
109 | "tracks":[{
110 | "data": {
111 | "url": ...,
112 | "type": ...
113 | },
114 | // mark type
115 | "mark": "area",
116 | // mark visual channels
117 | "x": {
118 | "field": "position", // data field
119 | "type": "genomic", // type of data field
120 | "axis": "top"
121 | },
122 | "y": {
123 | "field": "peak",
124 | "type": "quantitative"
125 | },
126 | "color": ...,
127 | ... // other encodings and styles
128 | }]
129 | }
130 | ```
131 |
132 | ## Bar
133 |
134 | The `bar` mark is designed for drawing bar charts. Each bar shows the value of one data point through its height.
135 |
136 |
137 |
138 | [Try it in the online editor]()
139 |
140 | ```javascript
141 | // an example of area marks
142 | {
143 | "tracks":[{
144 | "data": {
145 | "url": ...,
146 | "type": ...
147 | },
148 | // mark type
149 | "mark": "bar",
150 | // mark visual channels
151 | "x": {
152 | "field": "position", // data field
153 | "type": "genomic", // type of data field
154 | "axis": "top"
155 | },
156 | // y indicates the visual encoding of the bar height
157 | "y": {
158 | "field": "peak",
159 | "type": "quantitative"
160 | },
161 | ... // other encodings and styles
162 | }]
163 | }
164 | ```
165 |
166 | ## Rect
167 | The `rect` mark is designed for representing genomic intervals using rectangular shapes. Left and right edge of the rectangle indicate the start and end genomic positions, respectively.
168 |
169 |
170 |
171 | [Try it in the online editor]()
172 |
173 | ```javascript
174 | // an example of rect marks
175 | {
176 | "traks":[
177 | {
178 | "data": ...,
179 | // specify the type of mark
180 | "mark": "rect",
181 | // bind the color of each rect mark to the data field: Stain
182 | "color": {
183 | "field": "Stain",
184 | "type": "nominal",,
185 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
186 | "range": ["white", "#D9D9D9", "#979797", "#636363", "black", "#A0A0F2"]
187 | },
188 | // bind the start position of each rect mark to the data field: chromStart
189 | "x": {
190 | "field": "chromStart",
191 | "type": "genomic",
192 | "axis": "top"
193 | },
194 | // bind the end position of each rect mark to the data field: chromEnd
195 | "xe": {
196 | "field": "chromEnd", "type": "genomic"
197 | },
198 | "size": {
199 | "value": 30 // specify the constant height of each rect mark
200 | }
201 | },
202 | ... // other encodings and styles of the rect mark
203 | ],
204 | }
205 |
206 | ```
207 |
208 | ## Text
209 |
210 | The `text` mark is designed to display textual labels. For example, gene names and nucleobases can be displayed with `text` marks.
211 |
212 |
213 |
214 | [Try it in the online editor]()
215 |
216 | ```javascript
217 | {
218 | "tracks":[{
219 | "data": ...,
220 |
221 | // specify the type of mark
222 | "mark": "text",
223 |
224 | // specify styles of the mark
225 | "style": {"textStrokeWidth": 0},
226 |
227 | // bind visual channels to corresponding data fields
228 | "x": {"field": "start", "type": "genomic", "axis": "top"},
229 | "xe": {"field": "end", "type": "genomic"},
230 | "y": {"field": "count", "type": "quantitative"},
231 | "color": {
232 | "field": "base",
233 | "type": "nominal",
234 | "domain": ["A", "T", "G", "C"]
235 | },
236 |
237 | // specify the text content
238 | "text": {"field": "base", "type": "nominal"}
239 | }]
240 | }
241 | ```
242 |
243 | ## Link
244 |
245 | The `link` mark is designed to show connections between chromosomes using an arc that connects two genomic intervals.
246 |
247 |
248 |
249 | [Try it in the online editor]()
250 |
251 |
252 | ```javascript
253 | {
254 | "tracks": [
255 | {
256 | "data": ...,
257 |
258 | "mark": "link", // specify the mark type
259 |
260 | // bind visual channels to corresponding data fields
261 |
262 | // x and xe indicates the start point of the arc
263 | "x": {
264 | "field": "s1",
265 | "type": "genomic",
266 | "domain": {"chromosome": "1"},
267 | "axis": "top"
268 | },
269 | "xe": {"field": "e1", "type": "genomic"},
270 |
271 | // x and xe indicates the end point of the arc
272 | "x1": {
273 | "field": "s2",
274 | "type": "genomic",
275 | "domain": {"chromosome": "1"},
276 | "axis": "top"
277 | },
278 | "x1e": {"field": "e2", "type": "genomic"},
279 |
280 | // specify styles of the mark
281 | "stroke": {"value": "steelblue"},
282 | "style": {"circularLink": true}
283 | }
284 | ]
285 | }
286 | ```
287 |
288 | ## Triangle
289 |
290 | [:link: source code](https://github.com/gosling-lang/gosling.js/blob/master/src/core/mark/triangle.ts)
291 |
292 | Gosling supports three types of triangle marks: `triangleLeft`, `triangleRight`, `triangleBottom`
--------------------------------------------------------------------------------
/docs/public-datasets.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Public Datasets
3 | ---
4 | To help using Gosling for the first time, this document provides some useful datasets that can be directly used in Gosling.
5 |
6 | For the flexible data exploration, Gosling supports two different kinds of datasets:
7 |
8 | 1. **Plain Datasets**: For the convenience, Gosling allows to use several data formats directly in the system without requiring to preprocess data or set up a dedicated server (i.e., HiGlass server).
9 |
10 |
11 | 2. **Pre-aggregated Datasets**: To allow scalable data exploration, Gosling supports using HiGlass' preprocessed datasets which requires the dedicated HiGlass server.
12 |
13 | In this document, we provide a list of public datasets in those two classes. For the pre-aggregated ones listed below, we provide them in our Gosling's server, so you do not need to set up your own HiGlass server to visualize them.
14 |
15 | > **Tip.** When you are using online editor, you can check out a "Data Preview" panel on the right-bottom part of the interface to see how the actual data looks like.
16 |
17 | ## List of Plain Datasets
18 | - Type: CSV
19 | - URL: https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv
20 | - Description: hg38 cytoband
21 | - Soruce: UCSC
22 | ---
23 | - Type: BigWig
24 | - URL: https://s3.amazonaws.com/gosling-lang.org/data/4DNFIMPI5A9N.bw
25 | - Source: 4DN (https://data.4dnucleome.org/files-processed/4DNFIMPI5A9N/#file-overview)
26 | ---
27 | - Type: CSV
28 | - URL: https://s3.amazonaws.com/gosling-lang.org/data/COVID/NC_045512.2-Genes.csv
29 | - Description: Gene Annotations of SARS-CoV-2 in NC_045512.2
30 | - Source: https://genome.ucsc.edu/covid19.html
31 | ---
32 | - Type: CSV
33 | - URL: https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/circos-segdup-edited.txt
34 | - Description: Circos Segmental Duplication
35 | - Source: https://github.com/nicgirault/circosJS/blob/master/demo/data/segdup.csv
36 | ## List of Pre-aggregated Datasets
37 | - Type: BEDDB (Originally, a bed file)
38 | - URL: https://server.gosling-lang.org/api/v1/tileset_info/?d=gene-annotation
39 | - Description: hg38 gene annotation
40 | - Source: http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/
41 |
42 | ---
43 | - Type: Multivec (Originally, multiple bigwig files)
44 | - URL: https://server.gosling-lang.org/api/v1/tileset_info/?d=cistrome-multivec
45 | - Description: Multiple samples of ChIP-seq and DNase-seq analysis
46 | - Source: Cistrome Browser (http://cistrome.org/db/#/)
47 |
48 | ---
49 |
50 | - Type: Multivec (Originally, a FASTA file)
51 | - URL: https://server.gosling-lang.org/api/v1/tileset_info/?d=sequence-multivec
52 | - Description: hg38 sequence
53 | - Source: UCSC (https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/)
54 |
55 | ---
56 |
57 | - Type: BEDDB (Originally, a VCF file)
58 | - URL: https://server.gosling-lang.org/api/v1/tileset_info/?d=clinvar-beddb
59 | - Description: hg38 ClinVar data
60 | - Source: https://ftp.ncbi.nlm.nih.gov/pub/clinvar/vcf_GRCh38/
61 |
62 | ---
63 | - Type: Multivec (Originally, a VCF file)
64 | - URL: https://server.gosling-lang.org/api/v1/tileset_info/?d=clinvar-multivec
65 | - Description: Density of ClinVar data by seven pathogenicity categories
66 | - Source: https://ftp.ncbi.nlm.nih.gov/pub/clinvar/vcf_GRCh38/
67 |
68 | ```ts
69 | categories: [
70 | 'Benign',
71 | 'Benign/Likely_benign',
72 | 'Likely_benign',
73 | 'Uncertain_significance',
74 | 'Likely_pathogenic',
75 | 'Pathogenic/Likely_pathogenic',
76 | 'Pathogenic',
77 | 'risk_factor',
78 | 'Conflicting_interpretations_of_pathogenicity'
79 | ]
80 | ```
81 |
--------------------------------------------------------------------------------
/docs/semantic-zoom.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Semantic Zoom
3 | ---
4 |
5 | [:link: source code](https://github.com/gosling-lang/gosling.js/blob/43626eaf21417bf36128a405dceeaa6ee00d0851/src/core/gosling.schema.ts#L278)
6 |
7 | Advanced zooming technique, called Semantic Zooming, allows you to dynamically switch between visual representations upon zooming in and out.
8 |
9 | For example, detailed information of nucleotide bases can be shown with textual labels when zoomed in while it can be switched to show the overall distribution of the bases using a stacked bar chart when zoomed out.
10 |
11 | ## Example: Sequence Visualization
12 |
13 |
14 |
15 |
16 | [Try this example in the online editor]()
17 |
18 | ## Example: Cyto Band
19 |
20 |
21 |
22 |
23 | **Top**: only `rect` marks are represented; **Bottom:** `text` and `triangle` marks are presented when zooming in to show more details.
24 | [Try this example in the online editor]()
25 |
26 |
27 | Semantic zoom is achieved by controlling `alignment` and `visibility`.
28 | [`alignment`](https://github.com/gosling-lang/gosling-docs/blob/master/docs/composition.md#overlaid-tracks) allow users to overlap multiple marks on top of one other, thus allowing users to create different visualizations for the same data.
29 | `visibility` controls the visibility of visual marks, thus allowing the switch between different visualizations based on the zoom level.
30 |
31 | `visibility` is an array of object with the following properties:
32 |
33 | | properties | type | description|
34 | |---|---|---|
35 | |target| string| **required**, support "track" \| "mark" |
36 | | measure | string | **required**, support "width"\|"height"\|"zoomLevel".|
37 | | threshold | "\|xe-x\|" \| number | **required**, when using `number`, the unit of a number is pixel with `width` and `height` measures while it is a base pair (bp) with `zoomLevel` |
38 | | operation | string | **required**, specify the logical operation to conduct between `threshold` and the `measure` of `target`
> :"greater-than", "gt", "GT",
< : "less-than", "lt", "LT",
≥ : "greater-than-or-equal-to", "gtet", "GTET"),
≤ : "less-than-or-equal-to", "ltet", "LTET" |
39 | | conditionPadding | number | buffer px size of width or height when calculating the visibility, default = 0 |
40 | | transitionPadding | number | buffer px size of width or height for smooth transition, default = 0 |
41 |
42 | The `visibility` of corresponding marks are decided by whether the `measure` of `target` and the `threshold` satisfy the `operation`.
43 |
44 | For example, in the code below, text marks only show when the width (`measure`) of the mark (`target`) is great-than (`operation`) 20 (`threshold`).
45 |
46 | ```javascript
47 | {
48 | // example of semantic zoom: show text marks when zooming in
49 |
50 | "tracks":[{
51 | "data":...,
52 | "x": ...,
53 | "y": ...,
54 | // overlay overlaps bar marks and text marks for the same data
55 | "alignment": "overlay",
56 | "tracks":[
57 | //bar marks always show
58 | {"mark": "bar"},
59 | //text marks only show when the width of mark is great than 20
60 | {
61 | "mark": "text",
62 | "visibility": [{
63 | "operation": "greater-than",
64 | "measure": "width",
65 | "threshold": "20",
66 | "target": "mark"
67 | }]
68 | }
69 | ]
70 | }]
71 | }
72 | ```
--------------------------------------------------------------------------------
/docs/user-interaction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: User Interaction
3 | ---
4 | - [Zooming and Panning](#zooming-and-panning)
5 | - [Linking Views](#linking-views)
6 | - [Brushing and Linking](#brushing-and-linking)
7 |
8 | ## Zooming and Panning
9 |
10 |
11 | Each visualization in Gosling supports the Zooming and Panning interaction.
12 | Users can zoom in/out a visualization using the scrolling up/down actions.
13 | Users can pan by clicking on the visualization and then drag it in the desired direction.
14 |
15 | Zooming and panning are controlled through the `static` property, which has a default value of `false`.
16 | When `static = true`, zooming and panning are disabled.
17 | Users can set the `static` property of all tracks at the root level or specify it in a single track definition.
18 | ```javascript
19 | {
20 | "static": true, //disable zoom & pan for all tracks
21 | "tracks": [
22 | {
23 | "static": false, // enable zoom & pan for this track
24 | ...
25 | },
26 | {
27 | ...
28 | },
29 | ...
30 | ]
31 | }
32 | ```
33 |
34 | ## Linking Views
35 |
36 |
37 | When views/tracks are linked, the zooming and panning performed in one view/track will be automatically applied to the linked views/tracks.
38 |
39 | [Try it in the online editor]()
40 |
41 | Views and tracks can be linked through an user-assigned id.
42 | This id is assigned to a `track` through the `x.linkingId` property, and assigned to a `view` through the `linkingId` property.
43 |
44 | ```javascript
45 | // linking serveral tracks
46 | {
47 | "tracks":[
48 | // track A
49 | {
50 | "data": ...,
51 | "mark": "rect",
52 | "x": {
53 | ..., // other properties of x channel
54 | "linkingId": "a unique string" // assign a linking id for the track A
55 | }
56 | },
57 | // track B
58 | {
59 | "data": ...,
60 | "mark": "point",
61 | "x": {
62 | ..., // other properties of x channel
63 | "linkingId": "a unique string" // the same linking id links track A and track B
64 | }
65 | },
66 | ... // other tracks
67 | ]
68 | }
69 | ```
70 |
71 | ```javascript
72 | // linking views and tracks
73 | {
74 | "views": [
75 | {
76 | // view A
77 | "linkingId": "detail",
78 | ....
79 | },
80 | {
81 | // view B
82 | "linkingId": "detail",
83 | ....
84 | },
85 | {
86 | // view C
87 | "tracks":[
88 | {
89 | // this track wil be linked to view A and view B
90 | "x": {"linkingId": "detail", ...},
91 | ...
92 | },
93 | {...} // without the linkingId, this track will not be linked
94 | ]
95 | }
96 | ]
97 | }
98 | ```
99 |
100 | ## Brushing and Linking
101 | Users can use **brushing** to select a subset of the data items using a rectangle. Users can modify the left and right edge of the rectangle to modify the selection. The selected data items can be linked to data items in another track.
102 |
103 | [Try it in the online editor]()
104 |
105 | ```javascript
106 | {
107 | "tracks":[
108 | // track A
109 | {
110 | "data": ...,
111 | "mark": "line",
112 | ...,
113 |
114 | // create a rectangle brush
115 | "alignment": "overlay",
116 | "tracks": [
117 | {}, // this dummy object cannot be removed
118 | {
119 | "mark": "rect-brush",
120 | "x": {"linkingId": "linking-with-brush"}, // assign a unique id to the brush
121 | "color": {"value":"steelBlue"}
122 | }
123 | ]
124 | },
125 | // track B
126 | {
127 | "data": ...,
128 | "mark": "point",
129 | "x": {
130 | ..., // other properties of x channel
131 | "linkingId": "a unique string" // the same linking id links track B and the brush in track A
132 | }
133 | },
134 | ... // other tracks
135 | ]
136 | }
137 | ```
--------------------------------------------------------------------------------
/docs/visual-channel.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Visual Channel
3 | ---
4 | The visual appearance of a mark is controlled by a set of visual channels (e.g., size, position, and color). One visual channel can be bound with either a data field or just a constant value.
5 |
6 | ```javascript
7 | // an example configuration for a line chart (x and y are encoded)
8 |
9 | {
10 | "tracks":[{
11 | "data": {
12 | "url": ...,
13 | "type": ...
14 | },
15 | // specify the mark type
16 | "mark": "line",
17 | // visual channel x is bound with the data field genomic
18 | "x": {
19 | "field": "position",
20 | "type": "genomic"
21 | },
22 | // visual channel y is bound with the data field peak
23 | "y": {
24 | "field": "peak",
25 | "type": "quantitative"
26 | },
27 | // visual channel color is assigned a constant value
28 | "color": {"value": "steelblue"}
29 | }]
30 | }
31 |
32 | ```
33 |
34 | - [x](#x)
35 | - [xe](#xe)
36 | - [y](#y)
37 | - [ye](#ye)
38 | - [x1 x1e y1 y1e](#x1-x1e-y1-y1e)
39 | - [row](#row)
40 | - [size](#size)
41 | - [text](#text)
42 | - [color](#color)
43 | - [stroke](#stroke)
44 | - [strokeWidth](#strokewidth)
45 | - [opacity](#opacity)
46 | - [Style](#style)
47 |
48 |
49 | As the table shown below, different marks have different visual channels.
50 |
51 | | mark type | supported visual channels |
52 | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
53 | | [`point`](#point) | [`x`](#x), [`y`](#y), [`row`](#row), [`size`](#size), [`color`](#color), [`strokeWidth`](#strokeWidth), [`opacity`](#opacity) |
54 | | [`line`](#line) | [`x`](#x), [`y`](#y), [`row`](#row), [`color`](#color), [`strokeWidth`](#strokeWidth) |
55 | | [`rect`](#rect) | [`x`](#x), [`xe`](#xe), [`row`](#row), [`color`](#color), [`strokeWidth`](#strokeWidth), [`opacity`](#opacity) |
56 | | [`bar`](#bar) | [`x`](#x), [`y`](#y), [`row`](#row), [`color`](#color), [`strokeWidth`](#strokeWidth), [`opacity`](#opacity) |
57 | | [`area`](#area) | [`x`](#x), [`y`](#y), [`row`](#row), [`color`](#color), [`strokeWidth`](#strokeWidth) |
58 | | [`link`](#link) | [`x`](#x), [`xe`](#xe), [`x1`](#x1-y1-x1e-y1e), [`x1e`](#x1-y1-x1e-y1e), [`color`](#color), [`opacity`](#opacity) |
59 | | [`triangle`](#triangle) | [`x`](#x), [`xe`](#xe), [`row`](#row), [`size`](#size), [`color`](#color), [`opacity`](#opacity) |
60 | | [`text`](#text) | [`x`](#x), [`xe`](#xe), [`row`](#row), [`color`](#color), [`opacity`](#opacity) |
61 |
62 | A visual channel can be either assigned a constant value or bound with a data field. When a visual channel is bound with a data field, Gosling creates a mapping from the values of the data field (e.g., [gnes, gpos25, gpos50, ...]) to the values of the visual channel (e.g., position of a bar). We call the values of data field **domain** and the values of the visual channel **range**.
63 |
64 | **Table: Properties shared by all visual channels**
65 |
66 | | visual channel properties | type | description |
67 | | ------------------------- | --------------------------- | ---------------------------------------------------------------------------------- |
68 | | field | string | specify name of the data field |
69 | | type | string | specify type of the data field. support `"genomic"`, `"nominal"`, `"quantitative"` |
70 | | aggregate | string | support `"max"`, `"min"`, `"mean"`, `"bin"`, `"count"` |
71 | | domain | [number, number]\| string[] | specify values of the data field |
72 | | range | [number, number]\| string[] | specify values of the visual channel |
73 | | value | string \| number | assign a constant value to the visual channel |
74 |
75 |
76 |
77 | For example, the code below creates a mapping from the data `field` "Stain" to the color of the `rect` mark.
78 | "gneg" will show as a white rect mark, "gpos100" will show as a black rect mark.
79 | ```javascript
80 | {
81 | "tracks": [{
82 | "mark": "rect",
83 | "color": {
84 | "field": "Stain",
85 | "type": "nominal",
86 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
87 | "range": ["white", "#D9D9D9", "#979797", "#636363", "black", "#A0A0F2"]
88 | },
89 | ... // other visual channels
90 | }]
91 | }
92 | ```
93 |
94 | ## x
95 | `x` specify a mark's position in the horizontal direction.
96 |
97 | Apart from the properties shared by all channels, `x` channel have the following unique properties:
98 |
99 | | unique properties | type | description |
100 | | ----------------- | ------ | ------------------------------------------------------------------------------------------------------------------ |
101 | | aggregate | string | support "max", "min", "count", "mean", "bin" |
102 | | axis | string | specify the axis position, support "none", "top", "bottom", "left", "right" |
103 | | linkingId | string | a unique linkingId is needed for [linking views](#linking-views) and [Brushing and Linking](#brushing-and-linking) |
104 |
105 |
106 | ## xe
107 | `xe` stands for the end of x axis. `xe` is usually used with `x` to specify the start position and the end position of a visual mark in the horizontal direction, respectively.
108 |
109 | Apart from the properties shared by all channels, `xe` channel have the following unique properties:
110 |
111 | | unique properties | type | description |
112 | | ----------------- | ------ | --------------------------------------------------------------------------- |
113 | | aggregate | string | support "max", "min", "count", "mean", "bin" |
114 | | axis | string | specify the axis position, support "none", "top", "bottom", "left", "right" |
115 |
116 | ## y
117 | `y` specify a mark's position in the vertical direction.
118 |
119 | Apart from the properties shared by all channels, `y` channel have the following unique properties:
120 |
121 | | unique properties | type | description |
122 | | ----------------- | ---------------- | --------------------------------------------------------------------------- |
123 | | axis | string | specify the axis position, support "none", "top", "bottom", "left", "right" |
124 | | baseline | string \| number | |
125 |
126 | ## ye
127 | `ye` stands for the end of y axis. `ye` is usually used with `x` to specify the start position and the end position of a visual mark in the vertical direction, respectively.
128 |
129 | ## x1 x1e y1 y1e
130 | The four channels are used together only in `link` mark. In this case, `x` and `xe` are used with `x1` and `x1e` to specify a pair of genomic intervals that needs to be connected using band representations. Similarly, `y` and `ye` can be used with `y1` and `y1e` to show band connection along vertical axis.
131 |
132 |
133 |
134 |
135 |
136 | ## row
137 |
138 | Channel `row` is used with channel `y` to stratify a visualization with categorical values.
139 |
140 | Without specifying `row`:
141 |
142 |
143 |
144 | Line charts are stratified with sample names.
145 |
146 |
147 |
148 | ```javascript
149 | {
150 | "tracks":[
151 | {
152 | // specify data source
153 | "data": {
154 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
155 | "type": "tileset"
156 | },
157 | "metadata": {
158 | "type": "higlass-multivec",
159 | "row": "sample",
160 | "column": "position",
161 | "value": "peak",
162 | "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
163 | },
164 | // specify the mark type
165 | "mark": "line",
166 | // specify visual channels
167 | "x": {
168 | "field": "position",
169 | "type": "genomic",
170 | "domain": {"chromosome": "1", "interval": [1, 3000500]},
171 | "axis": "top"
172 | },
173 | "y": {"field": "peak", "type": "quantitative"},
174 | "color": {"field": "sample", "type": "nominal", "legend": true},
175 | // visual channel row is bound with the data field: sample
176 | "row": {"field": "sample", "type": "nominal"}
177 | }
178 | ]
179 |
180 | }
181 | ```
182 |
183 | ## size
184 | Channel `size` indicates the size of the visual mark. It determines either the radius of a circle (`mark: point`), the vertical length of a triangle (`mark: triangleRight`, `mark: triangleLeft`, `mark: triangleBottom`), the vertical length of a rectangle (`mark: rect`), the thickness of a line (`mark: line`).
185 |
186 | ## text
187 |
188 | `text` channel is used only in `text` mark to specify what textual information to display.
189 |
190 | ## color
191 | Channel `color` specifies the filling color of the mark. Binding `color` with categorical values in `bar` and `area` marks stack marks that are positioned in the same genomic intervals to better show their cumulative values.
192 |
193 | Apart from the properties shared by all channels, the `color` channel have the following unique properties:
194 |
195 | | unique properties | type | description |
196 | | ----------------- | ------- | -------------------------------- |
197 | | legend | boolean | whether to show the color legend |
198 |
199 | ## stroke
200 | Channel `stroke` defines the outline color of the mark. Gosling supports `stroke` in the following marks: `rect`, `area`, `point`, `bar`, `link`.
201 |
202 | ## strokeWidth
203 | Channel `strokeWidth` defines the outline thickness of the mark shape. Gosling supports `strokeWidth` in the following marks: `rect`, `area`, `point`, `bar`, `link`.
204 |
205 | ## opacity
206 | Channel `opacity` specifies the opacity of the mark shape.
207 |
208 |
209 |
210 |
211 | ## Style
212 |
213 | `style` specifies the visual appearances of a track that are not bound with data fields.
214 |
215 | | style properties | type | description |
216 | | ---------------- | ------------------------------------------------------ | ---------------------------------------- |
217 | | background | string | color of the background |
218 | | dashed | [number, number] |
219 | | linePatterns | { "type": "triangleLeft" \| "triangleRight"; size: number } |
220 | | curve | string | support "top", "bottom", "left", "right" |
221 | | align | string | support "left", "right" |
222 | | dy | number |
223 | | outline | string |
224 | | outlineWidth | number |
225 | | circularLink | boolean |
226 | | textFontSize | number |
227 | | textStroke | string |
228 | | textStrokeWidth | number |
229 | | textFontWeight | string | support "bold", "normal" |
230 |
--------------------------------------------------------------------------------
/images/alignment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/alignment.png
--------------------------------------------------------------------------------
/images/area_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/area_example.png
--------------------------------------------------------------------------------
/images/bar_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/bar_example.png
--------------------------------------------------------------------------------
/images/layout_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/layout_demo.png
--------------------------------------------------------------------------------
/images/line_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/line_example.png
--------------------------------------------------------------------------------
/images/linear_circular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/linear_circular.png
--------------------------------------------------------------------------------
/images/link_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/link_example.png
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/logo.png
--------------------------------------------------------------------------------
/images/multi_views.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/multi_views.png
--------------------------------------------------------------------------------
/images/point_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/point_example.png
--------------------------------------------------------------------------------
/images/rect_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/rect_example.png
--------------------------------------------------------------------------------
/images/semantic_zoom_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/semantic_zoom_0.png
--------------------------------------------------------------------------------
/images/semantic_zoom_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/semantic_zoom_1.png
--------------------------------------------------------------------------------
/images/semantic_zoom_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/semantic_zoom_2.png
--------------------------------------------------------------------------------
/images/semantic_zoom_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/semantic_zoom_3.png
--------------------------------------------------------------------------------
/images/text_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/text_example.png
--------------------------------------------------------------------------------
/images/tutorial/tutorial_0.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_0.gif
--------------------------------------------------------------------------------
/images/tutorial/tutorial_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_0.png
--------------------------------------------------------------------------------
/images/tutorial/tutorial_circular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_circular.png
--------------------------------------------------------------------------------
/images/tutorial/tutorial_dataTransform.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_dataTransform.png
--------------------------------------------------------------------------------
/images/tutorial/tutorial_detail_view1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_detail_view1.png
--------------------------------------------------------------------------------
/images/tutorial/tutorial_multi_track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_multi_track.png
--------------------------------------------------------------------------------
/images/tutorial/tutorial_multi_views.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_multi_views.gif
--------------------------------------------------------------------------------
/images/tutorial/tutorial_overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_overlay.png
--------------------------------------------------------------------------------
/images/tutorial/tutorial_style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_style.png
--------------------------------------------------------------------------------
/images/tutorial/tutorial_text_label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/tutorial/tutorial_text_label.png
--------------------------------------------------------------------------------
/images/with_row.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/with_row.png
--------------------------------------------------------------------------------
/images/without_row.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/without_row.png
--------------------------------------------------------------------------------
/images/x_x1_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gosling-lang/gosling-docs/dcbc4f62c2c76d613d691b4d3265a2bb817c1b5d/images/x_x1_example.png
--------------------------------------------------------------------------------
/tutorials/create-multi-track-visualization.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Multi-track Visualizations
3 | ---
4 | In [Tutorial 1](https://github.com/gosling-lang/gosling-docs/blob/master/tutorials/create-single-track-visualization.md), we introduce how to load data, encode data with marks, transform data, overlay multiple marks and obtain the following visualization.
5 |
6 |
7 | click to expand the code
8 |
9 | ```javascript
10 | {
11 | "tracks":[{
12 | "width": 700,
13 | "height": 70,
14 | "data": {
15 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
16 | "type": "csv",
17 | "chromosomeField": "Chromosome",
18 | "genomicFields": ["chromStart", "chromEnd"]
19 | },
20 | "x": {
21 | "field": "chromStart",
22 | "type": "genomic",
23 | "domain": {"chromosome": "1"},
24 | "axis": "top"
25 | },
26 | "xe": {"field": "chromEnd", "type": "genomic"},
27 | "alignment": "overlay",
28 | "tracks":[
29 | {
30 | "mark": "rect",
31 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
32 | "color": {
33 | "field": "Stain",
34 | "type": "nominal",
35 | "domain": ["gpos25", "gpos50", "gpos75", "gpos100"],
36 | "range": ["#D9D9D9","#979797","#636363", "black"]
37 | }
38 | },
39 | {
40 | "mark": "triangleRight",
41 | "dataTransform": [
42 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
43 | {"type":"filter", "field": "Name", "include": "q"}
44 | ],
45 | "color": {"value": "#B70101"}
46 | },
47 | {
48 | "mark": "triangleLeft",
49 | "dataTransform": [
50 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
51 | {"type":"filter", "field": "Name", "include": "p"}
52 | ],
53 | "color": {"value": "#B70101"}
54 | }
55 | ],
56 | "size": {"value": 20},
57 | "stroke": {"value": "gray"},
58 | "strokeWidth": {"value": 0.5}
59 | }]
60 | }
61 | ```
62 |
63 |
64 | This tutorial continues from this example and introduces more advances functions:
65 | - [Semantic Zooming](#semantic-zooming)
66 | - [Multiple Linked Tracks](#multiple-linked-tracks)
67 | - [Circular Layout](#circular-layout)
68 |
69 |
70 | ## Semantic Zooming
71 |
72 | Apart from the default zoom and pan interactions, [semantic zoom](https://github.com/gosling-lang/gosling-docs/blob/master/docs/semantic-zoom.md) is supported in Gosling and allows users to switch between different visualizations of the same data through zooming in/out. When zooming in, the same data will be represented in a different way in which more details are shown.
73 |
74 | Let's say, for this visualization, we want text annotations to show up when zooming in.
75 | We add `text` marks to the `overlay` property and specify when the `text` marks should appear through the `visibility` property.
76 | We may wish the text marks to appear when the distance between chromStart and chromEnd is big enough to place a text mark.
77 | In other words, the text marks appear when the width (`measure`) of the text mark (`target`) is less than (`operation`) than `|xe-x|`.
78 |
79 |
80 |
81 |
82 | ```diff
83 | {
84 | "tracks": [
85 | {
86 | "width": 700,
87 | "height": 70,
88 | "data": {
89 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
90 | "type": "csv",
91 | "chromosomeField": "Chromosome",
92 | "genomicFields": ["chromStart", "chromEnd"]
93 | },
94 | "x": {
95 | "field": "chromStart",
96 | "type": "genomic",
97 | "domain": {"chromosome": "1"},
98 | "axis": "top"
99 | },
100 | "xe": {"field": "chromEnd", "type": "genomic"},
101 | "alignment": "overlay",
102 | "tracks": [
103 | + {
104 | + "mark": "text",
105 | + "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
106 | + "text": {"field": "Name", "type": "nominal"},
107 | + "color": {
108 | + "field": "Stain",
109 | + "type": "nominal",
110 | + "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
111 | + "range": ["black", "black", "black", "black", "white", "black"]
112 | + },
113 | + "visibility": [
114 | + {
115 | + "operation": "less-than",
116 | + "measure": "width",
117 | + "threshold": "|xe-x|",
118 | + "target": "mark"
119 | + }
120 | + ],
121 | + "style": {"textStrokeWidth": 0}
122 | + },
123 | {
124 | "mark": "rect",
125 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
126 | "color": {
127 | "field": "Stain",
128 | "type": "nominal",
129 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
130 | "range": [
131 | "white",
132 | "#D9D9D9",
133 | "#979797",
134 | "#636363",
135 | "black",
136 | "#A0A0F2"
137 | ]
138 | }
139 | },
140 | {
141 | "mark": "triangleRight",
142 | "dataTransform": [
143 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
144 | {"type":"filter", "field": "Name", "include": "q"}
145 | ],
146 | "color": {"value": "#B40101"}
147 | },
148 | {
149 | "mark": "triangleLeft",
150 | "dataTransform": [
151 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
152 | {"type":"filter", "field": "Name", "include": "p"}
153 | ],
154 | "color": {"value": "#B40101"}
155 | }
156 | ],
157 | "size": {"value": 20},
158 | "stroke": {"value": "gray"},
159 | "strokeWidth": {"value": 0.5}
160 | }
161 | ]
162 | }
163 | ```
164 |
165 |
166 | ## Multiple Linked Tracks
167 |
168 | We may wish to represent the same data from different aspects using different types of visualization.
169 | To achieve this, we add an area chart (i.e., a new `track`) to the `tracks` property.
170 | Since these tracks share the same `x` coordinate, we wish to link these two tracks: the zooming and panning performed in one track will be automatically applied to the linked track.
171 | In Gosling, `tracks` can be linked by assigning `x` the same `linkingId`.
172 |
173 |
174 |
175 |
176 | ```diff
177 | {
178 | + "spacing": 5,
179 | "tracks": [
180 | + {
181 | + "width": 700,
182 | + "height": 40,
183 | + "data": {
184 | + "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
185 | + "type": "multivec",
186 | + "row": "sample",
187 | + "column": "position",
188 | + "value": "peak",
189 | + "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
190 | + },
191 | + "mark": "area",
192 | + "x": {
193 | + "field": "position",
194 | + "type": "genomic",
195 | + "domain": {"chromosome": "1"},
196 | + "axis": "top",
197 | + "linkingId": "link-1"
198 | + },
199 | + "y": {"field": "peak", "type": "quantitative"},
200 | + "color": {"field": "sample", "type": "nominal"}
201 | + },
202 | {
203 | "width": 700,
204 | - "height": 70,
205 | + "height": 20,
206 | "data": {
207 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
208 | "type": "csv",
209 | "chromosomeField": "Chromosome",
210 | "genomicFields": ["chromStart", "chromEnd"]
211 | },
212 | "x": {
213 | "field": "chromStart",
214 | "type": "genomic",
215 | "domain": {"chromosome": "1"},
216 | - "axis": "top"
217 | + "linkingId": "link-1"
218 | },
219 | "xe": {"field": "chromEnd", "type": "genomic"},
220 | "alignment": "overlay",
221 | "tracks": [
222 | {
223 | "mark": "text",
224 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
225 | "text": {"field": "Name", "type": "nominal"},
226 | "color": {
227 | "field": "Stain",
228 | "type": "nominal",
229 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
230 | "range": ["black", "black", "black", "black", "white", "black"]
231 | },
232 | "visibility": [
233 | {
234 | "operation": "less-than",
235 | "measure": "width",
236 | "threshold": "|xe-x|",
237 | "transitionPadding": 10,
238 | "target": "mark"
239 | }
240 | ],
241 | "style": {"textStrokeWidth": 0}
242 | },
243 | {
244 | "mark": "rect",
245 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
246 | "color": {
247 | "field": "Stain",
248 | "type": "nominal",
249 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
250 | "range": [
251 | "white",
252 | "#D9D9D9",
253 | "#979797",
254 | "#636363",
255 | "black",
256 | "#A0A0F2"
257 | ]
258 | }
259 | },
260 | {
261 | "mark": "triangleRight",
262 | "dataTransform": [
263 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
264 | {"type":"filter", "field": "Name", "include": "q"}
265 | ],
266 | "color": {"value": "#B40101"}
267 | },
268 | {
269 | "mark": "triangleLeft",
270 | "dataTransform": [
271 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
272 | {"type":"filter", "field": "Name", "include": "p"}
273 | ],
274 | "color": {"value": "#B40101"}
275 | }
276 | ],
277 | "size": {"value": 20},
278 | "stroke": {"value": "gray"},
279 | "strokeWidth": {"value": 0.5}
280 | }
281 | ]
282 | }
283 | ```
284 |
285 |
286 | ## Circular Layout
287 |
288 | We can easily turn the visualization into a circular layout through the `layout` property.
289 |
290 |
291 |
292 | ```diff
293 | + "layout": "circular",
294 | + "centerRadius": 0.6,
295 | ```
296 |
297 |
298 | Click here to expand the complete code
299 |
300 | ```javscript
301 | {
302 | "layout": "circular",
303 | "centerRadius": 0.6,
304 | "spacing": 5,
305 | "tracks": [
306 | {
307 | "width": 700,
308 | "height": 40,
309 | "data": {
310 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
311 | "type": "multivec",
312 | "row": "sample",
313 | "column": "position",
314 | "value": "peak",
315 | "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
316 | },
317 | "mark": "area",
318 | "x": {
319 | "field": "position",
320 | "type": "genomic",
321 | "domain": {"chromosome": "1"},
322 | "axis": "top",
323 | "linkingId": "link-1"
324 | },
325 | "y": {"field": "peak", "type": "quantitative"},
326 | "color": {"field": "sample", "type": "nominal"}
327 | },
328 | {
329 | "width": 700,
330 | "height": 20,
331 | "data": {
332 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
333 | "type": "csv",
334 | "chromosomeField": "Chromosome",
335 | "genomicFields": ["chromStart", "chromEnd"]
336 | },
337 | "x": {
338 | "field": "chromStart",
339 | "type": "genomic",
340 | "domain": {"chromosome": "1"},
341 | "linkingId": "link-1"
342 | },
343 | "xe": {"field": "chromEnd", "type": "genomic"},
344 | "alignment": "overlay",
345 | "tracks": [
346 | {
347 | "mark": "text",
348 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
349 | "text": {"field": "Name", "type": "nominal"},
350 | "color": {
351 | "field": "Stain",
352 | "type": "nominal",
353 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
354 | "range": ["black", "black", "black", "black", "white", "black"]
355 | },
356 | "visibility": [
357 | {
358 | "operation": "less-than",
359 | "measure": "width",
360 | "threshold": "|xe-x|",
361 | "transitionPadding": 10,
362 | "target": "mark"
363 | }
364 | ],
365 | "style": {"textStrokeWidth": 0}
366 | },
367 | {
368 | "mark": "rect",
369 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
370 | "color": {
371 | "field": "Stain",
372 | "type": "nominal",
373 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
374 | "range": [
375 | "white",
376 | "#D9D9D9",
377 | "#979797",
378 | "#636363",
379 | "black",
380 | "#A0A0F2"
381 | ]
382 | }
383 | },
384 | {
385 | "mark": "triangleRight",
386 | "dataTransform": [
387 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
388 | {"type":"filter", "field": "Name", "include": "q"}
389 | ],
390 | "color": {"value": "#B40101"}
391 | },
392 | {
393 | "mark": "triangleLeft",
394 | "dataTransform": [
395 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
396 | {"type":"filter", "field": "Name", "include": "p"}
397 | ],
398 | "color": {"value": "#B40101"}
399 | }
400 | ],
401 | "size": {"value": 20},
402 | "stroke": {"value": "gray"},
403 | "strokeWidth": {"value": 0.5}
404 | }
405 | ]
406 | }
407 | ```
408 |
409 |
--------------------------------------------------------------------------------
/tutorials/create-multi-view-visualization.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Multi-view Visualizations
3 | ---
4 | In [Tutorial 2](https://github.com/gosling-lang/gosling-docs/blob/master/tutorials/create-multi-track-visualization.md), we introduce how to create a multi-track visualization, as shown below.
5 |
6 |
7 |
8 |
9 | Click here to expand the complete code
10 |
11 | ```javascript
12 | {
13 | "layout": "circular",
14 | "centerRadius": 0.6,
15 | "spacing": 5,
16 | "tracks": [
17 | {
18 | "width": 700,
19 | "height": 40,
20 | "data": {
21 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
22 | "type": "multivec",
23 | "row": "sample",
24 | "column": "position",
25 | "value": "peak",
26 | "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
27 | },
28 | "mark": "area",
29 | "x": {
30 | "field": "position",
31 | "type": "genomic",
32 | "domain": {"chromosome": "1"},
33 | "axis": "top",
34 | "linkingId": "link-1"
35 | },
36 | "y": {"field": "peak", "type": "quantitative"},
37 | "color": {"field": "sample", "type": "nominal"}
38 | },
39 | {
40 | "width": 700,
41 | "height": 20,
42 | "data": {
43 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
44 | "type": "csv",
45 | "chromosomeField": "Chromosome",
46 | "genomicFields": ["chromStart", "chromEnd"]
47 | },
48 | "x": {
49 | "field": "chromStart",
50 | "type": "genomic",
51 | "domain": {"chromosome": "1"},
52 | "linkingId": "link-1"
53 | },
54 | "xe": {"field": "chromEnd", "type": "genomic"},
55 | "alignment": "overlay",
56 | "tracks": [
57 | {
58 | "mark": "text",
59 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
60 | "text": {"field": "Name", "type": "nominal"},
61 | "color": {
62 | "field": "Stain",
63 | "type": "nominal",
64 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
65 | "range": ["black", "black", "black", "black", "white", "black"]
66 | },
67 | "visibility": [
68 | {
69 | "operation": "less-than",
70 | "measure": "width",
71 | "threshold": "|xe-x|",
72 | "transitionPadding": 10,
73 | "target": "mark"
74 | }
75 | ],
76 | "style": {"textStrokeWidth": 0}
77 | },
78 | {
79 | "mark": "rect",
80 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
81 | "color": {
82 | "field": "Stain",
83 | "type": "nominal",
84 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
85 | "range": [
86 | "white",
87 | "#D9D9D9",
88 | "#979797",
89 | "#636363",
90 | "black",
91 | "#A0A0F2"
92 | ]
93 | }
94 | },
95 | {
96 | "mark": "triangleRight",
97 | "dataTransform": [
98 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
99 | {"type":"filter", "field": "Name", "include": "q"}
100 | ],
101 | "color": {"value": "#B40101"}
102 | },
103 | {
104 | "mark": "triangleLeft",
105 | "dataTransform": [
106 | {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
107 | {"type":"filter", "field": "Name", "include": "p"}
108 | ],
109 | "color": {"value": "#B40101"}
110 | }
111 | ],
112 | "size": {"value": 20},
113 | "stroke": {"value": "gray"},
114 | "strokeWidth": {"value": 0.5}
115 | }
116 | ]
117 | }
118 | ```
119 |
120 |
121 | In Gosling, we call a visualization with several `tracks` as **a single view**.
122 | Sometimes, we may wish to create a visualization with **multiple views**, e.g., one overview + several detailed views.
123 |
124 | ## create Multiple Views
125 |
126 | Let's say we use the above circular visualization as the overview that visualizes all the chromosomes.
127 | To achieve this, we remove the specified `x.domain` in the overview.
128 | **Overview**
129 | ```diff
130 | - "domain": {"chromosome": "1"},
131 | ```
132 |
133 | We then create two linear detailed views for two different chromosomes, e.g., chromosome 2 and chromosome 5.
134 |
135 |
136 | **Detailed View 1**
137 |
138 |
139 |
140 | ```diff
141 | + {
142 | + "layout": "linear",
143 | + "tracks": [{
144 | + "row": {"field": "sample", "type": "nominal"},
145 | + "width": 340,
146 | + "height": 300,
147 | + "data": {
148 | + "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
149 | + "type": "multivec",
150 | + "row": "sample",
151 | + "column": "position",
152 | + "value": "peak",
153 | + "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
154 | + },
155 | + "mark": "area",
156 | + "x": {
157 | + "field": "position",
158 | + "type": "genomic",
159 | + "domain": {"chromosome": "2"}
160 | + "axis": "top"
161 | + },
162 | + "y": {"field": "peak", "type": "quantitative"},
163 | + "color": {"field": "sample", "type": "nominal"}
164 | + }]
165 | + }
166 | ```
167 |
168 |
169 |
170 | **Detailed View 2** is the same as **Detailed View 1** except the `x.domain`.
171 |
172 | ```diff
173 | - "domain": {"chromosome": "2"}
174 | + "domain": {"chromosome": "5"}
175 | ```
176 |
177 | Click to expand the complete code for Detailed View 2
178 |
179 | ```diff
180 | + {
181 | + "layout": "linear",
182 | + "tracks": [{
183 | + "row": {"field": "sample", "type": "nominal"},
184 | + "width": 340,
185 | + "height": 300,
186 | + "data": {
187 | + "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
188 | + "type": "multivec",
189 | + "row": "sample",
190 | + "column": "position",
191 | + "value": "peak",
192 | + "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
193 | + },
194 | + "mark": "area",
195 | + "x": {
196 | + "field": "position",
197 | + "type": "genomic",
198 | + "domain": {"chromosome": "5"}
199 | + "axis": "top"
200 | + },
201 | + "y": {"field": "peak", "type": "quantitative"},
202 | + "color": {"field": "sample", "type": "nominal"}
203 | + }]
204 | + }
205 | ```
206 |
207 |
208 |
209 | ## Arrange Multiple Views
210 | So far, we have created one overview and two detailed views.
211 | In Gosling, multiple views can be arranged using the `arrangement` property.
212 |
213 | ```javascript
214 | {
215 | "arrangement": "parallel"
216 | "views": [
217 | {/** overview **/},
218 | {
219 | "arrangement": "serial",
220 | "spacing": 20,
221 | "views": [
222 | {/** detailed view 1 **/},
223 | {/** detailed view 2 **/}
224 | ]
225 | }
226 | ]
227 | }
228 | ```
229 |
230 |
231 | Click here to expand the complete code
232 |
233 | ```javascript
234 | {
235 | "arrangement": "vertical",
236 | "views": [
237 | {
238 | "layout": "circular",
239 | "centerRadius": 0.6,
240 | "spacing": 5,
241 | "tracks": [
242 | {
243 | "width": 700,
244 | "height": 40,
245 | "data": {
246 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
247 | "type": "multivec",
248 | "row": "sample",
249 | "column": "position",
250 | "value": "peak",
251 | "categories": [
252 | "sample 1",
253 | "sample 2",
254 | "sample 3",
255 | "sample 4"
256 | ]
257 | },
258 | "mark": "area",
259 | "x": {
260 | "field": "position",
261 | "type": "genomic",
262 | "axis": "top",
263 | "linkingId": "link-1"
264 | },
265 | "y": {
266 | "field": "peak",
267 | "type": "quantitative"
268 | },
269 | "color": {
270 | "field": "sample",
271 | "type": "nominal"
272 | },
273 | "alignment": "overlay",
274 | "tracks": [
275 | {
276 | "mark": "area"
277 | },
278 | {
279 | "mark": "brush",
280 | "x": {
281 | "linkingId": "detail-1"
282 | },
283 | "color": {
284 | "value": "blue"
285 | }
286 | },
287 | {
288 | "mark": "brush",
289 | "x": {
290 | "linkingId": "detail-2"
291 | },
292 | "color": {
293 | "value": "red"
294 | }
295 | }
296 | ]
297 | },
298 | {
299 | "width": 700,
300 | "height": 20,
301 | "data": {
302 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
303 | "type": "csv",
304 | "chromosomeField": "Chromosome",
305 | "genomicFields": [
306 | "chromStart",
307 | "chromEnd"
308 | ]
309 | },
310 | "x": {
311 | "field": "chromStart",
312 | "type": "genomic"
313 | },
314 | "xe": {
315 | "field": "chromEnd",
316 | "type": "genomic"
317 | },
318 | "alignment": "overlay",
319 | "tracks": [
320 | {
321 | "mark": "text",
322 | "dataTransform": [
323 | {
324 | "type":"filter",
325 | "field": "Stain",
326 | "oneOf": [
327 | "acen"
328 | ],
329 | "not": true
330 | }
331 | ],
332 | "text": {
333 | "field": "Name",
334 | "type": "nominal"
335 | },
336 | "color": {
337 | "field": "Stain",
338 | "type": "nominal",
339 | "domain": [
340 | "gneg",
341 | "gpos25",
342 | "gpos50",
343 | "gpos75",
344 | "gpos100",
345 | "gvar"
346 | ],
347 | "range": [
348 | "black",
349 | "black",
350 | "black",
351 | "black",
352 | "white",
353 | "black"
354 | ]
355 | },
356 | "visibility": [
357 | {
358 | "operation": "less-than",
359 | "measure": "width",
360 | "threshold": "|xe-x|",
361 | "transitionPadding": 10,
362 | "target": "mark"
363 | }
364 | ],
365 | "style": {
366 | "textStrokeWidth": 0
367 | }
368 | },
369 | {
370 | "mark": "rect",
371 | "dataTransform": [
372 | {
373 | "type":"filter",
374 | "field": "Stain",
375 | "oneOf": [
376 | "acen"
377 | ],
378 | "not": true
379 | }
380 | ],
381 | "color": {
382 | "field": "Stain",
383 | "type": "nominal",
384 | "domain": [
385 | "gneg",
386 | "gpos25",
387 | "gpos50",
388 | "gpos75",
389 | "gpos100",
390 | "gvar"
391 | ],
392 | "range": [
393 | "white",
394 | "#D9D9D9",
395 | "#979797",
396 | "#636363",
397 | "black",
398 | "#A0A0F2"
399 | ]
400 | }
401 | },
402 | {
403 | "mark": "triangleRight",
404 | "dataTransform": [
405 | {
406 | "type":"filter",
407 | "field": "Stain",
408 | "oneOf": [
409 | "acen"
410 | ]
411 | },
412 | {
413 | "type":"filter",
414 | "field": "Name",
415 | "include": "q"
416 | }
417 | ],
418 | "color": {
419 | "value": "#B40101"
420 | }
421 | },
422 | {
423 | "mark": "triangleLeft",
424 | "dataTransform": [
425 | {
426 | "type":"filter",
427 | "field": "Stain",
428 | "oneOf": [
429 | "acen"
430 | ]
431 | },
432 | {
433 | "type":"filter",
434 | "field": "Name",
435 | "include": "p"
436 | }
437 | ],
438 | "color": {
439 | "value": "#B40101"
440 | }
441 | }
442 | ],
443 | "size": {
444 | "value": 20
445 | },
446 | "stroke": {
447 | "value": "gray"
448 | },
449 | "strokeWidth": {
450 | "value": 0.5
451 | }
452 | }
453 | ]
454 | },
455 | {
456 | "arrangement": "serial",
457 | "spacing": 100,
458 | "views": [
459 | {
460 | "layout": "linear",
461 | "tracks": [
462 | {
463 | "row": {
464 | "field": "sample",
465 | "type": "nominal"
466 | },
467 | "width": 300,
468 | "height": 100,
469 | "data": {
470 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
471 | "type": "multivec",
472 | "row": "sample",
473 | "column": "position",
474 | "value": "peak",
475 | "categories": [
476 | "sample 1",
477 | "sample 2",
478 | "sample 3",
479 | "sample 4"
480 | ]
481 | },
482 | "mark": "area",
483 | "x": {
484 | "field": "position",
485 | "type": "genomic",
486 | "domain": {
487 | "chromosome": "2"
488 | },
489 | "axis": "top"
490 | },
491 | "y": {
492 | "field": "peak",
493 | "type": "quantitative"
494 | },
495 | "color": {
496 | "field": "sample",
497 | "type": "nominal"
498 | }
499 | }
500 | ]
501 | },
502 | {
503 | "layout": "linear",
504 | "tracks": [
505 | {
506 | "row": {
507 | "field": "sample",
508 | "type": "nominal"
509 | },
510 | "width": 300,
511 | "height": 100,
512 | "data": {
513 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
514 | "type": "multivec",
515 | "row": "sample",
516 | "column": "position",
517 | "value": "peak",
518 | "categories": [
519 | "sample 1",
520 | "sample 2",
521 | "sample 3",
522 | "sample 4"
523 | ]
524 | },
525 | "mark": "area",
526 | "x": {
527 | "field": "position",
528 | "type": "genomic",
529 | "domain": {
530 | "chromosome": "5"
531 | },
532 | "axis": "top"
533 | },
534 | "y": {
535 | "field": "peak",
536 | "type": "quantitative"
537 | },
538 | "color": {
539 | "field": "sample",
540 | "type": "nominal"
541 | }
542 | }
543 | ]
544 | }
545 | ]
546 | }
547 | ]
548 | }
549 | ```
550 |
551 |
552 |
553 | ## Link Multiple Views
554 | We need to link the overview and the two detailed views.
555 | We overlay two `brush` objects to the overview, and link the two `brush` objects to the two detailed views using `linkingId` (i.e., "detail-1", "detail-2").
556 | To help users visually link the brush objects and the detailed views, we assign the same color to the `brush` of the overview and the `background` of the corresponding detailed view.
557 |
558 | **Overview**
559 | ```diff
560 | + "alignment": "overlay",
561 | + "tracks": [
562 | + {
563 | + "mark": "area"
564 | + },
565 | + {
566 | + "mark": "brush",
567 | + "x": {
568 | + "linkingId": "detail-1"
569 | + },
570 | + "color": {
571 | + "value": "blue"
572 | + }
573 | + },
574 | + {
575 | + "mark": "brush",
576 | + "x": {
577 | + "linkingId": "detail-2"
578 | + },
579 | + "color": {
580 | + "value": "red"
581 | + }
582 | + }
583 | + ]
584 | ```
585 |
586 | **Detailed View 1**
587 | ```diff
588 | + "linkingId": "detail-1",
589 |
590 | + "style": {
591 | + "background": "blue",
592 | + "backgroundOpacity": 0.1
593 | + }
594 | ```
595 |
596 | **Detailed View 2**
597 | ```diff
598 | + "linkingId": "detail-2",
599 |
600 | + "style": {
601 | + "background": "red",
602 | + "backgroundOpacity": 0.1
603 | + }
604 | ```
605 |
606 |
607 |
608 |
609 | Click here to expand the complete code
610 |
611 | ```javascript
612 | {
613 | "arrangement": "vertical",
614 | "views": [
615 | {
616 | "layout": "circular",
617 | "centerRadius": 0.6,
618 | "spacing": 5,
619 | "tracks": [
620 | {
621 | "width": 700,
622 | "height": 40,
623 | "data": {
624 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
625 | "type": "multivec",
626 | "row": "sample",
627 | "column": "position",
628 | "value": "peak",
629 | "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
630 | },
631 | "mark": "area",
632 | "x": {
633 | "field": "position",
634 | "type": "genomic",
635 | "axis": "top",
636 | "linkingId": "link-1"
637 | },
638 | "y": { "field": "peak", "type": "quantitative" },
639 | "color": { "field": "sample", "type": "nominal" },
640 | "alignment": "overlay",
641 | "tracks": [
642 | { "mark": "area" },
643 | {
644 | "mark": "brush",
645 | "x": { "linkingId": "detail-1" },
646 | "color": { "value": "blue" }
647 | },
648 | {
649 | "mark": "brush",
650 | "x": { "linkingId": "detail-2" },
651 | "color": { "value": "red" }
652 | }
653 | ]
654 | },
655 | {
656 | "width": 700,
657 | "height": 20,
658 | "data": {
659 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
660 | "type": "csv",
661 | "chromosomeField": "Chromosome",
662 | "genomicFields": ["chromStart", "chromEnd"]
663 | },
664 | "x": {
665 | "field": "chromStart",
666 | "type": "genomic",
667 | "linkingId": "link-1"
668 | },
669 | "xe": { "field": "chromEnd", "type": "genomic" },
670 | "alignment": "overlay",
671 | "tracks": [
672 | {
673 | "mark": "text",
674 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true }],
675 | "text": { "field": "Name", "type": "nominal" },
676 | "color": {
677 | "field": "Stain",
678 | "type": "nominal",
679 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
680 | "range": ["black", "black", "black", "black", "white", "black"]
681 | },
682 | "visibility": [
683 | {
684 | "operation": "less-than",
685 | "measure": "width",
686 | "threshold": "|xe-x|",
687 | "transitionPadding": 10,
688 | "target": "mark"
689 | }
690 | ],
691 | "style": { "textStrokeWidth": 0 }
692 | },
693 | {
694 | "mark": "rect",
695 | "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true }],
696 | "color": {
697 | "field": "Stain",
698 | "type": "nominal",
699 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
700 | "range": [
701 | "white",
702 | "#D9D9D9",
703 | "#979797",
704 | "#636363",
705 | "black",
706 | "#A0A0F2"
707 | ]
708 | }
709 | },
710 | {
711 | "mark": "triangleRight",
712 | "dataTransform": [
713 | {"type":"filter", "field": "Stain", "oneOf": ["acen"] },
714 | {"type":"filter", "field": "Name", "include": "q" }
715 | ],
716 | "color": { "value": "#B40101" }
717 | },
718 | {
719 | "mark": "triangleLeft",
720 | "dataTransform": [
721 | {"type":"filter", "field": "Stain", "oneOf": ["acen"] },
722 | {"type":"filter", "field": "Name", "include": "p" }
723 | ],
724 | "color": { "value": "#B40101" }
725 | }
726 | ],
727 | "size": { "value": 20 },
728 | "stroke": { "value": "gray" },
729 | "strokeWidth": { "value": 0.5 }
730 | }
731 | ]
732 | },
733 | {
734 | "arrangement": "serial",
735 | "spacing": 20,
736 | "views": [
737 | {
738 | "layout": "linear",
739 | "tracks": [
740 | {
741 | "row": { "field": "sample", "type": "nominal" },
742 | "width": 340,
743 | "height": 300,
744 | "data": {
745 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
746 | "type": "multivec",
747 | "row": "sample",
748 | "column": "position",
749 | "value": "peak",
750 | "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
751 | },
752 | "mark": "area",
753 | "x": {
754 | "field": "position",
755 | "type": "genomic",
756 | "domain": { "chromosome": "2" },
757 | "linkingId": "detail-1",
758 | "axis": "top"
759 | },
760 | "y": { "field": "peak", "type": "quantitative" },
761 | "color": { "field": "sample", "type": "nominal" },
762 | "style": { "background": "blue", "backgroundOpacity": 0.1 }
763 | }
764 | ]
765 | },
766 | {
767 | "layout": "linear",
768 | "tracks": [{
769 | "row": { "field": "sample", "type": "nominal" },
770 | "width": 340,
771 | "height": 300,
772 | "data": {
773 | "url": "https://resgen.io/api/v1/tileset_info/?d=UvVPeLHuRDiYA3qwFlm7xQ",
774 | "type": "multivec",
775 | "row": "sample",
776 | "column": "position",
777 | "value": "peak",
778 | "categories": ["sample 1", "sample 2", "sample 3", "sample 4"]
779 | },
780 | "mark": "area",
781 | "x": {
782 | "field": "position",
783 | "type": "genomic",
784 | "domain": { "chromosome": "5" },
785 | "linkingId": "detail-2",
786 | "axis": "top"
787 | },
788 | "y": { "field": "peak", "type": "quantitative" },
789 | "color": { "field": "sample", "type": "nominal" },
790 | "style": { "background": "red", "backgroundOpacity": 0.1 }
791 | }]
792 | }
793 | ]
794 | }
795 | ]
796 | }
797 | ```
798 |
--------------------------------------------------------------------------------
/tutorials/create-single-track-visualization.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Create Single Track Visualization
3 | hide_title: false
4 | slug: /
5 | ---
6 |
7 | This tutorial will guide you step by step in writing the JSON specification to create an interactive cytoband visualization in Gosling.
8 | You will learn about:
9 | - [Loading Data](#loading-data)
10 | - [Encoding Data with Marks](#encoding-data-with-marks)
11 | - [Transforming Data](#transforming-data)
12 | - [Overlaying Multiple Marks](#overlaying-multiple-marks)
13 | - [Coming Up Next](#coming-up-next)
14 |
15 | You are encouraged to follow the tutorial and create visualizations in the [online editor][onlineEditorURL].
16 |
17 | ## Loading Data
18 |
19 | In this tutorial, we use a CSV data that contains UCSC hg38 cytoband information ([the complete data file][csvDataURL]).
20 |
21 |
22 |
23 | |Chromosome|chromStart|chromEnd|Name|Stain|
24 | |---|---|---|---|--|
25 | |chr1|0|2300000|p36.33|gneg|
26 | |chr1|2300000|5300000|p36.32|gpos25|
27 | |chr1|5300000|770000|p36.31|gneg|
28 | |...|
29 |
30 |
31 | To start with, we load this data through URL to a visualization (i.e., a `track`).
32 | The `track.data` property specifies how to fetch and process the data.
33 | ```javascript
34 |
35 | {
36 | "tracks":[{
37 | // Load a csv data file through URL
38 | "data": {
39 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
40 | "chromosomeField": "Chromosome",
41 | "type": "csv",
42 | "genomicFields": ["chromStart", "chromEnd"]
43 | }
44 | }]
45 | }
46 | ```
47 |
48 | ## Encoding Data with Marks
49 | After loading the data, we now specify how to visualize the data.
50 | This process is achieved by binding the values of data fields to the visual channels (e.g., color, size) of a graphic element (i.e., `mark`).
51 |
52 | Let's say we use a `rect` mark for the loaded csv data.
53 | Each `rect` represents a chromosome.
54 | The x-coordinate of the mark's start (`x`) and end (`xe`) position indicate the chromStart and the chromeEnd, respectively.
55 | The `color` indicates the stain value.
56 |
57 | For each visual channel, Gosling creates a mapping from the values of the data field (e.g., [gnes, gpos25, gpos50, ...]) to the values of the visual channel (e.g., color). We call the values of data field **domain** and the values of the visual channel **range**.
58 | This mapping is specified by the following properties:
59 |
60 | | visual channel properties | type | description |
61 | | ------------------------- | --------------------------- | ---------------------------------------------------------------------------------- |
62 | | field | string | specify name of the data field |
63 | | type | string | specify type of the data field. support `"genomic"`, `"nominal"`, `"quantitative"` |
64 | | domain | [number, number]\| string[] | specify values of the data field |
65 | | range | [number, number]\| string[] | specify values of the visual channel |
66 |
67 |
68 | ```javascript
69 | {
70 | "tracks":[{
71 | // specify the size of the visualization
72 | "width": 700,
73 | "height": 70,
74 | // Load a csv data file through URL
75 | "data": {
76 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
77 | "chromosomeField": "Chromosome",
78 | "type": "csv",
79 | "genomicFields": ["chromStart", "chromEnd"]
80 | },
81 | // specify the mark type
82 | "mark": "rect",
83 | // encoding data with visual channels
84 | "x": {
85 | "field": "chromStart",
86 | "type": "genomic",
87 | "domain": {"chromosome": "1"},
88 | "axis": "top"
89 | },
90 | "xe": {"field": "chromEnd", "type": "genomic"},
91 | "color": {
92 | "field": "Stain",
93 | "type": "nominal",
94 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
95 | "range": ["white","#D9D9D9","#979797","#636363", "black","#A0A0F2"]
96 | },
97 | // customize the style of the visual marks.
98 | // default values will be used if not specifyed.
99 | "size": {"value": 20},
100 | "stroke": {"value": "gray"},
101 | "strokeWidth": {"value": 0.5}
102 | }]
103 | }
104 | ```
105 |
106 |
107 |
108 | **:tada: :tada: :tada: :tada: :tada: :tada: :tada: :tada:**
109 | **You have just created a scalable and interactive visualization in Gosling!**
110 | You can interact with the visualization you just created in the online editor through zoom and pan.
111 | Or, you can keep reading the tutorial and make your visualizations even more fancy.
112 |
113 | ## Transforming Data
114 | Gossling supports filtering out uninterested data through the `dataTransform` property.
115 | For example, we can add a filter to only visualize chromosomes whose stain result is one of "gpos25", "gpos50", "gpos75", or "gpos100".
116 |
117 | ```diff
118 | {
119 | "tracks":[{
120 | "width": 700,
121 | "height": 70,
122 | "data": {
123 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
124 | "chromosomeField": "Chromosome",
125 | "type": "csv",
126 | "genomicFields": ["chromStart", "chromEnd"]
127 | },
128 | + "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["gpos25", "gpos50", "gpos75", "gpos100"]}],
129 | "mark": "rect",
130 | "x": {
131 | "field": "chromStart",
132 | "type": "genomic",
133 | "domain": {"chromosome": "1"},
134 | "axis": "top"
135 | },
136 | "xe": {"field": "chromEnd", "type": "genomic"},
137 | "color": {
138 | "field": "Stain",
139 | "type": "nominal",
140 | "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
141 | "range": ["white","#D9D9D9","#979797","#636363", "black","#A0A0F2"]
142 | },
143 | "size": {"value": 20},
144 | "stroke": {"value": "gray"},
145 | "strokeWidth": {"value": 0.5}
146 | }]
147 | }
148 | ```
149 |
150 |
151 |
152 | gvar (purple rect) and gneg (white rect) are not shown in the updated visualization.
153 |
154 |
155 |
156 |
157 |
158 | ## Overlaying Multiple Marks
159 | Multiple `mark` shapes can be put on the top of one another by setting `alignment` as `"overlay"`.
160 | In the code below, a chromosome is visualized as a `triangleRight` mark if its stain result is `acen` and its name includes `q`; a chromosome is visualized as a `triangleLeft` mark if its stain result is `acen` and its name includes `p`. The `rect` mark, the `triangleRight` mark, and the `triangleLeft` mark are overlaid on the same genomic coordinate by setting `alignment` as `"overlay"`.
161 |
162 | ```diff
163 | {
164 | "tracks":[{
165 | "width": 700,
166 | "height": 70,
167 | "data": {
168 | "url": "https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv",
169 | "type": "csv",
170 | "chromosomeField": "Chromosome",
171 | "genomicFields": ["chromStart", "chromEnd"]
172 | },
173 | - "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["gpos25", "gpos50", "gpos75", "gpos100"]}],
174 | - "mark": "rect",
175 | "x": {
176 | "field": "chromStart",
177 | "type": "genomic",
178 | "domain": {"chromosome": "1"},
179 | "axis": "top"
180 | },
181 | "xe": {"field": "chromEnd", "type": "genomic"},
182 | - "color": {
183 | - "field": "Stain",
184 | - "type": "nominal",
185 | - "domain": ["gpos25", "gpos50", "gpos75", "gpos100"],
186 | - "range": ["#D9D9D9","#979797","#636363", "black"]
187 | - },
188 | + "alignment": "overlay",
189 | + "tracks":[
190 | + {
191 | + "mark": "rect",
192 | + "dataTransform": [{"type":"filter", "field": "Stain", "oneOf": ["acen"], "not": true}],
193 | + "color": {
194 | + "field": "Stain",
195 | + "type": "nominal",
196 | + "domain": ["gneg", "gpos25", "gpos50", "gpos75", "gpos100", "gvar"],
197 | + "range": ["white","#D9D9D9","#979797","#636363", "black","#A0A0F2"]
198 | + }
199 | + },
200 | + {
201 | + "mark": "triangleRight",
202 | + "dataTransform": [
203 | + {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
204 | + {"type":"filter", "field": "Name", "include": "q"}
205 | + ],
206 | + "color": {"value": "#B70101"}
207 | + },
208 | + {
209 | + "mark": "triangleLeft",
210 | + "dataTransform": [
211 | + {"type":"filter", "field": "Stain", "oneOf": ["acen"]},
212 | + {"type":"filter", "field": "Name", "include": "p"}
213 | + ],
214 | + "color": {"value": "#B70101"}
215 | + }
216 | + ],
217 | "size": {"value": 20},
218 | "stroke": {"value": "gray"},
219 | "strokeWidth": {"value": 0.5}
220 | }]
221 | }
222 | ```
223 |
224 |
225 |
226 |
227 | ## Coming Up Next
228 | [Tutorial 2](https://github.com/gosling-lang/gosling-docs/blob/master/tutorials/create-multi-track-visualization.md): how to use semantic zooming, multiple tracks, and circular layout in Gosling.
229 |
230 | [Tutorial 3](https://github.com/gosling-lang/gosling-docs/blob/master/tutorials/create-multi-view-visualization.md): how to arrange and link multiple views in Gosling.
231 |
232 | You can find more examples [here][exampleURL].
233 |
234 | [onlineEditorURL]: http://gosling.js.org
235 | [exampleURL]: http://gosling.js.org
236 | [csvDataURL]: https://raw.githubusercontent.com/sehilyi/gemini-datasets/master/data/UCSC.HG38.Human.CytoBandIdeogram.csv
237 |
--------------------------------------------------------------------------------