GithubHelp home page GithubHelp logo

redpandatronicsuk / arty-charty Goto Github PK

View Code? Open in Web Editor NEW
43.0 3.0 7.0 62 KB

React Native plugin for rendering charts using ART

License: MIT License

JavaScript 100.00%
chart area-chart bubble-chart stacked-charts candlestick-chart pie-chart render-charts bars-range-chart bars-3d-chart spline

arty-charty's Introduction

ARTy Charty

React Native plugin for rendering charts that used to use ART, but now switched to react-native-svg

About

The goal of ARTy Charty is to produce animated, interactive, performant charts. It uses React Native ART to render the charts. Arty Charty does not rely on 3rd party libraries, such as D3, to produce the charts. This keeps the size of the library small (<80kb uncompressed and not-minified) and chart generating functions can be optimised for speed.

We noticed some issues with the ART library, so we switched to use react-native-svg instead.

Installation

npm i --save arty-charty

You also need to have react-native-svg in your project. You can find instructins on how to install it here.

Usage

For more advanced usage have a look at the demo app here.

ArtyCharty

The ArtyCharty component is used to display line, spline, area, area-spline and bars charts. Charts can be stacked on top of each other by passing in an array of charts. Each chart object in the array needs to specify the kind of chart it is (line, spline, area, area-spline or bars) and an array of data points, where each data point needs to have a value field, which will be used as the value on the Y axis.

Simple line chart example

Simple line chart

import { ArtyCharty } from 'arty-charty';
...js
<ArtyCharty data={[{
          type: 'line',
          data: [{value: 2}, {value: 3}, {value: 1}]
        }]}/>

Stacked charts

Stacked charts

import { ArtyCharty } from 'arty-charty';
...
<ArtyCharty 
        data={[
     {
        type: 'area',
        data: [{value: 3.48}, {value: 1.38}, {value: 6.73}, {value: 4.62}, {value: 3.14}],
        highCol: 'rgb(255,0,0)',
        lowCol: 'rgb(255,165,0)'
    },
    {
        type: 'bars',
        data: [{value: 2.16}, {value: 4.83}, {value: 4.04}, {value: 4.30}, {value: 5.26}],
        highCol: 'rgb(125,0,255)',
        lowCol: 'rgb(0,255,0)'
    },
    {
        type: 'line',
        data: [{value: 4.47}, {value: 5.99}, {value: 1.21}, {value: 3.17}, {value: 4.24}],
        lineColor: 'green'
    },
    {
        type: 'spline',
        data: [{value: 3.10}, {value: 2.61}, {value: 3.89}, {value: 1.54}, {value: 1.32}],
        lineColor: 'rgba(255,255,0,.8)'
    },
        ]}/>

Stacked charts with animation and Y-axis ticks

This is the same data as before with animations and selectable line markers and bars enabled. Stacked charts

import { ArtyCharty } from 'arty-charty';
...
<ArtyCharty 
        interactive={true}
        yAxisLeft={{numberOfTicks: 5}}
        animated={true}
        clickFeedback={true}
        data={[
     {
        type: 'area',
        data: [{value: 3.48}, {value: 1.38}, {value: 6.73}, {value: 4.62}, {value: 3.14}],
        highCol: 'rgb(255,0,0)',
        lowCol: 'rgb(255,165,0)',
        drawChart: true
    },
    {
        type: 'bars',
        data: [{value: 2.16}, {value: 4.83}, {value: 4.04}, {value: 4.30}, {value: 5.26}],
        highCol: 'rgb(125,0,255)',
        lowCol: 'rgb(0,255,0)',
        drawChart: true
    },
    {
        type: 'line',
        data: [{value: 4.47}, {value: 5.99}, {value: 1.21}, {value: 3.17}, {value: 4.24}],
        lineColor: 'green'
    },
    {
        type: 'spline',
        data: [{value: 3.10}, {value: 2.61}, {value: 3.89}, {value: 1.54}, {value: 1.32}],
        lineColor: 'rgba(255,255,0,.8)'
    },
        ]}/>

Step chart

Step chart

<ArtyCharty
    interactive={true}
    animated={true}
    pointsOnScreen={20}
    data={[{
        type: 'step',
        lineColor: 'fuchsia',
        drawChart: true,
        data: Array.from(Array(40)).map(() => {
        let rand = Math.random() + 2;
        return {value: rand, valueLow: rand - Math.random() - .5};
        })}
        ]} />

Area-range chart

Area-range chart

 <ArtyCharty
    clickFeedback={true}
    interactive={true}
    animated={true}
    data={[{
        type: 'area-range',
        lineColor: 'rgba(255,0,0,.5)',
        highCol: 'rgb(255,0,0)',
        lowCol: 'rgb(255,165,0)',
        drawChart: true,
        data: Array.from(Array(20)).map(() => {
        let rand = Math.random() + 2;
        return {value: rand, valueLow: rand - Math.random() - .5};
        })}
        ]} />

