Giter Site home page Giter Site logo

jwilber / roughviz Goto Github PK

View Code? Open in Web Editor NEW
6.6K 55.0 227.0 3.49 MB

Reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser.

Home Page: https://www.jwilber.me/roughviz/

License: MIT License

JavaScript 92.98% HTML 5.90% CSS 1.12%
data-visualization d3v5 dashboard data-science visualization charting-library

roughviz's Introduction

roughViz.js

roughViz.js is a reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser, based on D3v5, roughjs, and handy.

roughViz.js

Why?

Use these charts where the communication goal is to show intent or generality, and not absolute precision. Or just because they're fun and look weird.

Chart Types

Chart Type API
Bar roughViz.Bar
Horizontal Bar roughViz.BarH
Donut roughViz.Donut
Line roughViz.Line
Pie roughViz.Pie
Scatter roughViz.Scatter
Stacked Bar roughViz.StackedBar

Visit this link for interactive examples of each chart.

Features

Apply the features of roughjs to each chart:

roughness:

roughness examples

fillStyle fillStyle examples

fillWeight fillStyle examples

As well as additional chart-specific options (see API below)

Installation

Via CDN (expose the roughViz global in html):

<script src="https://unpkg.com/[email protected]"></script>

Via npm:

npm install rough-viz

Want to use with React? There's a wrapper!:

npm install react-roughviz

Want to use with Vue? There's a wrapper!:

npm install vue-roughviz

Want to use it with Python? Go crazy:

pip install py-roughviz

How to use

If you're using ESM, make sure to import the library:

import roughViz from "rough-viz";

Create some container elements, one for each chart:

<!--you can name each id whatever you want -->
<div id="viz0"></div>
<div id="viz1"></div>

In the javascript, just create charts, referencing the desired container:

// create Bar chart from csv file, using default options
 new roughViz.Bar({
    element: '#viz0', // container selection
    data: 'https://raw.githubusercontent.com/jwilber/random_data/master/flavors.csv',
    labels: 'flavor',
    values: 'price'
});

// create Donut chart using defined data & customize plot options
new roughViz.Donut(
  {
    element: '#viz1',
    data: {
      labels: ['North', 'South', 'East', 'West'],
      values: [10, 5, 8, 3]
    },
    title: "Regions",
    width: window.innerWidth / 4,
    roughness: 8,
    colors: ['red', 'orange', 'blue', 'skyblue'],
    stroke: 'black',
    strokeWidth: 3,
    fillStyle: 'cross-hatch',
    fillWeight: 3.5,
  }
);

API

roughViz.Bar

Required

  • element [string]: Id or class of container element.

  • data: Data with which to construct chart. Can be either an object or string.

    • If object: must contain labels and values keys:
    new roughViz.Bar({
       element: '.viz',
       data: {labels: ['a', 'b'], values: [10, 20]}
     })
    • If string: must be a path/url to a csv or tsv, and you must also specify the labels and values as separate attributes that represent columns in said file:
    new roughViz.Bar({
      element: '#viz0',
      data: 'stringToDataUrl.csv',
      labels: 'nameOfLabelsColumn',
      values: 'nameOfValuesColumn',
    })

Optional

  • axisFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • axisRoughness [number]: Roughness for x & y axes. Default: 0.5.
  • axisStrokeWidth [number]: Stroke-width for x & y axes. Default: 0.5.
  • bowing [number]: Chart bowing. Default: 0.
  • color [string]: Color for each bar. Default: 'skyblue'.
  • fillStyle [string]: Bar fill-style. Should be one of fillStyles shown above.
  • fillWeight [number]: Weight of inner paths' color. Default: 0.5.
  • font: Font-family to use. You can use 0 or gaegu to use Gaegu, or 1 or indie flower to use Indie Flower. Or feed it something else. Default: Gaegu.
  • highlight [string]: Color for each bar on hover. Default: 'coral'.
  • innerStrokeWidth [number]: Stroke-width for paths inside bars. Default: 1.
  • interactive [boolean]: Whether or not chart is interactive. Default: true.
  • labelFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • margin [object]: Margin object. Default: {top: 50, right: 20, bottom: 70, left: 100}
  • padding [number]: Padding between bars. Default: 0.1.
  • roughness [number]: Roughness level of chart. Default: 1.
  • simplification [number]: Chart simplification. Default 0.2.
  • stroke [string]: Color of bars' stroke. Default: black.
  • strokeWidth [number]: Size of bars' stroke. Default: 1.
  • title [string]: Chart title. Optional.
  • titleFontSize [string]: Font-size for chart title. Default: '1rem'.
  • tooltipFontSize [string]: Font-size for tooltip. Default: '0.95rem'.
  • xLabel [string]: Label for x-axis.
  • yLabel [string]: Label for y-axis.

