Skip to content

Commit

Permalink
Merge pull request #1 from EvoAlias/master
Browse files Browse the repository at this point in the history
Edited Docs Section
  • Loading branch information
EvoAlias committed Oct 3, 2018
2 parents c385e1a + 86c67b7 commit 3471aa6
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 247 deletions.
119 changes: 62 additions & 57 deletions docs/datahub.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ Pasted below is an example data hub for mouse mm10:
"url": "https://wangftp.wustl.edu/~dli/test/TW463_20-5-bonemarrow_MeDIP.bigWig",
"name": "MeDIP",
"options": {
"color": "red"
"color": "red",
"backgroundColor":"#FFE7AB"
},
"metadata": {
"sample": "bone",
Expand All @@ -52,7 +53,8 @@ Pasted below is an example data hub for mouse mm10:
"url": "https://wangftp.wustl.edu/~dli/test/TW551_20-5-bonemarrow_MRE.CpG.bigWig",
"name": "MRE",
"options": {
"color": "blue"
"color": "blue",
"backgroundColor":"#C0E3CC"
},
"metadata": {
"sample": "bone",
Expand All @@ -76,7 +78,7 @@ Example bigWig track
}
}
Supported options: color_, color2_, yScale_, yMax_, yMin_
Supported options: backgroundColor_, color_, color2_, yScale_, yMax_, and yMin_

Track properties
----------------
Expand All @@ -102,37 +104,41 @@ type
name
~~~~

*Requried*. ``name`` specifies the track name used internally by the browser. It's aso used for
display as track legend if no label_ speficied. Value can be any string.
*Requried*. ``name`` specifies the track name used internally by the browser. It is also
displayed as the track legend if no label_ speficied. Value can be any string.

label
~~~~~

*Optional*. ``label`` specifies the track legend displayed in the browser. It overrites the name_ arrtibute.
*Optional*. ``label`` specifies the track legend displayed in the browser. It overrides the name_ arrtibute.
Value can be any string.

url
~~~

*Requried*. ``url`` contains the URL to the track file, need to be HTTP or HTTPS location string.

.. important:: ``url`` is requried for all the tracks in binary format. While for gene annotaion tracks
like ``refGene``, it's not requried, since the data are stored in Mongo database. Another
case is ``ruler`` track, ``url`` is also not needed.
*Requried*. ``url`` contains the URL to the track file and needs to be HTTP or HTTPS location string.

.. important:: A ``url`` is requried for all the tracks in binary format. Gene annotaion tracks,
like ``refGene``, do not need a ``url`` as they are stored in the Mongo database.
Additional annotation tracks, such as the ``ruler`` track, also do not need a ``url``.

.. caution:: Each user-provided ``url`` must link to a publically available website, without password
protection, so that the browser can read in the file.

metadata
~~~~~~~~

*Optional*. An object speficies the metadata of the track. Examples like::
*Optional*. An object specifying the metadata of the track.

In this basic example the value of each metadata term is a **string**. ::

"metadata": {
"sample": "bone",
"assay": "MRE"
}

the value of each metadata term can be a **string** or a **list of string** with *hirarchical structure*, for
example, the public Roamap hub have metadata definition like::
This example public Roadmap data hub has more complex metadata definitions and makes use of a **list of strings**
to build a *hierarchical structure*. ::

{
"url": "https://egg.wustl.edu/d/hg19/GSM997242_1.bigWig",
Expand Down Expand Up @@ -165,15 +171,15 @@ example, the public Roamap hub have metadata definition like::
"name": "H3K9me3 of CD4+_CD25-_Th_Primary_Cells"
}

The list of metadata has order from more generic to more specific, and
this helps build the facet table hierarchy, make **search** and **filter** in track table easier.
The list of metadata is ordered from more generic to more specific and
helps build the facet table hierarchy making the **search** and **filter** functions in track table easier.

details
~~~~~~~

*Optional*. If you want to more information to be shown on right click the track, you can put
them in ``details`` attribute, contents put here will be displayed when right click the track,
and toggle the **More Information** dropdown menu::
*Optional*. If you want to add more information for each track then the ``details`` attribute is helpful.
After right clicking on the track you can click **More Information** and see the
``details``, ``url``, and ``metadata`` for each track in the dropdown menu. ::

