Code Monkey home page Code Monkey logo

d3po's Introduction

D3po

R-CMD-check

Methods and features

D3po’s goal is to provide out-of-the-box beautiful visualizations with minimum time and coding effort from the final user. It acts as intermediate layer between the user and Shiny and D3 by providing “templates”, enabling high quality interactive visualizations.

D3po methods:

  • Area (or distribution) chart
  • Box and whiskers
  • Column charts (horizontal and vertical)
  • Donut chart
  • Geographical maps
  • Line charts
  • Networks
  • Pie chart
  • Scatterplots
  • Treemaps

D3po features:

  • Automatic content resizing, sensitive to internet browser window maximization/minimization
  • Downloading the charts in SVG format
  • Downloading the charts in PNG format
  • Downloading the charts in JPEG format
  • Providing internatilization options (i.e., numbers as 1.234.567,89 instead of 1,234,567.89 in Spanish or French).
  • Producing high quality results with a minimal number of lines of code

Installation

You can install the stable version from CRAN with:

install.packages("d3po")

You can install the development version of d3po from GitHub with:

# install.packages("devtools")
devtools::install_github("pachadotdev/d3po")

Examples

This is an example consisting in the creation of a box and whiskers plot:

d3po(pokemon) %>%
  po_box(daes(x = type_1, y = speed, color = color_1)) %>%
  po_title("Distribution of Pokemon speed by main type")

To access a templated project, in RStudio's top bar click File -> New Project -> New Directory -> Shiny app with Golem+D3po. Otherwise, start with a blank project and run d3po::d3po_template() to copy the same templates.

You can install the templated projects as any other R package. The templates have their own readme files, so please read them.

Vignette

