Skip to content

Introduction to Front End

Matt Whiteside edited this page Aug 18, 2016 · 58 revisions

Table of Contents

INTRODUCTION

This is an introduction to the front-end of the SuperPhy application. It will cover the combination of software products and programming languages that are currently being used to create the application. Applications typically have two software components: client-side and server-side (also known as front-end and back-end). The front-end tech stack consists of:

  • Coffeescript
  • Mithril.js

COFFEESCRIPT

What is CoffeeScript (CS)? How is it different from JavaScript (JS)?

CoffeeScript is basically a shorthand of JavaSciript. In fact, it compiles directly into JavaScript. It's an open-source project that provides a simpler and more readable syntax for JavaScript. Code written in .coffee files are not interpreted at run time, like JavaScript, instead they are compiled into .js files.

Before learning CoffeeScript, I first brushed up on my JavaScript knowledge. It is important to know JS because you need to have a good grasp of it in order for you to successfully understand and debug CS. It's a very concise language which makes it easy to miss what's happening in your code, especially if you don't have a good background knowledge of the underlying language (JS). CS has comparatively less code (no curly braces, semi-colons, e.t.c.) than JS, and it's syntax is closer to natural language than JS. Below is a comparison of the two languages.

JavaScript:

 var myFunc;

 myFunc = function (myList) {
    for(var x in myList) {
      console.log(x);
    }
 };

/*
 The syntax for JS is typical to most programming languages
*/

And CoffeeScript:

myFunc = (myList) ->
    for x of myList
        console.log x
  return

###
 Notice the syntax is simpler
###

How do I learn CoffeeScript?

You should start by working through this JavaScript course on Codecademy, if you don't know JS already. Then go to the various websites listed in the resources page and work through some examples of CS on your own. Don't be afraid to jump in and start working on a feature in your copy of the SuperPhy code, change things and see what happens.

There is also a CoffeeScript tutorial once you are familiar with JS. It should help you with understanding some concepts in CS and Mithril (discussed below).

Structuring classes

Creating objects in CS is very similar to JS in syntax and logic. When creating classes, you use the class keyword, and write a function that is invoked upon instantiation (a contructor). When creating an instance of the class, you use the new keyword. When a new instance of a class is created, the constructor of the parent class is invoked (unless you overwrite it).

It's also important to know that there the function in the class named constructor is similar to the __init__ function in Python. Again, similar to python and JS, the keyword this is used in a similar way. Inside a class definition, this refers to the class object. In other words you can set class properties by setting them directly on this.

What front-end features are currently being developed?

  • The Group Browse pape.
    • Table view.
    • Map view.
    • Tree view.
  • The VF & AMR feature.
  • Styling on various pages.

MITHRIL

What is Mithril and why do we use it?

Mithril is a front-end MVC JavaScript Framework for building applications. A framework is used to organize code in an easily understandable and maintanable way. It is a comparatively fast and simple JS framework. It's syntax is similar to HTML and CSS (but in JavaScript), which makes it familiar and easy to understand if you know HTML or CSS.

Look at some Mithril code:

m(".panel.panel-default", [
        m(".panel-heading", [
            m("h3.panel-title", "Panel title")
        ]),
        m(".panel-body", [
            "Panel content"
        ])
])

And the equivalent HTML...

 <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">Panel title</h3>
        </div>
        <div class="panel-body">
            Panel content
        </div>
 </div>
    

Mithril's Flow of Control

Below you will find more information about the development of the front-end, the file structures on GitHub, and a description and reasoning behind the separation of Model, Component, and Pages.

MAKING COMPONENTS

Each component class should at least have a view method (controllers are optional).

Class components
  • When creating a class component, make sure the controller does return @, otherwise the arguments will not be accessible in the view.

The front-end pages are mostly based on the component system of Mithril.js. Each component class should at least have a view method (controllers are optional). In coffeescript, if the component is a class and it has a controller object with other variables/methods in it, it can be passed to the view if you return @ (equivalent to this in javascript).

Example
class Foo
    controller: (args) ->
        @someString = args.arg1
        @method1= () ->
            console.log(args.arg2)
        return @
    view: (ctrl, args) ->
        ctrl.method1() ## Logs "world"
        m('.', "Some div")
App =
    m.component(Foo, {
        arg1: "hello"
        arg2: "world"
    })

In the example above, the object {arg1: "hello", arg2: "world"} is passed in as an argument to Foo, and can be accessed through the args parameter (in both the controller and view). Furthermore, the controller can be accessed in the view through the ctrl parameter.

WARNING: Do not put request methods in a view, as views are redrawn for most user actions like scrolling. Use a config method instead (see Matrix component for example).

FRONT-END STRUCTURE

mithril
├── bower_components
│   └── mithril-components
├── coffee
│   ├── Components
│   ├── Models
│   └── Pages
│       └── Auth
├── coffee_old
├── css
│   └── font-awesome-4.5.0
├── images
├── js
│   └── d3
└── less
"bower-components"

Currently only has the mithril components by eddyystop

"coffee" folder

Holds all the coffee files for the front-end pages. Folder is split up into more directories:

All .coffee files are compiled into a one-page Javascript file.

"coffee_old" files

Old Coffeescript code. Most likely not relevant anymore.

"css" files

Compiled CSS from the less files, in addition to CSS libraries (i.e. Font Awesome and Bootstrap). All of these files are gitignored.

"less" files

All Less styling files.

DESIGN

TODO: Describe organisation here...

Pages

  1. Genome Explorer
  2. Group Builder - Map
  3. Group Builder - Tree
  4. Group Builder - Metadata Table
  5. Group Builder - AMR
  6. Group Builder - VF. See Group Builder - AMR
  7. Group Builder - Create
  8. Group Builder - Modify/Merge
  9. Genome Analysis - Select
  10. Genome Analysis - Epidemiological Visualisation
  11. Genome Analysis - Select AMR
  12. Genome Analysis - Select VF. See Genome Analysis - Select AMR
  13. Genome Analysis - Gene Distribution
  14. Genome Analysis - Gene Info
  15. Genome Analysis - Predictive Genomics
  16. Genome Analysis - Predictive Genomics Results

Models

GroupModel

GroupModel contains a subset of genomes and associated metadata. There may need to be a cap on the size of a group. GroupModels contains a collection of groups that are active on a page. This class is an interface to the groups and triggers actions for all groups in collection as well as individual group actions. GroupModelPlus extends the parent GroupModel; it also contains gene linkages for group members. GroupModel and GroupModel models are used in pages:

  1. Genome Explorer
  2. Group Builder - Map
  3. Group Builder - Tree
  4. Group Builder - Metadata Table
  5. Group Builder - AMR
  6. Group Builder - VF. See Group Builder - AMR
  7. Group Builder - Create
  8. Group Builder - Modify/Merge
  9. Genome Analysis - Select
  10. Genome Analysis - Epidemiological Visualisation
  11. Genome Analysis - Select AMR
  12. Genome Analysis - Select VF
  13. Genome Analysis - Gene Info

GroupList

GroupList lists several selectable groups

  1. Genome Explorer
  2. Group Builder - Create
  3. Group Builder - Modify/Merge

GenomeNames

GenomeNames model is used in pages:

  1. Genome Explorer

GenomeLocations

Contains a summary of visible genomes locations. GenomeLocations model is used in pages:

  1. Group Builder - Map
  2. Genome Analysis - Epidemiological Visualisation

GenomePhylo

Contains a summary of genome phylogeny for different tree resolutions. GenomePhylo model is used in pages:

  1. Group Builder - Tree
  2. Genome Analysis - Epidemiological Visualisation

GenomeMetaPage

A subset of genome metadata. GenomeMetaPage model is used in pages:

  1. Group Builder - Metadata Table

Genes

One or more gene features can be linked to each genome. Async requests may be needed if the number of genomes linked is too large. Genes model is used in pages:

  1. Group Builder - AMR
  2. Group Builder - VF
  3. Genome Analysis - Select AMR
  4. Genome Analysis - Select VF

Components

BuildMenu

BuildMenu component is used in pages:

  1. Genome Explorer

GroupMenu

GroupMenu component is used in pages:

  1. Genome Explorer

