Giter Club home page Giter Club logo

epicontacts's Introduction

Build Status Build status Coverage Status CRAN_Status_Badge

reconhub

This packages installs and loads all stable RECON packages similiar to the tidyverse package.

Installing the package

To install the current stable, CRAN version of the package, type:

install.packages("reconhub")

To benefit from the latest features and bug fixes, install the development, github version of the package using:

devtools::install_github("reconhub/reconhub")

Note that this requires the package devtools installed.

What does it do?

# attaches all stable recon packages
library(reconhub)
## Attaching package epicontacts

## Attaching package outbreaks

## Attaching package incidence

Also, you can install all development versions of RECON packages:

reconhub::install_dev_versions()

Getting help online

Bug reports and feature requests should be posted on github using the issue system. All other questions should be posted on the RECON forum:
http://www.repidemicsconsortium.org/forum/

Contributions are welcome via pull requests.

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

epicontacts's People

Contributors

bwlewis avatar finlaycampbell avatar jamesmbaazam avatar joshwlambert avatar nistara avatar tc13 avatar thibautjombart avatar vpnagraj avatar zkamvar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

epicontacts's Issues

`vis_epi_contacts` fixes

  • restore the local highlight upon clicking (was there before)
  • check if display speed can be optimized
  • by default, plot all info upon overlaying

formal argument "group" matched by multiple actual arguments

When using the plot function and the group attribute this error happens:

formal argument "group" matched by multiple actual arguments

Minimal example:

plot(epicontacts::make_epicontacts(outbreaks::mers_korea_2015$linelist, outbreaks::mers_korea_2015$contacts), group = "age")

Expected result:

epicontacts::vis_epicontacts(epicontacts::make_epicontacts(outbreaks::mers_korea_2015$linelist, outbreaks::mers_korea_2015$contacts), group = "age")

Internalise `subset_clusters_by...`

These should be put as options in subset and internalized (i.e. no export, no dedicated doc).

User cases should still be illustrated in the doc of subset

`get_id` improve doc

  • add bullet points to description
  • complete example: check intersections and unions, and use basic subestting

Various fixes for vignette

Various things to fix in the vignette:

  • use the same title as package
  • make figures larger (they're way too small now)
  • assume the CRAN release is available
  • fix the first plot(x) - nothing is displayed
  • rename Selection functions by individuals to more explicit
  • fix plot(x_subset_N), it looks like a different plot (plot(x))?
  • fix plot(net_igraph, ... : graph is impossible to visualize
  • fix renderGraph(g): nothing is displayed

errror building vignette

On current 3.4.0, all packages updated:

> check()
Updating epicontacts documentation
Loading epicontacts
Setting env vars --------------------------------------------------------------
CFLAGS  : -Wall -pedantic
CXXFLAGS: -Wall -pedantic
Building epicontacts ----------------------------------------------------------
'/usr/local/lib/R/bin/R' --no-site-file --no-environ --no-save --no-restore  \
  --quiet CMD build '/home/thibaut/dev/recon/epicontacts' --no-resave-data  \
  --no-manual 

* checking for file ‘/home/thibaut/dev/recon/epicontacts/DESCRIPTION’ ... OK
* preparing ‘epicontacts’:
* checking DESCRIPTION meta-information ... OK
* installing the package to build vignettes
* creating vignettes ... ERROR
Warning in structure(x, class = unique(c("AsIs", oldClass(x)))) :
  Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.
Quitting from lines 219-233 (epicontacts.Rmd) 
Error: processing vignette 'epicontacts.Rmd' failed with diagnostics:
undefined columns selected
Execution halted
Error: Command failed (1)

README misses install CRAN and examples

I suspect it was there at some point and has been removed, although I could be confused.

We need to add installation guidelines for CRAN version (it's okay to have them before the actual CRAN version). We also need some simple worked example (without interactive graphics as they won't display on github).

shiny app is broken

Getting a table display but no graph. It might be from the subset?
Pasting part of the log below (sorry I'm at User, can't track the error further for now):

    67: output$netplot
     1: runApp
Warning: Error in <-: 'names' attribute [1] must be the same length as the vector [0]
Stack trace (innermost first):
    72: exprFunc [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#81]
    71: widgetFunc
    70: func
    69: renderFunc
    68: output$linelisttab
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in apply: dim(X) must have a positive length
Stack trace (innermost first):
    73: apply
    72: paste
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in apply: dim(X) must have a positive length
Stack trace (innermost first):
    73: apply
    72: paste
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in apply: dim(X) must have a positive length
Stack trace (innermost first):
    73: apply
    72: paste
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in apply: dim(X) must have a positive length
Stack trace (innermost first):
    73: apply
    72: paste
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in $<-.data.frame: replacement has 1 row, data has 0
Stack trace (innermost first):
    73: $<-.data.frame
    72: $<-
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in apply: dim(X) must have a positive length
Stack trace (innermost first):
    73: apply
    72: paste
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in $<-.data.frame: replacement has 1 row, data has 0
Stack trace (innermost first):
    73: $<-.data.frame
    72: $<-
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in $<-.data.frame: replacement has 1 row, data has 0
Stack trace (innermost first):
    73: $<-.data.frame
    72: $<-
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)
Warning: Error in $<-.data.frame: replacement has 1 row, data has 0
Stack trace (innermost first):
    73: $<-.data.frame
    72: $<-
    71: vis_epi_contacts
    70: plot.epi_contacts
    69: plot
    68: func [/home/thibaut/dev/hackout3/epicontacts/inst/contacts_server/server.R#70]
    67: output$netplot
     1: runApp
Warning in `[.epi_contacts`(x, i = node.id, j = edge.from, contacts = "from") :
  'j' is not a character; enforcing conversion 
(logicals and integers cannot be used to subset epi_contacts objects)

NOTE ON 'ebola' BRANCH

@nistara @vpnagraj @finlaycampbell Just to let you know, I will be making an 'ebola' branch to implement changes to the package to accommodate needs for the Ebola outbreak in DRC. Most of these will be along the lines of customisation of the plot as in dibbler (see ?plot.dibbler):

  • using icons to display linelist info
  • using colors or symbols for edges to display contacts info

warning - need to rename argument in summary

@vpnagraj :
devtools::check() gives:

R CMD check results
0 errors | 1 warning  | 0 notes
checking S3 generic/method consistency ... WARNING
summary:
  function(object, ...)
summary.epi_contacts:
  function(x, ...)

See sectionGeneric functions and methodsin theWriting R
Extensionsmanual.

This is because arguments before the `...``need to match the generic definition. Renaming and should be okay :)

Tidy up subset function

It probably does the right job as it stands, but it is really hard to figure out what's going on there:
https://github.com/reconhub/epicontacts/blob/master/R/subset.epi_contacts.R

A few tips that I found useful:

  • make intermediate variables with explicit names
  • short command lines (<80 characters) where possible
  • comments explaining what is being done whenever there's something non-trivial, so that someone could recode the function from your comments

The idea is that anyone should be able to look at this code and patch it if needed

CRAN release! :)

Once #66 is closed, I think we should go ahead and finally put this one on CRAN :)

add dataset option to shiny app

add dataset option to shiny app (mers, ebola.sim, upload your own) ... default should be set to one of two datasets included in the package so the user doesn't necessarily have to upload a csv

Potential bug in `subset_clusters_by_id`

In the example code, the resulting object does not show the "target case" in the plot:

 ## build data
     x <- make_epi_contacts(ebola.sim$linelist, ebola.sim$contacts,
                            id="case.id", to="case.id", from="infector",
                            directed=TRUE)


     id <- "cac51e" ## it can be a vector of id as well


     ## subset based on cluster to which "cac51e" belongs
     x_subset <- subset_clusters_by_id(x, id)

     plot(x_subset) # does not show `cac51e`

Handling of `annot` argument in graph3D

From these lines:
https://github.com/reconhub/epicontacts/blob/master/R/graph3D.R#L103-L112

it looks like the function will only behave well as expected if a logical is given for annot, which does not agree with the doc (an index of columns in $linelist).

See behaviour in vis_epicontacts:
https://github.com/reconhub/epicontacts/blob/master/R/vis_epicontacts.R#L86-L93
and then
https://github.com/reconhub/epicontacts/blob/master/R/vis_epicontacts.R#L113-L118

@nistara do you think we can have something similar with graph3D? Incidentally, I think once this is done and unit-tested, we'll be at 100% coverage =D

Restructure vignette: handling, plotting, analysis

As it currently stands, the vignette does a good job of showing functionalities but is a bit hard to follow. It reads like a catalog, which is more the purpose of the manual. We could probably make information more accessible by re-structuring the content. I would think:

  1. Introduction & overview (i.e. what is this package for?)
  2. Installation
  3. Getting your data into epicontact
  4. Handling data
  5. Plotting data
  6. Analysis

@vpnagraj @nistara @tc13 @finlaycampbell What do y'all think?

`subset_clusters_by_`... rename `node` to `id`

As our user base will be mostly epidemiologists, it may be better to refer to cases as cases rather than nodes when possible. I think nodes/edges terminology is fine internally, but maybe best avoided on the user side (especially since some functions and the data structure use the 'case/id' terminology.

@vpnagraj @nistara is it OK with you?

I have made the change at 651a9b2

Release patch on CRAN

Version 1.0.1 fixes the following:

  • make_epicontacts now handles contacts provided as factors

  • added URL of website and issue system to DESCRIPTION

  • replaced javascript graphics in README.md with screenshots - these were not
    rendering on github

Would be great to have it on CRAN.

vis_epicontacts tests pass then fail

> test()
Loading epicontacts
Testing epicontacts
Testing igraph conversion: .
Colors and palettes: ........
Retrieving clusters from linelist with get_clusters: ....
Computing number of contacts per case: .....
Extracting IDs from epi_contact: ..............
Test get_pairwise: ...........
3D Graph: .....
Handling: [ operator: ...........................
Converting data to epicontacts using make_epicontacts: ...............
Plotting epicontacts: .
Printing of epicontacts objects: .
Subsetting clusters by ID: .
Subsetting clusters by size: .......
Subsetting epicontacts by node and edge attributes: ...............
Printing of epicontacts summary objects: .
Thin: .........
vis_epicontacts objects: ...........

DONE ===========================================================================
> test()
Loading epicontacts
Testing epicontacts
Testing igraph conversion: .
Colors and palettes: ........
Retrieving clusters from linelist with get_clusters: ....
Computing number of contacts per case: .....
Extracting IDs from epi_contact: ..............
Test get_pairwise: ...........
3D Graph: .....
Handling: [ operator: ...........................
Converting data to epicontacts using make_epicontacts: ...............
Plotting epicontacts: .
Printing of epicontacts objects: .
Subsetting clusters by ID: .
Subsetting clusters by size: .......
Subsetting epicontacts by node and edge attributes: ...............
Printing of epicontacts summary objects: .
Thin: .........
vis_epicontacts objects: ...1234....

Failed -------------------------------------------------------------------------
1. Failure: Plotting groups as color (@test_vis_epicontacts.R#27) --------------
`vis3` not equal to reference from `rds/vis3.rds`.
Component “x”: Component “nodes”: Component “title”: 83 string mismatches


2. Failure: Plotting groups as color (@test_vis_epicontacts.R#28) --------------
`vis4` not equal to reference from `rds/vis4.rds`.
Component “x”: Component “nodes”: Component “title”: 83 string mismatches


3. Failure: Plotting groups as color (@test_vis_epicontacts.R#29) --------------
`vis5` not equal to reference from `rds/vis5.rds`.
Component “x”: Component “nodes”: Component “title”: 83 string mismatches


4. Failure: Plotting groups as color (@test_vis_epicontacts.R#30) --------------
`vis6` not equal to reference from `rds/vis6.rds`.
Component “x”: Component “nodes”: Component “group”: 83 string mismatches
Component “x”: Component “nodes”: Component “title”: 83 string mismatches
Component “x”: Component “groups”: 5 string mismatches


DONE ===========================================================================
> 

small bug in `get_clusters`: cases not in linelist

get_clusters is cool =D

I was just adding a new example in the vignette for it. There's a weird thing happening, with invidiuals in some clusters effectively having no cluster:

x <- make_epicontacts(ebola_sim$linelist, ebola_sim$contacts,
                      id = "case.id", to = "case.id", from = "infector",
                      directed = TRUE)
x
x <- get_clusters(x)
x_14 <- subset(x, cs = 14)
plot(x_14, "cluster_member")

See the nodes in grey on the plot. I think it comes from the fact that these nodes are in x$contacts but not in the x$linelist before the call to get_clusters. When calling get_clusters(x, output = "epicontact") (the default) we may want to add automatically entries in the $linelist (with their ID and cluster info, and NA elsewhere).

Incidentally, this may be a more general task to implement in a function - like the opposite of thin. fatten?
@nistara @vpnagraj what do you think?

Use consistent thining in plot.epicontacts / vis_epicontacts

Currently, plot.epicontacts by default thins the data and uses vis_epicontacts to plot the output.

However, vis_epicontacts has no thinning by default, resulting in different outputs. This has confused some users during the Epidemics6 workshop, maybe we want to think about it.

Error with devtools::check()

I'm getting this error when I check the package using devtools::check() or even when I check it using RStudio. It doesn't show up when I build and reload via RStudio. Has to do with the outbreaks package in the vignette.

Setting env vars ---------------------------------------------------------------
CFLAGS  : -Wall -pedantic
CXXFLAGS: -Wall -pedantic
Building epicontacts -----------------------------------------------------------
'/Library/Frameworks/R.framework/Resources/bin/R' --no-site-file --no-environ  \
  --no-save --no-restore --quiet CMD build '/Users/nistara/Dropbox/UC  \
  DAVIS/Projects/2016_epicontacts/epicontacts' --no-resave-data --no-manual 

* checking for file ‘/Users/nistara/Dropbox/UC DAVIS/Projects/2016_epicontacts/epicontacts/DESCRIPTION’ ... OK
* preparing ‘epicontacts’:
* checking DESCRIPTION meta-information ... OK
* installing the package to build vignettes
* creating vignettes ... ERROR
Quitting from lines 73-75 (epicontacts.Rmd) 
Error: processing vignette 'epicontacts.Rmd' failed with diagnostics:
there is no package called 'outbreaks'
Execution halted
Error: Command failed (1)
Execution halted

Exited with status 1.

streamline vignette narrative

the current vignette is now consolidated into a single file: https://github.com/Hackout3/epicontacts/blob/master/vignettes/epicontacts.Rmd) as of ec6689a

the content is all there thanks to bertrand and nistara but the formatting / narrative make it hard to follow

@nistara i've assigned myself to this but feel free to take a look ... note that any changes should be made to the rmd file mentioned above unless we want to split demonstrations of features into individual vignettes

rename `igraph.epi_contacts` to `as.igraph.epi_contacts`

As it is clearly a conversion function. I don't mind at all having the function as it is, but as.igraph... should be available too, especially since it will let us omit the class name so that we can call as.igraph(x) where x is an epi_contacts object.

rationalise code in `graph3D`

The code currently mixes different cases in the arguments:

graph3D <- function(epi_contacts,
                    label_column = "id",
                    v_col_by = "NA",
                    v.col = "darkturquoise",
                    g.title = "",
                    g.bg = "white",
                    g.fg = "darkturquoise",
                    v.size = 1,
                    e.size = .5) {

We should stick to snake_case in all APIs (internal code doesn't matter as much).
It would be nice to try and use similar arguments in all graphical functions, to the extent that it's possible. For instance:

function (x, group = "id", annot = c("id"), legend = TRUE, legend_max = 10, 
    col_pal = cases_pal, NA_col = "lightgrey", width = "90%", 
    height = "700px", selector = TRUE, editor = FALSE, ...) 

uses a color palette and group definitions to define colors for the vertices, which should be possible here too (?). @nistara @vpnagraj (and others ;) ) what do you think?

Flag priority contacts

Based on a given time window, and potentially type of contact, pull list of contacts that should be prioritized for evaluation/visit.

shiny interface stuff

So, the plans will be to eventually have a template interface across various RECON packages. In the meantime, we can develop our own, but I really would not prioritise this aspect for now, especially for the first release. So, this is just if we want to release a GUI straight away.

Things that would need investigating, if we were to release the interface, include:

  • fixing the subsetting (weird legend of 'group' when doing so)
  • fixing the plot/input; for some reason the default Ebola simulation is much smaller than it should
  • input: "Is this a directed" -> move to a radiobutton yes/no, or simply write "Contacts are directed".
  • subsetting causes errors upon changing dataset; try: input = Ebola > subset base on outcome > retain death > input =MERS

Suppose linelist has a column named "group"

Not sure if this is an issue, but say the linelist already has a column named group. In that case, the following code would overwrite the original column, and the annotations would contain the new group values instead of the original ones.

  ## join back to linelist to retrieve attributes for grouping

  nodes <- suppressMessages(
    suppressWarnings(dplyr::left_join(nodes, x$linelist)))
  nodes$group <- as.character(nodes[, group])
  nodes$group[is.na(nodes$group)] <- "NA"
  nodes$group <- factor(nodes$group)


  ## get annotations

  temp <- nodes[, annot, drop = FALSE]
  temp <- sapply(names(temp), function(e) paste(e, temp[, e], sep = ": "))
  nodes$title <- paste("<p>",
                       apply(temp, 1, paste0, collapse = "<br>"), "</p>")

To avoid the overwriting in graph3D(), I got the annotations first and then did the grouping process. Do you think we should do the same for vis_epicontacts()?
@thibautjombart ?

epicontacts versus epi_contacts

i was just about to get started on the vignette for data structure and it occurred to me that while we call the package epicontacts, the s3 class is epi_contacts. for the sake of consistency we might want to rename the data structure to epicontacts.

not a huge deal to me ... do you all have any strong feelings on this? let me know if you'd like to me to make the change, if one of you would prefer to jump in and do it or if we should just leave everything as-is.

@thibautjombart @nistara @finlaycampbell

`clusters_epi_contacts`

This is cool, but small changes may be useful. Probably mostly for @nistara (?)

  • change arguments to clusters_epi_contacts(x, output = c("epi_contacts", "factor")) and then use output <- match.arg(ouput) to get the type of output; keep current behaviour by default, but allow for a basic factor to be returned, named after IDs.
  • description: say that the function identifies transitive clusters (i.e. connected components) and adds this information to the linelist data; *question: * what happens when individuals from the contacts are not documented in the linelist? Are they added using some kind of merge?
  • example: rename objects to x and y or something similar (just shorter)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.