0.0.10 • Published 4 years ago

react-native-web-svg-charts v0.0.10

Weekly downloads
49
License
-
Repository
github
Last release
4 years ago

version downloads license

react-native-web-svg-charts

A much improved decorator system has been introduced, allowing for greater flexibility and less complexity. See releases for more information.


Examples

In order to not bloat this README to much we've moved some examples over to 'Examples'. There we will try to showcase the really cool things you can do with this library. This README will try to keep things as simple as possible so that everybody can get up and running as fast as possible.

To run examples

yarn

cd web

yarn

yarn start

Prerequisites

This library uses react-native-svg to render its graphs. Therefore this library needs to be installed AND linked into your project to work.

react-native-reanimated for support animated path.

Other than the above dependencies this library uses pure javascript and supports iOS and Android and Web

Getting Started

Make sure to follow the installation mentioned in the Prerequisites

Then you can install the library using either yarn:

yarn add react-native-web-svg-charts react-native-svg react-native-reanimated

Now you're good to go!

Motivation

Creating beautiful graphs in React Native shouldn't be hard or require a ton of knowledge. We use react-native-svg in order to render our SVG's and to provide you with great extensibility. We utilize the very popular d3 library to create our SVG paths and to calculate the coordinates.

We built this library to be as extensible as possible while still providing you with the most common charts and data visualization tools out of the box. We're very proud of our "decorator" support. All charts can be extended with "decorators", a component that somehow styles or enhances your chart. Simply pass in a react-native-svg compliant component as a child to the graph and it will be called with all the necessary information to layout your decorator. See each chart for information on what data the decorator will be called with.

Common params

PropertyDefaultDescription
datarequiredAn array of arbitrary data - use prop xAccessor/yAccessorto tell the chart about the data structure
yAccessor({ item }) => itemA function that takes each entry of data (named "item") as well as the index and returns the y-value of that entry
xAccessor({ index }) => indexSame as yAccessor but returns the x-value of that entry
yScaled3Scale.scaleLinearA function that determines the scale of said axis (only tested with scaleLinear, scaleTime & scaleBand )
xScaled3Scale.scaleLinearSame as yScale but for the x axis
animatefalsePropTypes.bool
animationDuration300PropTypes.number
curved3.curveLinearA function like this
contentInset{ top: 0, left: 0, right: 0, bottom: 0 }An object that specifies how much fake "margin" to use inside of the SVG canvas. This is particularly helpful on Android where overflow: "visible" isn't supported and might cause clipping. Note: important to have same contentInset on axis's and chart
numberOfTicks10We use d3-array to evenly distribute the grid and dataPoints on the yAxis. This prop specifies how many "ticks" we should try to render. Note: important that this prop is the same on both the chart and on the yAxis
showGridtrueWhether or not to show the grid lines
yMinundefinedAlter how the chart bounds are calculated
yMaxundefinedAlter how the chart bounds are calculated
xMinundefinedAlter how the chart bounds are calculated
xMaxundefinedAlter how the chart bounds are calculated

Common arguments to children

PropertyDescription
xa function that normally accepts the index of a data point an returns its 'x' location on the canvas
ya function that normally accepts the value of a data point an returns its 'y' location on the canvas
widththe width of the canvas in pixels
heightthe height of the canvas in pixels
datathe same data array provided to the chart, use this to map over your data points if you want decorators on each point
ticksif numberOfTicks has been provided to the chart this array will include the calculated tick values (useful for grids)

Components

This library currently provides the following components

Also see

AreaChart

Area chart

Example

import React from "react";
import * as shape from "d3-shape";
import {
  Chart,
  Grid,
  Path,
  useChart,
  useArea,
  useLayout,
} from "react-native-web-svg-charts";

const AreaChartExample = () => {
  const data = [50, 10, 40, 95, -4, -24, 85, 91, 35, 53, -53, 24, 50, -20, -80];

  const { width, height, onLayout } = useLayout();

  const { x, y, ticks, mappedData } = useChart({
    width,
    height,
    data,
    contentInset: { top: 30, bottom: 30 },
  });
  const { area } = useArea({
    mappedData,
    x,
    y,
    curve: shape.curveNatural,
  });

  return (
    <Chart style={{ height: 200 }} {...{ width, height, onLayout }}>
      <Grid y={y} ticks={ticks} />
      <Path fill="rgba(134, 65, 244, 0.8)" d={area} />
    </Chart>
  );
};

Props

See Common Props

PropertyDefaultDescription
start0The value of which the area should start (will always end on the data point)

Arguments to children

Supports all Common arguments to children

StackedAreaChart

Very similar to an area chart but with multiple sets of data stacked together. We suggest that you read up on d3 stacks in order to better understand this chart and its props See Area stack chart with Y axis to see how to use a YAxis with this component Use the svgs prop to pass in react-native-svg compliant props to each area.