Bars-range chart

Bars-range chart

<ArtyCharty
    interactive={true}
    clickFeedback={true}
    animated={true}
    data={[{
        type: 'bars-range',
        lineColor: 'fuchsia',
        data: Array.from(Array(20)).map(() => {
        let rand = Math.random() + 2;
        return {value: rand, valueLow: rand - Math.random() - .5};
        })}
        ]} />

Bars-3d chart

Bars-3d chart

<ArtyCharty
    animated={true}
    interactive={true}
    clickFeedback={true}
    data={[{
        type: 'bars-3d',
        drawChart: true,
        data: Array.from(Array(3)).map((u, idx) => {
        let col = `rgb(${Math.round(Math.random()*255)},${Math.round(Math.random()*255)},${Math.round(Math.random()*255)})`;
            return Array.from(Array(5)).map((u2, idx2) => {
            let val = Math.random();
            return {value: val, color: shadeColor(col, 1 - val)};
            });
        })
    }
    ]} />

Candlestick chart

Candlestick chart

 <ArtyCharty
    clickFeedback={true}
    interactive={true}
    animated={true}
    data={[{
        type: 'candlestick',
        lineColor: 'fuchsia',
        fillUp:  'orange',
        fillDown: 'rgba(0,0,0,0)',
        drawChart: true,
        data: Array.from(Array(20)).map(() => {
            let rand = Math.random() + 2, open, close, low, high;
            if (Math.random() > .5) {
            open = rand + Math.random();
            high = open + Math.random();
            close = rand - Math.random();
            low = close - Math.random();
            } else {
            open = rand - Math.random();
            low = open - Math.random();
            close = rand + Math.random();
            high = close + Math.random();
            }
            return {open, close, low, high};
        })},
        {
        type: 'candlestick',
        lineColor: 'blue',
        fillUp:  'green',
        fillDown: 'red',
        drawChart: true,
        data: Array.from(Array(20)).map(() => {
            let rand = Math.random() + 7, open, close, low, high;
            if (Math.random() > .5) {
            open = rand + Math.random();
            high = open + Math.random();
            close = rand - Math.random();
            low = close - Math.random();
            } else {
            open = rand - Math.random();
            low = open - Math.random();
            close = rand + Math.random();
            high = close + Math.random();
            }
            return {open, close, low, high};
        })}
        ]} />

Parameters

ArtyCharty component parameters
Parameter Type Description
animated boolean If set to true the chart will be animated. TODO: Add animation parameters to documentation (timing functions, etc...)
clickFeedback boolean If set to true a material design like click feedback is shown on clicks
interactive boolean If set to true line markers and bars are selectable.
onMarkerClick(clickedChartIdx, clickedEntryIdx) function If interactive is set to true, this function will be called with the first parameter being the index of the chart that was clicked and the second parameter the index of the data point on that chart that was clicked.
yAxisLeft object If this parameter is set, the yAxis will be drawn, with the specified options, e.g. {numberOfTicks: 3, TODO: Add more options...}
data array Array containing chart objects, see next section for description.
width number Width in pixels of the chart.
Chart object

The data parameter for the ArtyCharty component is an array of chart objects, with the following options:

Property Type Description
type string The type of the chart to render, available types: line, spline, area, area-spline, bars
data *array Array containing the data points of the chart. See table 'Data object' below for what the objects in this array should look like for the diferent chart types.
drawChart boolean If set to true the chart will be animated from left to right.
lineColor string The color of the line for line charts or the border color for the bar chart.
Area and bar chart only
highCol string The fill color for high values
lowCol string The fill color for low values
The fill color used for the bar or area chart for a specific point will be the interpolation between the high and low value. E.g. if highCol is set to red and lowCol to green, then the bar with the highest value will have a red fill and the one with the lowest value will have a green fill.
Data object
Chart type Description
line, spline, area, spline-area {value: number}
area-range {value: number, valueLow: number}
candlestick {open: number, close: number, low: number, high: number}

ArtyChartyPie

Pie chart

import { ArtyChartyPie } from 'arty-charty';
...
<ArtyChartyPie 
    data={{
    data: [
        {value: .6, color: 'red'},
        {value: 5, color: 'green'},
        {value: 3, color: 'blue'}]
}}/>

Parameters

Parameter Type Description
data array Array of data objects
onSliceClick(clickedSliceIdx) function Call back when a pie slice is clicked, the index of the clicked slice is passed as the argument to the callback function.
Data objects
Property Type Description
color string Color of the slice
value number Value

ArtyChartyDonut

Stacked donut chart

<ArtyChartyDonut
    style={{overflow: 'visible'}}
        data={{
        stackInnerRadius: 250,
        stackouterRadius: 400,
        gap: 15,
        data: [
        {data: [{ value: 84, color: "rgba(255,255,0,.75)"}, {value: 16, color: "rgba(50,50,50,.75)"}]},
        {data: [{value: 6, color: 'red'}, {value: 5, color: 'green'}, {value: 3, color: 'blue'}]},
        {data: [{value: 3, color: 'orange'}, {value: 15, color: 'purple'}, {value: 3, color: 'yellow'}]}
        ]
}}/>

Parameters

Parameter Type Description
data array Array of data objects
stackInnerRadius number The radius of the inner most donut chart
stackouterRadius number The radius of the outer most donut chart
gap number Gap size in pixels between donut charts
Data objects
Property Type Description
color string Color of the slice
value number Value

ArtyChartyRadar

Radar chart

import { ArtyChartyRadar } from 'arty-charty';
...
<ArtyChartyRadar 
  gridColor="orange"
  gridLineWidth={1}
  gridStrokeDash={[0,0,4,6]}
  gridTextColor="white"
  gridTextSize={18}
  labelsTextSize={28}
  labelsTextColor="white"
  fill="rgba(0,255,0,.1)"
  labels={['Pace', 'Shooting', 'Passing', 'Dribbling', 'Defending', 'Physical']}
  data={[
    {
      lineColor: 'black',
      markerColor: 'yellow',
      fill: 'rgba(85,37,130,.25)',
      data: Array.from(Array(6)).map(Math.random)
    },
    {
      lineColor: 'aqua',
      lineWidth: 5,
      strokeDash: [0,10],
      lineCap: 'round',
      markerColor: 'blue',
      fill: 'rgba(255,0,0,.25)',
      data: Array.from(Array(6)).map(Math.random)
    }
    ]}/>

Parameters

Parameter Type Description
gridColor string Color of the grid
gridLineWidth number Line width of the grid
gridStrokeDash array SVG dash-array of the grid line
gridTextColor string Color of the grid ticks text
gridTextSize number Size of the grid ticks text
labelsTextColor string Color of the outer labels text
labelsTextSize number Size of the outer labels text
fill string Backgroud color of the chart
Labels array Array of strings to use as labels
data array Array of data objects
onMarkerClick(clickedMarkerIdx, clickedChartIdx) function Call back when a markeris clicked, the index of the point is passed and the index of the dataset are passed as arguments to the callback function.
Data objects
Property Type Description
lineColor string Color of the line
lineWidth number Width of the line
lineCap string SVG line cap of the line
strokeDash array SVG dash-array of the line
markerColor string Color of the marker
fill string Fill color
data array Array of numbers

ArtyChartyXY

ArtyChartyXY is used to plot data on a X-Y axis, such as scatter and bubble charts.

Parameters

Parameter Type Description
type string The type of X-Y chart, either scatter or bubble.
data array Array of data objects.
animated boolean If set to true the chart will be animated.
width number The width of the chart.
height number The height of the chart.
showGrid boolean If set to true the grid will be shown.
pointRadius number The point radius for scatter charts only, for bubble charts, the bubble's radius is determined by its value
color string The color of the points or bubble, note: point colors can also be set individually, see below.
onPointClick(clickedPointIdx) function Callback function when a point is clicked with the index of the clicked point as the functions argument.

Scatter

Scatter chart

<ArtyChartyXY 
    showGrid={true} 
    type="scatter"
    pointRadius={3} 
    data={Array.from(Array(20)).map(()=> {
        return {x: Math.random()*20, y: Math.random()* 10
        }})}/>
Data objects
Property Type Description
x number X coordinate of the point
y number Y coordinate of the point
color string Color of the slice
value number Value

Bubble

Bubble chart

<ArtyChartyXY 
    type="bubble" 
    animated={true} 
    data={Array.from(Array(20)).map(()=> { 
    return {
        x: Math.random()*20, 
        y: Math.random()* 10, 
        value: Math.random()* 20, 
        color: `rgba(${Math.round(Math.random() * 255)},${Math.round(Math.random() * 255)},${Math.round(Math.random() * 255)}, .5)` }
    })}/>
Data objects

Same as for scatter with additionally:

Property Type Description
value number Value, used to determine the radius of the bubble.

ArtySparky

For the line and pie chart there is also a spark (inline chart) component, which are light-weight versions of their full chart components. Axes, animations, click interactions have been removed and the ability to stack charts.

ArtySparkyLine

ArtySparkyLine

<ArtySparkyLine 
    data={Array.from(Array(50)).map(Math.random)}
    color="fuchsia"
    width={300}
    height={50}
/>

ArtySparkyPie

ArtySparkyPie

<ArtySparkyPie
    data={{data: Array.from(Array(5)).map(() => {
        return {
            value: Math.random(),
            color: `rgb(${Math.round(Math.random()*255)},${Math.round(Math.random()*255)},${Math.round(Math.random()*255)})`
        }
    })}}
        size={50}
    />

ArtyChartyHeatmap

ArtyChartyHeatmap

<ArtyChartyHeatmap data={[
    [1,2,3,4,5,6],
    [7,8,9,10,11,12],
    [13,14,15,16,17,18],
    [19,20,21,22,23,24]
]} highColor="red" lowColor="blue" />

Contributing

If you find bugs or have any suggestions, please open an issue. Pull requests are also welcome. All charts are rendered as SVG paths, have a look at this CodePen if you want to get more familiar with SVG paths and how we use them to generate charts.

TO-DO:

  • Better documentation, add default values to parameter tables

  • Add more parameters: [markerRadius, selectedMarkerRadii, markerColor, selectedMarkerColors, yAxis stuff, xAxis, animation stuff] and imporve parameter names

  • More chart types [stacked-columns]

  • Nicer animations for adding/removing data points from the chart

  • Editable/draggable points with onValueChange callback function

  • Try replacing panlistener transformX with offset in render function, that can also be used to render only points shown on the screen!!!

arty-charty's People

Contributors

lprhodes avatar redpandatronicsuk 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

Watchers

 avatar  avatar  avatar

arty-charty's Issues

Fix width

Hi - how do you go about specifying a fixed width for the chart. I'm working with the spline charts and at the moment the width it dynamic based on the data points but ideally it would be a fixed width and the points would spread accordingly.

Can't find variable: SVG

It has an issue about SVG at

makeYaxis(num, minVal, maxVal) {
const width = this.props.width || Dimensions.get('window').width
let topY = (CHART_HEIGHT+CHART_HEIGHT_OFFSET) - this.maxValue * ((CHART_HEIGHT-MARKER_RADIUS)/this.maxValue);
let bottomY = CHART_HEIGHT+CHART_HEIGHT/2;
let i;
let interval = (bottomY - topY) / num;
let lineVal = this.maxValue;
let lineDecrement = (maxVal - minVal) / num;
let lines = [];
for (i = 0 ; i <= num; i++) {
lines.push(<Path key={i} strokeDash={[0, 0, 4, 6]} stroke="black" strokeWidth={.5} d={M 0 ${topY + interval * i} H ${width}} />);
lines.push(<SVG.Text key={1000+i} fill="black" stroke="white" strokeWidth={1} x={0} y={(topY + interval * i) - 22} font="20px Arial">{lineVal.toFixed(2)}</SVG.Text>);
lineVal -= lineDecrement;
}
return lines;
}

It won't work properly either when charts has a y axis with label.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.

Since we did not receive a CI status on the greenkeeper/initial branch, we assume that you still need to configure it.

If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with greenkeeper/.

We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

Once you have installed CI on this repository, you’ll need to re-trigger Greenkeeper’s initial Pull Request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper integration’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Display point value above/below each point

Hi dude! I found your chart lib awesome with many configuration possibilities but I was wondering if is possible to display the point value above/below each point.

Can I do it? how?

Thanks a lot!

Can we display some information in the chart?

Hi : )

This lib is so cool and I really love it.
I have one question, can we add some information, like label name, value into the chart (like ArtyChartyPie)?
I can't find the corresponding API in the readme.

Thanks!

ART to react-native-svg migration

There were some issue with the ART library on Android, so I decided to use react-native-svg instead. Not sure if that was a good idea though. I have some general questions, if you know the answer or can otherwise contribute to the discussion, please post a comment.

  1. I read the RN ART implementation is more efficient than react-native-svg, but that some while ago and might have changed. This is the main reason why I decided to use ART rather than react-native-svg in the first place!
  2. ART is already shipped with RN, whilst react-native-svg needs to be installed with npm. For iOS, ART needs to be linked manually in XCode, whilst for react-native-svg you can just use react-native link, so the effort for installing each one is about the same. Is it possible to make the SVG installation automatic by adding a post-install script or something like that to package.json?
  3. Does react-native-svg support the standard Animatable from RN? For ART that didn't work and I ended up writing a custom Tweener class, which updates values on the state in requestAnimatinFrame loop.
  4. What about the name? ARTy Charty no longer makes sense, but SVGy Charty doesn't sound as good. Any suggestions?

TO-DO

  • react-native-svg supports tags, so repeating stuff, such as markers, etc., should be only defined once in and then refer to it with afterwards
  • react-native-svg supports other elements than just Path, so maybe we can remove our functions that make SVG paths from shape parameters. test which is more efficient, probably using the react-native-svg elements
  • Check if all features still work, especially things like strokeDasharray, if I remember correctly, the ART implementation of that feature used slightly different parameters than normal SVG
  • Clean up code - the SVG migration was rather rushed and dirty, needs clean up!!

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.