GenomeWidget

GenomeWidget coordinates genome visualisation components (e.g. Map, Tree) with state components (e.g. GenomeList) and controls (e.g. MetadataDisplayControl). SelectionGenomeWidget and DisplayGenomeWidget extend the parent GenomeWidget. It is used in pages:

  1. Group Builder - Map
  2. Group Builder - Tree
  3. Group Builder - Metadata Table
  4. Group Builder - AMR
  5. Genome Analysis - Epidemiological Visualisation
  6. Genome Analysis - Gene Info

Map

Shows distribution of genomes on a geospatial world map. SelectionMap and DisplayMap extend the main parent Map component. It is used in pages:

  1. Group Builder - Map
  2. Genome Analysis - Epidemiological Visualisation

Tree

Shows phylogeny of genomes for different levels/resolutions. SelectionTree and DisplayTree extend the main parent Tree component. It is used in pages:

  1. Group Builder - Tree
  2. Genome Analysis - Epidemiological Visualisation

MetaTable

Shows genome metadata in table format. Using async request to pull down subsets of genome data. SelectionMetaTable and DisplayMetaTable extend the main parent MetaTable component. It is used in pages:

  1. Group Builder - Metadata Table

GenomesList

GenomesList shows an active subset of genomes and their metadata properties. Unlike table, GenomesList does only shows a subset of genomes and should not require paging and should fit into memory. SelectionGenomesList and DisplayGenomesList extend the main parent GenomesList component. It is used in pages:

  1. Group Builder - Map
  2. Group Builder - Tree
  3. Group Builder - Metadata Table
  4. Group Builder - Create
  5. Group Builder - Modify/Merge
  6. Group Builder - AMR
  7. Genome Analysis - Epidemiological Visualisation

MetadataDisplayControl

MetadataDisplayControl controls what metadata properties are shown in the genome visualisations. It is used in pages:

  1. Group Builder - Map
  2. Group Builder - Tree
  3. Group Builder - Metadata Table
  4. Group Builder - AMR
  5. Genome Analysis - Epidemiological Visualisation
  6. Genome Analysis - Gene Info

MetadataFilterControl

MetadataFilterControl controls what genomes are shown in the genome visualisations, by removing genomes that do not match the specified search criteria. It is used in pages:

  1. Group Builder - Map
  2. Group Builder - Tree
  3. Group Builder - Metadata Table
  4. Group Builder - AMR
  5. Genome Analysis - Epidemiological Visualisation
  6. Genome Analysis - Gene Info

GroupForm

GroupForm is used to add or update new genome groups for a user. NewGenomeForm, UpdateGenomeForm DeleteGenomeForm extend the main parent GroupForm component. It is used in pages:

  1. Group Builder - Create
  2. Group Builder - Modify/Merge

MergeForm

MergeForm is for combining existing groups using set operations into new groups. It is used in pages:

  1. Group Builder - Modify/Merge

AnalysisForm

AnalysisForm is for launching an analysis with a given genome group. It is used in pages:

  1. Genome Analysis - Select

GeneList

GeneList displays genes linked to one or more genomes. It has child components GeneCategoryFilter. It is used in pages:

  1. Group Builder - AMR
  2. Genome Analysis - Select AMR
  3. Genome Analysis - Select VF

GeneCategoryFilter

GeneCategoryFilter can refine a GeneList only displaying certain genes in the model. It is used in pages:

  1. Group Builder - AMR
  2. Genome Analysis - Select AMR
  3. Genome Analysis - Select VF

GeneMatrix

GeneMatrix displays gene copy number for multiple genes and one or more genomes in matrix format. It has child components GeneCategoryFilter and MetadataFilterControl. It is used in pages:

  1. Genome Analysis - Gene Distribution

GeneHistogram

GeneHistogram displays gene copy number for one gene and one or more genomes in histogram format. It has child components GeneCategoryFilter and MetadataFilterControl. It is used in pages:

  1. Genome Analysis - Gene Info

Class UML

Model-Component Interface

Sequence UML

Filtering

Changing Metadata display

Adding or removing genome from selection

Clone this wiki locally