Stacked area chart

Example

import React from "react";
import * as shape from "d3-shape";
import {
  Chart,
  Grid,
  Path,
  useStackArea,
  useLayout,
} from "react-native-web-svg-charts";

const AreaStackChartExample = () => {
  const data = [
    {
      month: new Date(2015, 0, 1),
      apples: 3840,
      bananas: 1920,
      cherries: 960,
      dates: 400,
    },
    {
      month: new Date(2015, 1, 1),
      apples: 1600,
      bananas: 1440,
      cherries: 960,
      dates: 400,
    },
    {
      month: new Date(2015, 2, 1),
      apples: 640,
      bananas: 960,
      cherries: 3640,
      dates: 400,
    },
    {
      month: new Date(2015, 3, 1),
      apples: 3320,
      bananas: 480,
      cherries: 640,
      dates: 400,
    },
  ];

  const colors = ["#8800cc", "#aa00ff", "#cc66ff", "#eeccff"];
  const keys = ["apples", "bananas", "cherries", "dates"];
  const svgs = [
    { onPress: () => console.log("apples") },
    { onPress: () => console.log("bananas") },
    { onPress: () => console.log("cherries") },
    { onPress: () => console.log("dates") },
  ];

  const { width, height, onLayout } = useLayout();

  const { areas, ticks, y } = useStackArea({
    width,
    height,
    data,
    keys,
    curve: shape.curveNatural,
  });

  return (
    <Chart
      style={{ height: 200, paddingVertical: 16 }}
      {...{ width, height, onLayout }}
    >
      <Grid {...{ y, ticks }} />
      {areas.map(({ path, line, key }, index) => (
        <Fragment {...{ key }}>
          <Path fill={colors[index]} {...svgs[index]} d={path} />
          <Line {...{ line }} />
        </Fragment>
      ))}
    </Chart>
  );
};

const Line = ({ line }) => {
  return <Path d={line} stroke={"green"} fill={"none"} />;
};

Props

PropertyDefaultDescription
datarequiredAn array of the data entries
keysrequiredThis array should contain the object keys of interest (see above example)
colorsrequiredAn array of equal size as keys with the color for each key
orderd3.stackOrderNoneThe order in which to sort the areas
offsetd3.stackOffsetNoneA function to determine the offset of the areas

Also see Common Props

Arguments to children

PropertyDescription
xa function that normally accepts the index of a data points an returns its 'x' location on the canvas
ya function that normally accepts the value of a data points an returns its 'y' location on the canvas
widththe width of the canvas in pixels
heightthe height of the canvas in pixels
data~~the same data array provided to the chart, use this to map over your data points if you want decorators on each point~
ticksif numberOfTicks has been provided to the chart this array will include the calculated tick values (useful for grids)

This chart does not call a child with the data argument. This is due to the fact that a lot of calculations go into creating the stacked chart, meaning that the original data prop doesn't provide especially valuable information when trying to layout decorators. It does however call with the rest of the common arguments

BarChart

Bar chart

Example

import React from "react";
import { BarChart, Grid } from "react-native-web-svg-charts";

class BarChartExample extends React.PureComponent {
  render() {
    const fill = "rgb(134, 65, 244)";
    const data = [
      50,
      10,
      40,
      95,
      -4,
      -24,
      null,
      85,
      undefined,
      0,
      35,
      53,
      -53,
      24,
      50,
      -20,
      -80,
    ];

    return (
      <BarChart
        style={{ height: 200 }}
        data={data}
        svg={{ fill }}
        contentInset={{ top: 30, bottom: 30 }}
      >
        <Grid />
      </BarChart>
    );
  }
}

Props

Also see Common Props

PropertyDefaultDescription
datarequiredThe data prop in a barChart can look exactly like in a Line- or AreaChart, i.e an array of just numbers or complex objects. It can however also be an array with several data sets. A data object can contain a svg property which allows you two override styles on that specific object. See the examples repo
horizontalfalseBoolean whether or not the bars should be horizontal
svg{}Default svg props for all bars. Supports all svg props an svg path normally supports. This styles will be overridden if there are specific styles for a given data object
spacingInner0.05Spacing between the bars (or groups of bars)
spacingOuter0.05Spacing outside of the bars (or groups of bars). Percentage of one bars width
contentInset{ top: 0, left: 0, right: 0, bottom: 0 }PropTypes.shape

Arguments to children

PropertyDescription
bandwidththe width of a band (a.k.a bar)

Also supports all Common arguments to children

StackedBarChart

The same as the StackedAreaChart except with bars (and different svgs prop). We suggest that you read up on d3 stacks in order to better understand this chart and its props

The svgs prop here is not based on keys, but rather entries, as the user might want to specify different props for each entry in each bar. Therefore each key entry can contain a complex object that contains e.g an svg prop. See this example for inspiration