roughViz.BarH

Required

  • element [string]: Id or class of container element.

  • data: Data with which to construct chart. Can be either an object or string.

    • If object: must contain labels and values keys:
    new roughViz.BarH({
       element: '.viz',
       data: {labels: ['a', 'b'], values: [10, 20]}
     })
    • If string: must be a path/url to a csv or tsv, and you must also specify the labels and values as separate attributes that represent columns in said file:
    new roughViz.BarH({
      element: '#viz0',
      data: 'stringToDataUrl.csv',
      labels: 'nameOfLabelsColumn',
      values: 'nameOfValuesColumn',
    })

Optional

  • axisFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • axisRoughness [number]: Roughness for x & y axes. Default: 0.5.
  • axisStrokeWidth [number]: Stroke-width for x & y axes. Default: 0.5.
  • bowing [number]: Chart bowing. Default: 0.
  • color [string]: Color for each bar. Default: 'skyblue'.
  • fillStyle [string]: Bar fill-style. Should be one of fillStyles shown above.
  • fillWeight [number]: Weight of inner paths' color. Default: 0.5.
  • font: Font-family to use. You can use 0 or gaegu to use Gaegu, or 1 or indie flower to use Indie Flower. Or feed it something else. Default: Gaegu.
  • highlight [string]: Color for each bar on hover. Default: 'coral'.
  • innerStrokeWidth [number]: Stroke-width for paths inside bars. Default: 1.
  • interactive [boolean]: Whether or not chart is interactive. Default: true.
  • labelFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • margin [object]: Margin object. Default: {top: 50, right: 20, bottom: 70, left: 100}
  • padding [number]: Padding between bars. Default: 0.1.
  • roughness [number]: Roughness level of chart. Default: 1.
  • simplification [number]: Chart simplification. Default 0.2.
  • stroke [string]: Color of bars' stroke. Default: black.
  • strokeWidth [number]: Size of bars' stroke. Default: 1.
  • title [string]: Chart title. Optional.
  • titleFontSize [string]: Font-size for chart title. Default: '1rem'.
  • tooltipFontSize [string]: Font-size for tooltip. Default: '0.95rem'.
  • xLabel [string]: Label for x-axis.
  • yLabel [string]: Label for y-axis.

roughViz.Donut

Required

  • element [string]: Id or class of container element.

  • data: Data with which to construct chart. Can be either an object or string.

    • If object: must contain labels and values keys:
    new roughViz.Donut({
       element: '.viz',
       data: {labels: ['a', 'b'], values: [10, 20]}
     })
    • If string: must be a path/url to a csv, json, or tsv, and you must also specify the labels and values as separate attributes that represent columns in said file:
    new roughViz.Donut({
      element: '#viz0',
      data: 'stringToDataUrl.csv',
      labels: 'nameOfLabelsColumn',
      values: 'nameOfValuesColumn',
    })