Please (please!) read the vignette (https://github.com/pachadotdev/d3po/blob/main/vignettes/d3po.Rmd).

d3po's People

Contributors

curran avatar dependabot[bot] avatar fbecerra avatar johncoene avatar pachadotdev avatar severo avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3po's Issues

create an "open highcharter" for Shiny

I'm thinking about building an "open highcharter", something that allows interactive D3 visualization from Shiny in a very easy way. Think of this as Ikea furniture, something that is accesible and fits almost anywhere.

R already features excellent visualization libraries such as D3 (via the r2d3 package) or plotly, however though those enable the creation of great looking visualisations they have very steep learning curves and even sometimes require some understanding of JavaScript.

After LatinR I realised that, for this to be complete, it has to include internationalization (i.e. show 1.000 instead of 1,000 in spanish) and provide easy i18n activation for example with functions like the_chart(..., lang = "es").

The idea is to take the good ideas from highcharts, but also other good ideas from echarts, vegaLite and D3plus to create an R package that is easy to use and provides a set of well polished D3 templates for interactive visualization.

As an R user, I'm thinking about something designed for the %>% operator and the ultimate aim of the project is to produce a package that:

  • Offers perfect integration with Shiny
  • Enables downloading the charts in different image formats (png, jpeg, svg)
  • Enables downloading the data in different formats (json, csv, xlsx)
  • Can produce high quality results with a minimal number of lines of code
  • Has internalization with options to render visualizations in english, spanish and french

d3 todos (migration to d3 v5)

What remains to finish the migration to D3.js 5.x:

  • migrate d3.layout.treemap(), d3.layout.pack() and d3.layout.stack() to their 5.x counterparts
  • migrate d3.svg.axis() and d3.svg.brush() to their 5.x counterparts
  • test that everything works as expected.

Why it cannot be done currently:

  • the functions that remain to migrate are largely different between 3.x and 5.x, and the surrounding code and logic must be changed accordingly.
  • best practice for refactoring code (upgrading a library without modifying the behavior is refactoring) is to ensure the unit tests keep working after modifying the code. But there are no unit tests in the code base: trivial refactoring is OK, but touching largest parts of code is too risky and result cannot be verified.

What is recommended:

  • create unit tests for all the functions in the library

Additionally, it would be good to:

  • cut the functions in smaller functions (max. 30/35 lines)
  • add doctrings to all the functions (see http://documentation.js.org/ for example) + generate API documentation (result: https://docs.mapbox.com/mapbox-gl-js/api/)
  • enforce coherent code style with eslint and prettier
  • add a README.ms in the javascript/ directory
  • move the javascript/ directory to its own git repository, publish it as a npm package

Non-Trivial D3 Upgrades

  • Upgrade stack usage.
  • Upgrade treemap usage.
  • Upgrade pack usage.
  • Upgrade everything else.
  • Purge all references to d3 version 3 from the codebase.

npm audit

=== npm audit security report ===                        
                                                                                
# Run  npm install --save-dev [email protected]  to resolve 6 vulnerabilities
SEMVER WARNING: Recommended action is a potentially breaking change
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-stream > glob > minimatch             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/118                             │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-stream > minimatch                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/118                             │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > glob >     │
│               │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/118                             │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > minimatch  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/118                             │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > lodash     │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/782                             │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > lodash     │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/577                             │
└───────────────┴──────────────────────────────────────────────────────────────┘

visualization todos

resize

  • horizontal resing
  • vertical resing (works ok in shiny, not in viewer)

columns

  • chromium doesn't show years in x-axis

line

  • add point to segments' extremes

example to replicate: https://www.highcharts.com/demo/line-basic

networks

  • links not showing
  • tooltips not showing in browser works just in html, not in shiny
  • horizontal resize not working

example to replicate: http://d3plus.org/examples/basic/9042919/

box and whiskers

  • charts not rendering

sankeys

  • strenght argument needs to be passed in a different way to work

check here: https://github.com/pachamaltese/d3plus/blob/master/dev/sankey.R#L20
example to replicate: http://d3plus.org/examples/basic/a523b45768c2ca464363/

geo map

  • pass the topojson in a way that the chart may be rendered

treemap

  • always show percentages

labels

  • show percentages in pie and donut

Proxy Methods

Need to implement all proxy methods, currently only available for po_title.

Testing Setup

Before I start modifying code towards #16 , I want to be able to verify that everything still works at each step. I see there is a /dev directory with several examples in .html files. However, it's not clear how to run these. One way I can see is to copy-paste the code from those into the index.html of the src directory.

What I'm thinking of doing as a next step is to set up a page that shows all those examples at once, zoomed out, so that I can verify with little effort that nothing breaks when I change code. It's not exactly unit tests, but it's the same in spirit (let's call it "visual unit tests").

Repository size is > 10MB

When cloning, I notice the repository size is > 10MB.

image

This smells to me like there are some additional large files in the Git history that don't need to be there. There are ways to delete large files from Git history while preserving all code changes. It might be a good thing to do.

D3 5.x migration

What remains to finish the migration to D3.js 5.x:

  • migrate d3.layout.treemap(), d3.layout.pack() and d3.layout.stack() to their 5.x counterparts
  • migrate d3.svg.axis() and d3.svg.brush() to their 5.x counterparts
  • test that everything works as expected.

Why it cannot be done currently:

  • the functions that remain to migrate are largely different between 3.x and 5.x, and the surrounding code and logic must be changed accordingly.
  • best practice for refactoring code (upgrading a library without modifying the behavior is refactoring) is to ensure the unit tests keep working after modifying the code. But there are no unit tests in the code base: trivial refactoring is OK, but touching largest parts of code is too risky and result cannot be verified.

What is recommended:

  • create unit tests for all the functions in the library

Additionally, it would be good to:

  • cut the functions in smaller functions (max. 30/35 lines)
  • add doctrings to all the functions (see http://documentation.js.org/ for example) + generate API documentation (result: https://docs.mapbox.com/mapbox-gl-js/api/)
  • enforce coherent code style with eslint and prettier
  • add a README.ms in the javascript/ directory
  • move the javascript/ directory to its own git repository, publish it as a npm package

Fix broken example `geo.html`

The example geo.html has never worked for me. It would be great if it worked, so that I may verify that my refactoring work doesn't break it.

I'll leave this in your hands @pachamaltese .

alineacion del boton de descarga

image

hola @fbecerra
en el ultimo commit deje un ejemplo en javascript que ejecuto con python -m http.server, me gustaria dejar el boton de descarga dentro del div del titulo, con miras a agregarle un subtitulo despues (pero no ahora mismo)

Are color random and scale module doing what is expected?

See https://github.com/pachamaltese/d3po/blob/master/javascript/src/color/random.js and https://github.com/pachamaltese/d3po/blob/master/javascript/src/color/scale.js

Reading the code, the expected behavior seems to be:

// defined as: d3.scale.ordinal().range(["#bf3251", "#5c57d9", "#d6c650", "#406662", "#872a41", "#1c26b3", "#d05555", "#549e95", "#993f7b", "#dc8e7a", "#ede788", "#7485aa", "#4d6fd0", "#635b56", "#7454a6", "#a8c380", "#8abdb6", "#74c0e2", "#bcd8af", "#a1aafb", "#a17cb0", "#d1a1bc"]);
var defaultScale = require("./scale.js");

console.log(defaultScale(3))
// expected: "#406662", because it's the fourth color in the array (idx=3)
// actual: "#bf3251", because it's the first call to the scale and the argument (3) is not in the scale domain

But it's not, because no domain is defined for the ordinal scale. The actual behavior is that every call to the defaultScale function will return the following value in the range, and the argument is ignored since the domain is empty (in reality, every new argument is added to the domain, and a further call with the same argument will return the same value):

// defined as: d3.scale.ordinal().range(["#bf3251", "#5c57d9", "#d6c650", "#406662", "#872a41", "#1c26b3", "#d05555", "#549e95", "#993f7b", "#dc8e7a", "#ede788", "#7485aa", "#4d6fd0", "#635b56", "#7454a6", "#a8c380", "#8abdb6", "#74c0e2", "#bcd8af", "#a1aafb", "#a17cb0", "#d1a1bc"]);
var defaultScale = require("./scale.js");

console.log(defaultScale(235))
// returns the first value: #bf3251

console.log(defaultScale("string"))
// returns the second value: #5c57d9

console.log(defaultScale(0))
// returns the third value: #d6c650

console.log(defaultScale(235))
// returns the first value again: #bf3251, because 235 has been added to the domain

Thus, the values returned by https://github.com/pachamaltese/d3po/blob/master/javascript/src/color/random.js are not random at all.

Clean Code

  • Adopt Prettier (PR #21)
  • Adopt ESLint (PR #23)
  • Eliminate all ESLint Errors (PRs #25 #27)
  • Adopt ES6 (excluding module patterns) (PR #28)
  • Split modules (issue #26)

Straightforward D3 Upgrades

  • Establish a way to incrementally upgrade parts of the codebase. #20
  • Upgrade selection & transition usage.
  • Upgrade data fetching logic to use Promise-based API (if any).
  • Upgrade axis usage.
  • Upgrade brush usage.

Split Modules

Part of #15, the goal here is to split up large JS files ( > 500 lines) into smaller modules.

  • viz/helpers/ui/legend.js #31
  • viz/types/helpers/graph/includes/svg.js
  • viz/helpers/shapes/draw.js
  • viz/helpers/shapes/edges.js
  • viz/helpers/ui/timeline.js
  • tooltip/create.js
  • geom/largestrectangle.js
  • viz/types/helpers/graph/includes/plot.js
  • viz/types/rings.js

Tweak the Appearance

  • Show % smaller than texts on treemaps.
  • Center texts on [semi]donut properly.
  • Additional minor tweaks that may arise - we can discuss here in this issue in more detail.

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.