Stacked bar chart Stacked bar chart - horizontal

Example

import React from "react";
import { StackedBarChart } from "react-native-web-svg-charts";

class StackedBarChartExample extends React.PureComponent {
  render() {
    const data = [
      {
        month: new Date(2015, 0, 1),
        apples: 3840,
        bananas: 1920,
        cherries: 960,
        dates: 400,
        oranges: 400,
      },
      {
        month: new Date(2015, 1, 1),
        apples: 1600,
        bananas: 1440,
        cherries: 960,
        dates: 400,
      },
      {
        month: new Date(2015, 2, 1),
        apples: 640,
        bananas: 960,
        cherries: 3640,
        dates: 400,
      },
      {
        month: new Date(2015, 3, 1),
        apples: 3320,
        bananas: 480,
        cherries: 640,
        dates: 400,
      },
    ];

    const colors = ["#7b4173", "#a55194", "#ce6dbd", "#de9ed6"];
    const keys = ["apples", "bananas", "cherries", "dates"];

    return (
      <StackedBarChart
        style={{ height: 200 }}
        keys={keys}
        colors={colors}
        data={data}
        showGrid={false}
        contentInset={{ top: 30, bottom: 30 }}
      />
    );
  }
}

Props

PropertyDefaultDescription
datarequiredAn array of the data entries: each value can be a number or a complex object with custom svg props for example
keysrequiredThis array should contain the object keys of interest (see above example)
colorsrequiredAn array of equal size as keys with the color for each key
valueAccessor({ item, key }) => itemkeyVery similar to the yAccessor of the other charts, usually needed when using complex objects as values
horizontalfalseBoolean whether or not the bars should be horizontal
orderd3.stackOrderNoneThe order in which to sort the areas
offsetd3.stackOffsetNoneA function to determine the offset of the areas

Also see Common Props

Arguments to children

PropertyDescription
xa function that normally accepts the index of a data points an returns its 'x' location on the canvas
ya function that normally accepts the value of a data points an returns its 'y' location on the canvas
widththe width of the canvas in pixels
heightthe height of the canvas in pixels
datathe same data array provided to the chart, use this to map over your data points if you want decorators on each point
ticksif numberOfTicks has been provided to the chart this array will include the calculated tick values (useful for grids)

This chart does not call a child with the data argument. This is due to the fact that a lot of calculations go into creating the stacked chart, meaning that the original data prop doesn't provide especially valuable information when trying to layout decorators. It does however call with the rest of the common arguments

LineChart

Line chart

Example

import React from "react";
import { Grid, Path, Chart, useLayout, useChart, useLine } from "react-native-web-svg-charts;

const LineChartExample = () => {
  const data = [50, 10, 40, 95, -4, -24, 85, 91, 35, 53, -53, 24, 50, -20, -80];

  const { width, height, onLayout } = useLayout();

  const { x, y, ticks, mappedData } = useChart({
    width,
    height,
    data,
    contentInset: { top: 20, bottom: 20 },
  });
  const { line } = useLine({
    mappedData,
    x,
    y,
  });

  return (
    <Chart style={{ height: 200 }} {...{ width, height, onLayout }}>
      <Grid y={y} ticks={ticks} />
      <Path
        fill="none"
        stroke="rgb(134, 65, 244)"
        d={line}
        animate
        animationDuration={300}
      />
    </Chart>
  );
};

Props

See Common Props

Arguments to children

Supports all Common arguments to children

PieChart

The PieChart is a really nice component with great support for custom behavior. See more examples in the examples repo

Pie chart

Example

import React from "react";
import { PieChart } from "react-native-web-svg-charts";

class PieChartExample extends React.PureComponent {
  render() {
    const data = [
      50,
      10,
      40,
      95,
      -4,
      -24,
      85,
      91,
      35,
      53,
      -53,
      24,
      50,
      -20,
      -80,
    ];

    const randomColor = () =>
      ("#" + ((Math.random() * 0xffffff) << 0).toString(16) + "000000").slice(
        0,
        7,
      );

    const pieData = data
      .filter(value => value > 0)
      .map((value, index) => ({
        value,
        svg: {
          fill: randomColor(),
          onPress: () => console.log("press", index),
        },
        key: `pie-${index}`,
      }));

    return <PieChart style={{ height: 200 }} data={pieData} />;
  }
}

Props