"details": {
"data source": "Roadmap Project",
Expand All @@ -184,67 +190,66 @@ options
~~~~~~~

*Optional*. All track render options are placed in an object called ``options``.
this object can have the following properties:
This object can have the following properties:

color
^^^^^
color
^^^^^

``color`` is used to define the color for the track, color name, RGB values can be used.
For more about color name or RGB, please check https://www.w3schools.com/css/css_colors.asp.
``color`` is used to define the color for each track. A color name, RGB values, or hex color code can be used.
For more about color name or RGB please see https://www.w3schools.com/css/css_colors.asp.

color2
^^^^^^
color2
^^^^^^

``color2`` is used to define the color for negative values from the track data. Default is
the same as color_.
``color2`` is used to define the color for negative values from the track data. The default is
the same as color_.

backgroundColor
backgroundColor
^^^^^^^^^^^^^^^

``backgroundColor`` defines the background color of the track.
``backgroundColor`` defines the background color of the track.

height
^^^^^^
height
^^^^^^

``height`` controls the height of the track, speficied in number, unit is *pixel*.
``height`` controls the height of the track which is specified as a number and displayed in *pixels*.

yScale
^^^^^^
yScale
^^^^^^

``yScale`` allows you to configure the track's y-scale, you can use *auto* or *fixed*
here. *auto* means the y-scale will be calculated from the values in view region, from 0
to maximal of values in view region. *fixed* means you can specify the *minimal* and *maximal* value.
``yScale`` allows you to configure the track's y-scale. Options include *auto* or *fixed*.
*auto* sets the y-scale from 0 to the max value of values in the view region for a given track.
*fixed* means you can specify the *minimal* and *maximal* value.

yMax
^^^^
yMax
^^^^

``yMax`` used to define the *maximal* value of track y-axis. Value is number.
``yMax`` is used to define the *maximum* value of a track's y-axis. Value is number.

yMin
^^^^
yMin
^^^^

``yMin`` used to define the *minimal* value of track y-axis. Value is number.
``yMin`` is used to define the *minimum* value of a track's y-axis. Value is number.

.. important:: If you need the track to be in *fixed* scale, you need to specify ``yScale`` to *fixed*
besides of set ``yMax`` and ``yMin``.

colorAboveMax
^^^^^^^^^^^^^

``colorAboveMax`` defines the color when yScale_ set to *fixed*, and the value exceeds the value
yMax_ defined.
colorAboveMax
^^^^^^^^^^^^^

color2BelowMin
^^^^^^^^^^^^^^
``colorAboveMax`` defines the color displayed when a *fixed* yScale_ is used and a value exceeds the
yMax_ defined.

``color2BelowMin`` defines the color when yScale_ set to *fixed*, and the value below the value
yMin_ defined.
color2BelowMin
^^^^^^^^^^^^^^

displayMode
^^^^^^^^^^^
``color2BelowMin`` defines the color displayed when a *fixed* yScale_ is used and a value is below the
yMin_ defined.

``displayMode`` specifies display mode for tracks, different tracks have different display mode
supported.
displayMode
^^^^^^^^^^^

``displayMode`` specifies display mode for each tracks. Different tracks have different display modes as listed below.

.. list-table::
:widths: 25 50
Expand Down
93 changes: 45 additions & 48 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,21 @@ Installation

Setup
-----
* install NodeJS from https://nodejs.org/en/
* install MongoDB from https://www.mongodb.com/
* Install NodeJS from https://nodejs.org/en/
* Install MongoDB from https://www.mongodb.com/

.. note:: Feel free to use any package manager tool on your system to install them. Like ``brew`` etc.
.. note:: Feel free to use any package manager tool on your system for installation (``brew``\ , etc.).

Then enter the ``backend`` directory. Type
``npm install``\ , and then ``npm run setup``. This step will load the gene annotation data
to MongoDB database. (Make sure MongoDB server is running). Go to the ``frontend`` directory,
type ``npm install`` to install dependent packages.
Enter the ``backend`` directory. Type ``npm install`` and then ``npm run setup``. This step will load the gene annotation data to the MongoDB database. (Make sure the MongoDB server is running). Go to the ``frontend`` directory and type ``npm install`` to install dependent packages.

Start the browser
-----------------

#. Make sure MongoDB is running
#. Enter the ``backend`` directory
#. type ``npm start``
#. Type ``npm start``
#. Enter the ``frontend`` directory
#. type ``npm start``
#. Type ``npm start``

The browser is now accessible from http://localhost:3000/browser.

Expand All @@ -34,25 +31,25 @@ The client code is in the ``frontend`` folder. Here is a quick tour of ``fronte

* ``components``\ : All React components.

* ``genomeNavigator``\ : the navigation bar at the top that allows users to navigate
* ``track``\ : track-related components
* ``genomeNavigator``\ : The navigation bar at the top that allows users to navigate
* ``track``\ : Track-related components
* ``trackManagers``\ : UI that manages adding tracks

* ``dataSources``\ : API calls, AJAX calls, database connections, etc. that get data to display.
* ``model``\ : data models.
* ``stories``\ : stories for Storybook, on which unit tests depend.
* ``model``\ : Data models.
* ``stories``\ : Stories for Storybook on which unit tests depend.
* ``vendor``\ : 3rd-party libraries that are not in NPM.

Suggested order of reading
~~~~~~~~~~~~~~~~~~~~~~~~~~

If you plan to understand the app as a whole, here's a suggested order of code to read:
If you plan to understand the app as a whole here is a suggested order to read the code in:

#. ``Feature``\ : a feature or annotation in the genome
#. ``NavigationContext``\ : a list of ``Feature`` that represents everywhere a user can navigate. If the ``Feature``\ s are
actually entire chromosomes, then the user can effectively navigate the whole genome.
#. ``DisplayedRegionModel``\ : an interval in a ``NavigationContext``
#. ``App``\ : the root component of the app
#. ``Feature``\ : A feature or annotation in the genome.
#. ``NavigationContext``\ : A list of ``Feature``\ s that represent everywhere a user can navigate. If the ``Feature``\ s are
actually entire chromosomes then the user can effectively navigate the whole genome.
#. ``DisplayedRegionModel``\ : An interval in a ``NavigationContext``\ .
#. ``App``\ : The root component of the app.
#. From ``App``\ , descend into interested components.

Making a new track type
Expand All @@ -61,16 +58,16 @@ Making a new track type
Make a new TrackConfig
^^^^^^^^^^^^^^^^^^^^^^

Make a new class that extends ``TrackConfig``\ , or one of its subclasses. This class packages many essential track
Make a new class that extends ``TrackConfig``\ or one of its subclasses. This class packages many essential track
characteristics:

* ``getComponent()`` - gets the component that renders the main visualizer and legend of the track.
* ``getMenuComponents()`` - specifies context menu items in an array of components. You can choose existing ones
in the ``contextMenu`` directory, or make new ones.
* ``getOptions()`` - the visualizer probably renders with default options, like a color. This method returns a plain
* ``getComponent()`` - Gets the component that renders the main visualizer and legend of the track.
* ``getMenuComponents()`` - Specifies context menu items in an array of components. You can choose existing ones
in the ``contextMenu`` directory or make new ones.
* ``getOptions()`` - The visualizer probably renders with default options like a color. This method returns a plain
object containing those options.

You do not have to implement these methods immediately, as the base ``TrackConfig`` class provides minimal defaults.
You do not have to implement these methods immediately as the base ``TrackConfig`` class provides minimal defaults.
Just work on making the browser render *some* temporary placeholder at first.

Specify when to use the TrackConfig
Expand All @@ -82,23 +79,23 @@ Specify when to use the TrackConfig
Write a new track visualizer component (implement ``getComponent()``\ )
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

#. Make a new component expecting to receive a bunch of props from ``TrackContainer``. ``Track.js`` documents the props
#. Make a new component expecting to receive a bunch of props from ``TrackContainer``. ``Track.js`` documents the props
to expect.
#. If you need data, assume it will come through the ``data`` prop. We will add data fetch in the next step.
#. Your new component may ``render`` anything, though it is **highly** recommended you render a ``<Track>`` component, if
#. If you need data assume it will come through the ``data`` prop. We will add data fetch in the next step.
#. Your new component may ``render`` anything though it is **highly** recommended you render a ``<Track>`` component, if
not one of the more specialized components like ``<AnnotationTrack>`` or ``<NumericalTrack>``. Pass *all* track container
props to these sub-components.
#. In addition to track container props, you need to provide certain props to these sub-components, all of which the
#. In addition to track container props you need to provide certain props to these sub-components, all of which the
respective files document.

* For example, ``<Track>`` requires a legend and visualizer element. Use the track container props, which includes
* For example, ``<Track>`` requires a legend and visualizer element. Use the track container props, which includes
view region and width, to render a visualizer and pass it to ``<Track>``.

Add data fetch
^^^^^^^^^^^^^^

Available data sources are in the ``dataSources`` folder. If none of them fulfill your needs, write a new class that
fulfills the interface of ``DataSource.js``. More can be found in that file.
Available data sources are in the ``dataSources`` folder. If none of them fulfill your needs, write a new class that
fulfills the interface of ``DataSource.js``. More can be found in that file.

How do we give your visualizer data? `Higher-order components <https://reactjs.org/docs/higher-order-components.html>`_\ !
``track/commonComponents`` contains track-specific HOCs; their names start with ``config-`` or ``with-``.
Expand All @@ -111,51 +108,51 @@ components. After you use this function, a component will automatically receive
2. Specify context menu components (implement ``getMenuComponents()``\ )
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Specify context menu items with an array of components. You can choose existing ones in the ``contextMenu`` directory, or
Specify context menu items with an array of components. You can choose existing ones in the ``contextMenu`` directory or
make new ones.

* Make sure the method returns Component *classes*\ , not component instances.

3. Specify default options
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Default option objects look like the ``options`` prop of ``TrackModel`` objects. Context menu items will read these options
if the track model does not specify them. Make sure these options are consistent with the way you are rendering your
track component! The ``configOptionMerging`` HOC should help with that.
Default option objects look like the ``options`` prop of ``TrackModel`` objects. Context menu items will read these options
if the track model does not specify them. Make sure these options are consistent with the way you are rendering your
track component! The ``configOptionMerging`` HOC should help with that.

Once you have a default options object, call ``setDefaultOptions()`` in the constructor of ``TrackConfig`` to use them.

Performance tips
~~~~~~~~~~~~~~~~

Querying the width or height of any element, for example through ``clientWidth`` or ``getBoundingClientRect()``\ , is slow.
Such queries take on the order of 2 to 20 ms. While it is fine to do it once or twice, avoid doing it in a loop.
Suppose you aim to plot 500 data points on a SVG, and for each point you query the SVG's width. That is already a
Querying the width or height of any element, for example through ``clientWidth`` or ``getBoundingClientRect()``\ is slow.
Such queries take on the order of 2 to 20 ms. While it is fine to do it once or twice, avoid doing it in a loop.
Suppose you aim to plot 500 data points on a SVG and for each point you query the SVG's width. That is already a
second or more of computation -- very noticable to the user!

React (and other) gotchas
~~~~~~~~~~~~~~~~~~~~~~~~~

* On Macs, control + click is the same as a right click, which fires a ``contextmenu`` event. Note that ``click`` events
do not fire on ``contextmenu`` events. The ``mousedown`` and ``mouseup`` events will still fire, though.
* When using native DOM events, they take priority over React events. This is because React waits for events to bubble
to the root component before handling them. This can cause undesirable effects: for example, calling
``stopPropagation()`` on a React event will not actually stop native events. This StackOverflow post may also help if you
* On Macs, control + click is the same as a right click which fires a ``contextmenu`` event. Note that ``click`` events
do not fire on ``contextmenu`` events. The ``mousedown`` and ``mouseup`` events will still fire though.
* When using native DOM events they take priority over React events. This is because React waits for events to bubble
to the root component before handling them. This can cause undesirable effects: for example, calling
``stopPropagation()`` on a React event will not actually stop native events. This StackOverflow post may also help if you
have propagation problems: https://stackoverflow.com/questions/24415631/reactjs-syntheticevent-stoppropagation-only-works-with-react-events
* React *always* unmounts components if their parents change type. The ``Reparentable`` component works around this by
using app-unique IDs, but it can cause side effects with React's native events. Use with care.
* React *always* unmounts components if their parents change type. The ``Reparentable`` component works around this by
using app-unique IDs, but it can cause side effects with React's native events. Use with care.
* Webpack does not support circular dependencies, and while compilation may be successful, an import may resolve as
``undefined`` at runtime.

Lessons trying to refactor into WebWorkers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#. Data fetch and track display options are intimately related. For example, what if someone wants HiC data and
#. Data fetch and track display options are intimately related. For example, what if someone wants HiC data and
selects the 5KB resolution option?
#. Thus, for each track type, we have one object that gets the track component, default rendering options, and data
fetch/processing.
#. Webpack hangs forever if it encounters a cyclic dependency involving a webworker.
#. The code as in (2) causes a cyclic depdendency. This cycle is [config object] --> [data source] --> [worker] -->
#. The code as in (2) causes a cyclic depdendency. This cycle is [config object] --> [data source] --> [worker] -->
[track config deserializer] --> [config object]
#. We cannot have our cake and eat it too.

Expand Down

0 comments on commit 3471aa6

Please sign in to comment.