Optional

  • bowing [number]: Chart bowing. Default: 0.
  • colors [array]: Array of colors for each arc. Default: ['coral', 'skyblue', '#66c2a5', 'tan', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', 'tan', 'orange'].
  • fillStyle [string]: Bar fill-style. Should be one of fillStyles shown above.
  • fillWeight [number]: Weight of inner paths' color. Default: 0.85.
  • font: Font-family to use. You can use 0 or gaegu to use Gaegu, or 1 or indie flower to use Indie Flower. Or feed it something else. Default: Gaegu.
  • highlight [string]: Color for each arc on hover. Default: 'coral'.
  • innerStrokeWidth [number]: Stroke-width for paths inside arcs. Default: 0.75.
  • interactive [boolean]: Whether or not chart is interactive. Default: true.
  • legend [boolean]: Whether or not to add legend. Default: 'true'.
  • legendPosition [string]: Position of legend. Should be either 'left' or 'right'. Default: 'right'.
  • margin [object]: Margin object. Default: {top: 50, right: 20, bottom: 70, left: 100}
  • padding [number]: Padding between bars. Default: 0.1.
  • roughness [number]: Roughness level of chart. Default: 1.
  • simplification [number]: Chart simplification. Default 0.2.
  • strokeWidth [number]: Size of bars' stroke. Default: 1.
  • title [string]: Chart title. Optional.
  • titleFontSize [string]: Font-size for chart title. Default: '1rem'.
  • tooltipFontSize [string]: Font-size for tooltip. Default: '0.95rem'.

roughViz.Line

Required

  • element [string]: Id or class of container element.
  • data: Must be a path/url to a csv or tsv, and you must also specify the each y as separate attributes that represent columns in said file. Each attribute prefaced with y (except yLabel) will receive its own line:
    new roughViz.Line({
      element: '#viz0',
      data: 'https://raw.githubusercontent.com/jwilber/random_data/master/profits.csv',
      y1: 'revenue',
      y2: 'cost',
      y3: 'profit'
    })

Optional

  • axisFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • axisRoughness [number]: Roughness for x & y axes. Default: 0.5.
  • axisStrokeWidth [number]: Stroke-width for x & y axes. Default: 0.5.
  • bowing [number]: Chart bowing. Default: 0.
  • circle [boolean]: Whether or not to add circles to chart. Default: true.
  • circleRadius [number]: Radius of circles. Default: 10.
  • circleRoughness [number]: Roughness of circles. Default: 2.
  • colors [array or string]: Array of colors for each arc. Default: ['coral', 'skyblue', '#66c2a5', 'tan', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', 'tan', 'orange']. If string (e.g. 'blue'), all circles will take that color.
  • fillStyle [string]: Bar fill-style. Should be one of fillStyles shown above.
  • fillWeight [number]: Weight of inner paths' color. Default: 0.5.
  • font: Font-family to use. You can use 0 or gaegu to use Gaegu, or 1 or indie flower to use Indie Flower. Or feed it something else. Default: Gaegu.
  • interactive [boolean]: Whether or not chart is interactive. Default: true.
  • labelFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • legend [boolean]: Whether or not to add legend. Default: true.
  • legendPosition [string]: Position of legend. Should be either 'left' or 'right'. Default: 'right'.
  • margin [object]: Margin object. Default: {top: 50, right: 20, bottom: 70, left: 100}
  • roughness [number]: Roughness level of chart. Default: 1.
  • simplification [number]: Chart simplification. Default 0.2.
  • stroke [string]: Color of lines' stroke. Default: this.colors.
  • strokeWidth [number]: Size of lines' stroke. Default: 1.
  • title [string]: Chart title. Optional.
  • titleFontSize [string]: Font-size for chart title. Default: '0.95rem'.
  • tooltipFontSize [string]: Font-size for tooltip. Default: '0.95rem'.
  • xLabel [string]: Label for x-axis.
  • yLabel [string]: Label for y-axis.

roughViz.Pie

Required

  • element [string]: Id or class of container element.

  • data: Data with which to construct chart. Can be either an object or string.

    • If object: must contain labels and values keys:
    new roughViz.Pie({
       element: '.viz',
       data: {labels: ['a', 'b'], values: [10, 20]}
     })
    • If string: must be a path/url to a csv, json, or tsv, and you must also specify the labels and values as separate attributes that represent columns in said file:
    new roughViz.Pie({
      element: '#viz0',
      data: 'stringToDataUrl.csv',
      labels: 'nameOfLabelsColumn',
      values: 'nameOfValuesColumn',
    })

Optional

  • bowing [number]: Chart bowing. Default: 0.
  • colors [array]: Array of colors for each arc. Default: ['coral', 'skyblue', '#66c2a5', 'tan', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', 'tan', 'orange'].
  • fillStyle [string]: Bar fill-style. Should be one of fillStyles shown above.
  • fillWeight [number]: Weight of inner paths' color. Default: 0.85.
  • font: Font-family to use. You can use 0 or gaegu to use Gaegu, or 1 or indie flower to use Indie Flower. Or feed it something else. Default: Gaegu.
  • highlight [string]: Color for each arc on hover. Default: 'coral'.
  • innerStrokeWidth [number]: Stroke-width for paths inside arcs. Default: 0.75.
  • interactive [boolean]: Whether or not chart is interactive. Default: true.
  • legend [boolean]: Whether or not to add legend. Default: true.
  • legendPosition [string]: Position of legend. Should be either 'left' or 'right'. Default: 'right'.
  • margin [object]: Margin object. Default: {top: 50, right: 20, bottom: 70, left: 100}
  • padding [number]: Padding between bars. Default: 0.1.
  • roughness [number]: Roughness level of chart. Default: 1.
  • simplification [number]: Chart simplification. Default 0.2.
  • strokeWidth [number]: Size of bars' stroke. Default: 1.
  • title [string]: Chart title. Optional.
  • titleFontSize [string]: Font-size for chart title. Default: '1rem'.
  • tooltipFontSize [string]: Font-size for tooltip. Default: '0.95rem'.

roughViz.Scatter

Required

  • element [string]: Id or class of container element.

  • data: Data with which to construct chart. Can be either an object or string.

    • If object: must contain x and y keys:
    new roughViz.Scatter({
       element: '.viz',
       data: {x: [1, 2, 35], y: [10, 20, 8]}
     })
    • If string: must be a path/url to a csv or tsv, and you must also specify the x and y as separate attributes that represent columns in said file:
    new roughViz.Scatter({
      element: '#viz0',
      data: 'stringToDataUrl.csv',
      x: 'nameOfLabelsColumn',
      y: 'nameOfValuesColumn',
    })

Optional

  • axisFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • axisRoughness [number]: Roughness for x & y axes. Default: 0.5.
  • axisStrokeWidth [number]: Stroke-width for x & y axes. Default: 0.5.
  • bowing [number]: Chart bowing. Default: 0.
  • colors [array or string]: Array of colors for each arc. Default: ['coral', 'skyblue', '#66c2a5', 'tan', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', 'tan', 'orange']. If string (e.g. 'blue'), all circles will take that color.
  • colorVar [string]: If input data is csv or tsv, this should be an ordinal column with which to color points by. curbZero [boolean]: Whether or not to force (x, y) axes to (0, 0). Default: false.
  • fillStyle [string]: Bar fill-style. Should be one of fillStyles shown above.
  • fillWeight [number]: Weight of inner paths' color. Default: 0.5.
  • font: Font-family to use. You can use 0 or gaegu to use Gaegu, or 1 or indie flower to use Indie Flower. Or feed it something else. Default: Gaegu.
  • highlight [string]: Color for each bar on hover. Default: 'coral'.
  • highlightLabel [string]: If input data is csv or tsv, this should be a column representing what value to display on hover. Otherwise, (x, y) values will be shown on hover.
  • innerStrokeWidth [number]: Stroke-width for paths inside circles. Default: 1.
  • interactive [boolean]: Whether or not chart is interactive. Default: true.
  • labelFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • margin [object]: Margin object. Default: {top: 50, right: 20, bottom: 70, left: 100}
  • radius [number]: Circle radius. Default: 8.
  • roughness [number]: Roughness level of chart. Default: 1.
  • simplification [number]: Chart simplification. Default 0.2.
  • stroke [string]: Color of circles' stroke. Default: black.
  • strokeWidth [number]: Size of circles' stroke. Default: 1.
  • title [string]: Chart title. Optional.
  • titleFontSize [string]: Font-size for chart title. Default: '0.95rem'.
  • tooltipFontSize [string]: Font-size for tooltip. Default: '0.95rem'.
  • xLabel [string]: Label for x-axis.
  • yLabel [string]: Label for y-axis.

roughViz.StackedBar

Required

  • element [string]: Id or class of container element.

  • data: Data with which to construct chart. Should be an object.

  • labels: String name of label key in data object.

    new roughViz.StackedBar({
       element: '#vis0',
       data: [
           {month:'Jan', A:20, B: 5},
           {month:'Feb', A:25, B: 10},
       ],
       labels: 'month',
     })

Optional

  • axisFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • axisRoughness [number]: Roughness for x & y axes. Default: 0.5.
  • axisStrokeWidth [number]: Stroke-width for x & y axes. Default: 0.5.
  • bowing [number]: Chart bowing. Default: 0.
  • colors [string]: Array of colors for each bar grouping.
  • fillStyle [string]: Bar fill-style. Should be one of fillStyles shown above.
  • fillWeight [number]: Weight of inner paths' color. Default: 0.5.
  • font: Font-family to use. You can use 0 or gaegu to use Gaegu, or 1 or indie flower to use Indie Flower. Or feed it something else. Default: Gaegu.
  • highlight [string]: Color for each bar on hover. Default: 'coral'.
  • innerStrokeWidth [number]: Stroke-width for paths inside bars. Default: 1.
  • interactive [boolean]: Whether or not chart is interactive. Default: true.
  • labelFontSize [string]: Font-size for axes' labels. Default: '1rem'.
  • margin [object]: Margin object. Default: {top: 50, right: 20, bottom: 70, left: 100}
  • padding [number]: Padding between bars. Default: 0.1.
  • roughness [number]: Roughness level of chart. Default: 1.
  • simplification [number]: Chart simplification. Default 0.2.
  • stroke [string]: Color of bars' stroke. Default: black.
  • strokeWidth [number]: Size of bars' stroke. Default: 1.
  • title [string]: Chart title. Optional.
  • titleFontSize [string]: Font-size for chart title. Default: '1rem'.
  • tooltipFontSize [string]: Font-size for tooltip. Default: '0.95rem'.
  • xLabel [string]: Label for x-axis.
  • yLabel [string]: Label for y-axis.

Contributors

Acknowledgements

This library wouldn't be possible without the following people:

License

MIT License

Copyright (c) 2019 Jared Wilber

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

roughviz's People

Contributors

0xflotus avatar barrald avatar daveslutzkin avatar dependabot[bot] avatar haikyuu avatar hidetoshi-nagayasu avatar jwilber avatar lucasjwilber avatar mhmh4 avatar mlu-explain avatar nderim1 avatar woobs 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  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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

roughviz's Issues

Label names overlap each other

Hello, I'm using your package to help me do some survey data analysis. And although I love the way the bar chart looks, my labels by the x-axis overlap. I tried to see if there were any attributes in the Bar function that help rotate the labels, but I don't see anything for that.
Bar graph

Save roughViz resulting chart to SVG

First of all: wonderful work!
Now... Would it be possible to save the resulting SVG chart to a SVG file?
Maybe using FileSave.js (eligrey/FileSaver.js#176)
(But in that case the chart would have to be converted to blob first... Is it possible?)
I think this would be a good workaround to make the result responsive...

piechart not drawn correctly

When drawing a pie chart, somehow there are areas which are drawn two times, as visible in the screenshot. also, the message popup box on hover is displaced underneath the graph.

b1

some options with a value of `0` are overridden with the defaults

I expected to be able to provide a value of 0 for some options, but when I do they are turned into the defaults:

this.roughness = roughCeiling(opts.roughness) || 1;
this.axisRoughness = opts.axisRoughness || 0.5;
this.simplification = opts.simplification || 0.2;

Axis-caption and hovering message-box displaced

I tested this with the current npm package as well as your unpkg-link versions 1.0.5, 1.0.4 and 1.0.3. If I create a simple chart with own object-data, the labels are one chart-size beneath the bars. With the example from your docs there are two axis-labelings. When I hover the charts, the info box gets displayed in the area of the displaced label svg box.

rv1
rv2

If I position the parent div relative and the two svgs inside absolute, they are displayed correctly, but the message box on hover is completely displaced.

Feature Request: Animated redraw / Individually colored bars

Would it be possible to add a method that will allow the chart values to be updated and for any changes in the bar value to be shown by animating/transitioning to the new value.

I was able to get to the chart to redraw by force removal of the SVG nodes:-

  function refreshChart(values, labels) {
    if (chart !== undefined) {
      chart.data.labels = labels;
      chart.data.values = values;
      chart.svg.selectAll("*").remove();
      chart.drawChart();
    }
  }

This works but looks a little janky and has downsides such as no longer supporting tooltips, interactive highlight, etc. as the nodes are being recreated:-

roughViz

It would be awesome if there was a way to update all the options and call refresh()/redraw() and have these changes reflected without having to destroy the SVG nodes:-

chartJs

I would also like to be able to supply an array of colours for the bar charts similar to what is supported for the pie charts. Supporting only a single colour seems very limiting for such a cool chart.

Thanks

Not working with Svelte = Cannot read property 'ownerDocument' of null

The provided demo throws Cannot read property 'ownerDocument' of null when used as a Svelte component. See the following Repl showing the issue.

The reason seems to be (as covered in this video by Svelte Master) that the index.js is incorrect and contains the contents of what looks like a build / config issue:-

content of index.js as installed via npm

// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
parcelRequire = (function (modules, cache, entry, globalName) {
  // Save the require from previous bundle to this closure if any
  var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
  var nodeRequire = typeof require === 'function' && require;

function newRequire(name, jumped) {
if (!cache[name]) {
if (!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
if (!jumped && currentRequire) {
return currentRequire(name, true);
}

    // If there are other bundles on this page the require from the
    // previous one is saved to 'previousRequire'. Repeat this as
    // many times as there are bundles until the module is found or
    // we exhaust the require chain.
    if (previousRequire) {
      return previousRequire(name, true);
    }

    // Try the node require function if it exists.
    if (nodeRequire && typeof name === 'string') {
      return nodeRequire(name);
    }

    var err = new Error('Cannot find module \'' + name + '\'');
    err.code = 'MODULE_NOT_FOUND';
    throw err;
  }

  localRequire.resolve = resolve;
  localRequire.cache = {};

  var module = cache[name] = new newRequire.Module(name);

  modules[name][0].call(module.exports, localRequire, module, module.exports, this);
}

return cache[name].exports;

function localRequire(x){
  return newRequire(localRequire.resolve(x));
}

function resolve(x){
  return modules[name][1][x] || x;
}

}

function Module(moduleName) {
this.id = moduleName;
this.bundle = newRequire;
this.exports = {};
}

newRequire.isParcelRequire = true;
newRequire.Module = Module;
newRequire.modules = modules;
newRequire.cache = cache;
newRequire.parent = previousRequire;
newRequire.register = function (id, exports) {
modules[id] = [function (require, module) {
module.exports = exports;
}, {}];
};

var error;
for (var i = 0; i < entry.length; i++) {
try {
newRequire(entry[i]);
} catch (e) {
// Save first error but execute all entries
if (!error) {
error = e;
}
}
}

if (entry.length) {
// Expose entry point to Node, AMD or browser globals
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
var mainExports = newRequire(entry[entry.length - 1]);

// CommonJS
if (typeof exports === "object" && typeof module !== "undefined") {
  module.exports = mainExports;

// RequireJS
} else if (typeof define === "function" && define.amd) {
 define(function () {
   return mainExports;
 });

// <script>
} else if (globalName) {
  this[globalName] = mainExports;
}

}

// Override the current require with this new one
parcelRequire = newRequire;

if (error) {
// throw error from earlier, after updating parcelRequire
throw error;
}

return newRequire;
})({"../node_modules/parcel-bundler/src/builtins/bundle-url.js":[function(require,module,exports) {
var bundleURL = null;

function getBundleURLCached() {
if (!bundleURL) {
bundleURL = getBundleURL();
}

return bundleURL;
}

function getBundleURL() {
// Attempt to find the URL of the current script and use that as the base URL
try {
throw new Error();
} catch (err) {
var matches = ('' + err.stack).match(/(https?|file|ftp|chrome-extension|moz-extension)://[^)\n]+/g);

if (matches) {
  return getBaseURL(matches[0]);
}

}

return '/';
}

function getBaseURL(url) {
return ('' + url).replace(/^((?:https?|file|ftp|chrome-extension|moz-extension)://.+)/[^/]+$/, '$1') + '/';
}

exports.getBundleURL = getBundleURLCached;
exports.getBaseURL = getBaseURL;
},{}],"../node_modules/parcel-bundler/src/builtins/css-loader.js":[function(require,module,exports) {
var bundle = require('./bundle-url');

function updateLink(link) {
var newLink = link.cloneNode();

newLink.onload = function () {
link.remove();
};

newLink.href = link.href.split('?')[0] + '?' + Date.now();
link.parentNode.insertBefore(newLink, link.nextSibling);
}

var cssTimeout = null;

function reloadCSS() {
if (cssTimeout) {
return;
}

cssTimeout = setTimeout(function () {
var links = document.querySelectorAll('link[rel="stylesheet"]');

for (var i = 0; i < links.length; i++) {
  if (bundle.getBaseURL(links[i].href) === bundle.getBundleURL()) {
    updateLink(links[i]);
  }
}

cssTimeout = null;

}, 50);
}

module.exports = reloadCSS;
},{"./bundle-url":"../node_modules/parcel-bundler/src/builtins/bundle-url.js"}],"../node_modules/parcel-bundler/src/builtins/hmr-runtime.js":[function(require,module,exports) {
var global = arguments[3];
var OVERLAY_ID = 'parcel__error__overlay';
var OldModule = module.bundle.Module;

function Module(moduleName) {
OldModule.call(this, moduleName);
this.hot = {
data: module.bundle.hotData,
_acceptCallbacks: [],
_disposeCallbacks: [],
accept: function (fn) {
this._acceptCallbacks.push(fn || function () {});
},
dispose: function (fn) {
this._disposeCallbacks.push(fn);
}
};
module.bundle.hotData = null;
}

module.bundle.Module = Module;
var checkedAssets, assetsToAccept;
var parent = module.bundle.parent;

if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
var hostname = "" || location.hostname;
var protocol = location.protocol === 'https:' ? 'wss' : 'ws';
var ws = new WebSocket(protocol + '://' + hostname + ':' + "57962" + '/');

ws.onmessage = function (event) {
checkedAssets = {};
assetsToAccept = [];
var data = JSON.parse(event.data);

if (data.type === 'update') {
  var handled = false;
  data.assets.forEach(function (asset) {
    if (!asset.isNew) {
      var didAccept = hmrAcceptCheck(global.parcelRequire, asset.id);

      if (didAccept) {
        handled = true;
      }
    }
  }); // Enable HMR for CSS by default.

  handled = handled || data.assets.every(function (asset) {
    return asset.type === 'css' && asset.generated.js;
  });

  if (handled) {
    console.clear();
    data.assets.forEach(function (asset) {
      hmrApply(global.parcelRequire, asset);
    });
    assetsToAccept.forEach(function (v) {
      hmrAcceptRun(v[0], v[1]);
    });
  } else {
    window.location.reload();
  }
}

if (data.type === 'reload') {
  ws.close();

  ws.onclose = function () {
    location.reload();
  };
}

if (data.type === 'error-resolved') {
  console.log('[parcel] ✨ Error resolved');
  removeErrorOverlay();
}

if (data.type === 'error') {
  console.error('[parcel] 🚨  ' + data.error.message + '\n' + data.error.stack);
  removeErrorOverlay();
  var overlay = createErrorOverlay(data);
  document.body.appendChild(overlay);
}

};
}

function removeErrorOverlay() {
var overlay = document.getElementById(OVERLAY_ID);

if (overlay) {
overlay.remove();
}
}

function createErrorOverlay(data) {
var overlay = document.createElement('div');
overlay.id = OVERLAY_ID; // html encode message and stack trace

var message = document.createElement('div');
var stackTrace = document.createElement('pre');
message.innerText = data.error.message;
stackTrace.innerText = data.error.stack;
overlay.innerHTML = '

' + 'ERROR' + '🚨' + '
' + message.innerHTML + '
' + '
' + stackTrace.innerHTML + '
' + '
';
return overlay;
}

function getParents(bundle, id) {
var modules = bundle.modules;

if (!modules) {
return [];
}

var parents = [];
var k, d, dep;

for (k in modules) {
for (d in modules[k][1]) {
dep = modules[k][1][d];

  if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) {
    parents.push(k);
  }
}

}

if (bundle.parent) {
parents = parents.concat(getParents(bundle.parent, id));
}

return parents;
}

function hmrApply(bundle, asset) {
var modules = bundle.modules;

if (!modules) {
return;
}

if (modules[asset.id] || !bundle.parent) {
var fn = new Function('require', 'module', 'exports', asset.generated.js);
asset.isNew = !modules[asset.id];
modules[asset.id] = [fn, asset.deps];
} else if (bundle.parent) {
hmrApply(bundle.parent, asset);
}
}

function hmrAcceptCheck(bundle, id) {
var modules = bundle.modules;

if (!modules) {
return;
}

if (!modules[id] && bundle.parent) {
return hmrAcceptCheck(bundle.parent, id);
}

if (checkedAssets[id]) {
return;
}

checkedAssets[id] = true;
var cached = bundle.cache[id];
assetsToAccept.push([bundle, id]);

if (cached && cached.hot && cached.hot._acceptCallbacks.length) {
return true;
}

return getParents(global.parcelRequire, id).some(function (id) {
return hmrAcceptCheck(global.parcelRequire, id);
});
}

function hmrAcceptRun(bundle, id) {
var cached = bundle.cache[id];
bundle.hotData = {};

if (cached) {
cached.hot.data = bundle.hotData;
}

if (cached && cached.hot && cached.hot._disposeCallbacks.length) {
cached.hot._disposeCallbacks.forEach(function (cb) {
cb(bundle.hotData);
});
}

delete bundle.cache[id];
bundle(id);
cached = bundle.cache[id];

if (cached && cached.hot && cached.hot._acceptCallbacks.length) {
cached.hot._acceptCallbacks.forEach(function (cb) {
cb();
});

return true;

}
}
},{}]},{},["../node_modules/parcel-bundler/src/builtins/hmr-runtime.js"], null)
//# sourceMappingURL=/index.js.map

Work arounds:-

  • import roughViz from 'node_modules/rough-viz/dist/rough-viz.min.js';
  • rename the roughviz.min.js to index.js (which is probably related to issue #7)

Thanks for the great package. They are a great alternative to the standard charts and makes the charts fun :)

Unifiy titleFontSize

Some charts have titleFontSize with a default value set to '1rem' and others set to '0.95rem'.
For consistency, I think that all charts should have the same default value.

nice! didn't you run into rough.js problems with size?

I've used rough.js in another context, and found that the roughness factor had to be set for each general range of size--for small objects, the roughness was off the charts, and for large minor, all given the same roughness factor.

Make charts responsive

I was thinking about making the charts responsive.

As far as I can tell, this may be done by changing the width and height attributes for this.svg in the setSvg() method to preserveAspectRatio and viewBox as follows:

Old:

setSvg() {
    this.svg = select(this.el)
      .append('svg')
      .attr('width', this.width + this.margin.left + this.margin.right)
      .attr('height', this.height + this.margin.top + this.margin.bottom)
      .append('g')
      .attr('id', this.roughId)
      .attr('transform',
        'translate(' + this.margin.left + ',' + this.margin.top + ')');
  }

New

setSvg() {
    this.svg = select(this.el)
      .append('svg')
      .attr("preserveAspectRatio", "xMinYMin meet")
     .attr("viewBox", `0 0 ${(this.width + this.margin.left + this.margin.right)}
       ${(this.height + this.margin.top + this.margin.bottom)}`)
      .append('g')
      .attr('id', this.roughId)
      .attr('transform',
        'translate(' + this.margin.left + ',' + this.margin.top + ')');
  }

I can wait to make this change after you've finished the ABC, but since you're working on it (and I believe setSVG() will be a method of the ABC), I figured you could add it, assuming it works.

Something to think about!

Originally posted by @jwilber in #32 (comment)

Deploy a 1.0.7

First off, I love this library, such a clever idea!

I'm building a website that is still a bit rough around the edges, and you can see that the graphs are broken (at the time of writing this), however this is a bug that has already been fixed.

It turns out that the contents of the dist folder in the npm package are not up to date, the src folder is all good, but there are 2 dist files and neither are more recent than a year.

Would you please consider rebuilding and publishing a 1.0.7?

Thanks again πŸ™‚

Different color bars in stacked bar

I messed with the example and changed the data on the 'March' row. I replaced B with D. (Perhaps March doesn't have a B)
Nothing happened.
I was expecting the March column (right-most) to have a different color for the D value.

data: [
      {month:'Jan', A:20, B: 5,  C: 10},
      {month:'Feb', A:25, B: 10, C: 20},
      {month:'March', A:30, D:50, C:10}
  ],

Legend for `roughViz.StackedBar`

I think it is not possible at the moment, but would it be possible to have a legend for roughViz.StackedBar?

Thanks in advance

x axis labels in line plot as strings

Hi,

I am trying to plot a line graph where my xaxis are times (as strings i.e. '7am'), I have the following code:

new roughViz.Line( { element: '#streaming', data: './static/availability.csv', title: 'Line Chart', x: 'time', y1: '# games', width: window.innerWidth / 2, } );

It will render if I remove 'x', but otherwise I can't get it to use strings as the values- possibly because it needs continuous values? If so, is there a workaround to replace the visible tick labels?

Thanks!

Legend overlaps title

Hi, when title is a bit longer, the legend overlaps the title text in Pie and Donut charts.
image

HTML links to labels/titles

Very cool project! I was just playing with this yesterday and I was wondering if there's a way to add HTML links to either the label and/or titles?

Clickable bar charts

I'm using a stacked bar chart and I'd like things to happen when the user clicks bars. At the moment, a legend floats under the mouse cursor but I'd like to do more. I'd click to display information underneath the chart about the bar you clicked on.

Abstract Class

Originally I wanted to create a chart Abstract Base Class with the common methods across the charts (e.g. resolveFont(), initChartValues(), setSVG(), resolveData(), etc.) but didn't find a straightforward manner of doing so in ES6. I'm sure it can be done easily enough with prototypal inheritance, but I'd prefer to keep everything as ES6 as possible.

I don't write too much JavaScript, so it's pretty likely that I missed something. Very open to any ideas!

Crash with a zero value in Pie/Donut chart with Firefox 70.0.1

Description

When a value is 0 in a pie/donut chart, it makes the browser freezing (consuming tons of memory).

How to reproduce

Open the example for Pie/Donut and set a data value to 0

Workarounds

  • Zero values could be filtered
  • You can put a very small value

Line data as Object (no csv or tsv)

Hey there !

Thanks for the fantastic work :-)

I'd love to use the RoughViz Line without having to create .csv or .tsv files (getting data directly from a private db).

Is this something that can be easily enabled ?

Line chart with local data

Hi, would it be possible to use a line chart with local data, eg. objects instead of .csv files?

Edit: found out that when you pass an object an error occurs: this.data.map is not a function. This is a bug in Line.js:464.

Would like to open a PR for this.

Installation via npm contains additional roughviz.min.js

Not really an issue but thought I would mention it. When installed via npm the dist folder contains two resources for the minified code:-

image

It wasn't immediately clear which one to use so maybe you can remove one.

Thanks for a great package.

Usage with React TypeScript

I have been having difficulties in integrating this with my TypeScript project. It is an amazing library but if there is an article or example I can refer to. Well, that would be amazing.

And I have tried to use react-roughviz as well but found the documentation majorly lacking. Any help would be highly appreciated.

Ability to clear and re-draw

I'm currently using ref.current.querySelectorAll("*").forEach(n => n.remove()); where ref.current refers to the DOM <div> element.
This kinda works but it appears the y-axis is changing which might be a bug but I'd rather figure out a way to re-draw or clear.

Python Implementation

Hello, thanks for making such awesome visualization style. I made a Python wrapper based on your RoughViz

You could check it out here:
https://github.com/charlesdong1991/py-roughviz

And would be appreciated if you'd like to add to your README, so that more people could see and try python version based on your library. ^^

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.