PropertyDefaultDescription
datarequiredVery similar to the data prop of our other charts, the only exception is that the PieChart only accepts complex objects (not just numbers). An item can also contain the arc property which allows you two override settings on that specific arc. See examples repo
valueAccessor({ item }) => item.valueVery similar to the yAccessor of the other charts
outerRadius"100%"The outer radius, use this to tweak how close your pie is to the edge of it's container. Takes either percentages or absolute numbers (pixels)
innerRadius"50%"The inner radius, use this to create a donut. Takes either percentages or absolute numbers (pixels)
labelRadiusundefinedThe radius of the circle that will help you layout your labels. Takes either percentages or absolute numbers (pixels)
padAngleThe angle between the slices
startAngle0The start angle in radians of the entire pie
endAngleMath.PI * 2The end angle in radians of the entire pie
sort(a,b) => b.value - a.valueLike any normal sort function it expects either 0, a positive or negative return value. The arguments are each an object from the dataPoints array

Arguments to children

PropertyDescription
widththe width of the canvas in pixels
heightthe height of the canvas in pixels
slicesan array of the pie chart slices. See source code and examples for what it includes
datathe same data array provided to the chart, use this to map over your data points if you want decorators on each point

ProgressCircle

Progress circle

Example

import React from "react";
import { ProgressCircle } from "react-native-web-svg-charts";

class ProgressCircleExample extends React.PureComponent {
  render() {
    return (
      <ProgressCircle
        style={{ height: 200 }}
        progress={0.7}
        progressColor={"rgb(134, 65, 244)"}
      />
    );
  }
}

Props

PropertyDefaultDescription
progressrequiredPropTypes.number.isRequired
progressColor'black'PropTypes.any
backgroundColor'#ECECEC'PropTypes.any
startAngle0PropTypes.number
endAngleMath.PI * 2PropTypes.number
strokeWidth5PropTypes.number
cornerRadius45PropTypes.number

Arguments to children

PropertyDescription
widththe width of the canvas in pixels
heightthe height of the canvas in pixels
datathe same data array provided to the chart, use this to map over your data points if you want decorators on each point

YAxis

Y-axis

A helper component to layout your Y-axis labels on the same coordinates as your chart. It's very important that the component has the exact same view bounds (preferably wrapped in the same parent view) as the chart it's supposed to match. If the chart has property contentInset set it's very important that the YAxis has the same vertical contentInset.

Example

import React from "react";
import { LineChart, YAxis, Grid } from "react-native-web-svg-charts";
import { View } from "react-native";

class YAxisExample extends React.PureComponent {
  render() {
    const data = [
      50,
      10,
      40,
      95,
      -4,
      -24,
      85,
      91,
      35,
      53,
      -53,
      24,
      50,
      -20,
      -80,
    ];

    const contentInset = { top: 20, bottom: 20 };

    return (
      <View style={{ height: 200, flexDirection: "row" }}>
        <YAxis
          data={data}
          contentInset={contentInset}
          fill="grey"
          fontSize={10}
          numberOfTicks={10}
          formatLabel={value => `${value}ºC`}
        />
        <LineChart
          style={{ flex: 1, marginLeft: 16 }}
          data={data}
          svg={{ stroke: "rgb(134, 65, 244)" }}
          contentInset={contentInset}
        >
          <Grid />
        </LineChart>
      </View>
    );
  }
}

XAxis

Line chart

A helper component to layout your X-axis labels on the same coordinates as your chart. It's very important that the component has the exact same view bounds (preferably wrapped in the same parent view) as the chart it's supposed to match. If the chart has property contentInset set it's very important that the XAxis has the same horizontal contentInset.

The XAxis also supports the xAccessor prop, if it's not supplied it will assume that you're only interested in the index of the data set.

Example

import React from "react";
import { LineChart, XAxis, Grid } from "react-native-web-svg-charts";
import { View } from "react-native";

class XAxisExample extends React.PureComponent {
  render() {
    const data = [
      50,
      10,
      40,
      95,
      -4,
      -24,
      85,
      91,
      35,
      53,
      -53,
      24,
      50,
      -20,
      -80,
    ];

    return (
      <View style={{ height: 200, padding: 20 }}>
        <LineChart
          style={{ flex: 1 }}
          data={data}
          gridMin={0}
          contentInset={{ top: 10, bottom: 10 }}
          svg={{ stroke: "rgb(134, 65, 244)" }}
        >
          <Grid />
        </LineChart>
        <XAxis
          style={{ marginHorizontal: -10 }}
          data={data}
          formatLabel={(value, index) => index}
          contentInset={{ left: 10, right: 10 }}
          fontSize={10}
          fill="black"
        />
      </View>
    );
  }
}

Grid

This library provides a helper component for drawing grids. Simply place it as child to the chart of your choice and (if necessary) set its direction.

Props

PropertyDefaultDescription
svg{}an object containing all the props that should be passed down to the underlying react-native-svg component. See available props
directionGrid.Direction.HORIZONTALThe direction of the grid lines.
belowCharttruewhether or not to render below the chart

Contributing

Feedback and PR's are more than welcome 🙂

0.0.10

4 years ago

0.0.9

4 years ago

0.0.8

4 years ago

0.0.7

4 years ago

0.0.5

4 years ago

0.0.6

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago