diff --git a/.babelrc b/.babelrc
index 2bcd546d..7d30f8bf 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,8 +1,3 @@
{
- "presets": ["babel-preset-expo"],
- "env": {
- "development": {
- "plugins": ["transform-react-jsx-source"]
- }
- }
+ "presets": ["babel-preset-expo"]
}
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 00000000..5e603ecd
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "react-app"
+}
diff --git a/.gitignore b/.gitignore
index 1025e17b..ae31869b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,8 @@
node_modules/
.expo/
+.DS_Store
npm-debug.*
+package-lock.json
+.idea
+.vscode
+yarn.lock
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
index a3793247..6e2cdcf4 100644
--- a/.npmignore
+++ b/.npmignore
@@ -2,3 +2,4 @@ node_modules/
.expo/
npm-debug.*
/promo
+.babelrc
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/App.js b/App.js
index 464f9644..f835c519 100644
--- a/App.js
+++ b/App.js
@@ -1,106 +1,119 @@
-import React from 'react'
-import { ScrollView, StatusBar, Dimensions, Text } from 'react-native'
-import ScrollableTabView from 'react-native-scrollable-tab-view'
-import LineChart from './src/line-chart'
-import PieChart from './src/pie-chart'
-import ProgressChart from './src/progress-chart'
-import BarChart from './src/bar-chart'
-import ContributionGraph from './src/contribution-graph'
-import { data, contributionData, pieChartData, progressChartData } from './data'
-import 'babel-polyfill'
+import "babel-polyfill";
+import React from "react";
+import { ScrollView, StatusBar, Dimensions, Text } from "react-native";
+import ScrollableTabView from "react-native-scrollable-tab-view";
+import FlashMessage, { showMessage } from "react-native-flash-message";
+import LineChart from "./src/line-chart";
+import PieChart from "./src/pie-chart";
+import ProgressChart from "./src/progress-chart";
+import BarChart from "./src/bar-chart";
+import StackedBarChart from "./src/stackedbar-chart";
+import ContributionGraph from "./src/contribution-graph";
+import {
+ data,
+ contributionData,
+ pieChartData,
+ progressChartData,
+ stackedBarGraphData
+} from "./data";
// in Expo - swipe left to see the following styling, or create your own
const chartConfigs = [
{
- backgroundColor: '#000000',
- backgroundGradientFrom: '#1E2923',
- backgroundGradientTo: '#08130D',
+ backgroundColor: "#000000",
+ backgroundGradientFrom: "#1E2923",
+ backgroundGradientTo: "#08130D",
color: (opacity = 1) => `rgba(26, 255, 146, ${opacity})`,
style: {
borderRadius: 16
}
},
{
- backgroundColor: '#022173',
- backgroundGradientFrom: '#022173',
- backgroundGradientTo: '#1b3fa0',
+ backgroundColor: "#022173",
+ backgroundGradientFrom: "#022173",
+ backgroundGradientTo: "#1b3fa0",
color: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
style: {
borderRadius: 16
+ },
+ propsForBackgroundLines: {
+ strokeDasharray: "" // solid background lines with no dashes
}
},
{
- backgroundColor: '#ffffff',
- backgroundGradientFrom: '#ffffff',
- backgroundGradientTo: '#ffffff',
+ backgroundColor: "#ffffff",
+ backgroundGradientFrom: "#ffffff",
+ backgroundGradientTo: "#ffffff",
color: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`
},
{
- backgroundColor: '#26872a',
- backgroundGradientFrom: '#43a047',
- backgroundGradientTo: '#66bb6a',
+ backgroundColor: "#26872a",
+ backgroundGradientFrom: "#43a047",
+ backgroundGradientTo: "#66bb6a",
color: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
style: {
borderRadius: 16
}
},
{
- backgroundColor: '#000000',
- backgroundGradientFrom: '#000000',
- backgroundGradientTo: '#000000',
+ backgroundColor: "#000000",
+ backgroundGradientFrom: "#000000",
+ backgroundGradientTo: "#000000",
color: (opacity = 1) => `rgba(${255}, ${255}, ${255}, ${opacity})`
- }, {
- backgroundColor: '#0091EA',
- backgroundGradientFrom: '#0091EA',
- backgroundGradientTo: '#0091EA',
+ },
+ {
+ backgroundColor: "#0091EA",
+ backgroundGradientFrom: "#0091EA",
+ backgroundGradientTo: "#0091EA",
color: (opacity = 1) => `rgba(${255}, ${255}, ${255}, ${opacity})`
},
{
- backgroundColor: '#e26a00',
- backgroundGradientFrom: '#fb8c00',
- backgroundGradientTo: '#ffa726',
+ backgroundColor: "#e26a00",
+ backgroundGradientFrom: "#fb8c00",
+ backgroundGradientTo: "#ffa726",
color: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
style: {
borderRadius: 16
}
},
{
- backgroundColor: '#b90602',
- backgroundGradientFrom: '#e53935',
- backgroundGradientTo: '#ef5350',
+ backgroundColor: "#b90602",
+ backgroundGradientFrom: "#e53935",
+ backgroundGradientTo: "#ef5350",
color: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
style: {
borderRadius: 16
}
},
{
- backgroundColor: '#ff3e03',
- backgroundGradientFrom: '#ff3e03',
- backgroundGradientTo: '#ff3e03',
+ backgroundColor: "#ff3e03",
+ backgroundGradientFrom: "#ff3e03",
+ backgroundGradientTo: "#ff3e03",
color: (opacity = 1) => `rgba(${0}, ${0}, ${0}, ${opacity})`
}
-]
+];
export default class App extends React.Component {
renderTabBar() {
- return
+ return ;
}
+
render() {
- const width = Dimensions.get('window').width
- const height = 220
+ const { width } = Dimensions.get("window");
+ const height = 256;
return (
{chartConfigs.map(chartConfig => {
const labelStyle = {
color: chartConfig.color(),
marginVertical: 10,
- textAlign: 'center',
+ textAlign: "center",
fontSize: 16
- }
+ };
const graphStyle = {
marginVertical: 8,
...chartConfig.style
- }
+ };
return (
Bezier Line Chart
+ showMessage({
+ message: `${value}`,
+ description: "You selected this value",
+ backgroundColor: getColor(0.9)
+ })
+ }
+ formatXLabel={label => label.toUpperCase()}
/>
+
Progress Chart
Bar Graph
+ Stacked Bar Graph
+
Pie Chart
Line Chart
@@ -155,15 +193,105 @@ export default class App extends React.Component {
values={contributionData}
width={width}
height={height}
- endDate={new Date('2016-05-01')}
+ endDate={new Date("2016-05-01")}
numDays={105}
chartConfig={chartConfig}
style={graphStyle}
/>
+ Line Chart
+
+ Line Chart with shadow background as line color
+
+
+ Scrollable Line Chart
+ "#FF5500",
+ labelColor: (opacity = 1) => "#A0A0A0",
+ linejoinType: "round",
+
+ scrollableDotFill: "#fff",
+ scrollableDotRadius: 6,
+ scrollableDotStrokeColor: "#FF5500",
+ scrollableDotStrokeWidth: 3,
+
+ scrollableInfoViewStyle: {
+ justifyContent: "center",
+ alignContent: "center",
+ backgroundColor: "#121212",
+ borderRadius: 2
+ },
+ scrollableInfoTextStyle: {
+ color: "#C4C4C4",
+ marginHorizontal: 4,
+ flex: 1,
+ textAlign: "center"
+ },
+ scrollableInfoSize: { width: 65, height: 30 },
+ scrollableInfoOffset: 15
+ }}
+ style={{
+ marginVertical: 8
+ }}
+ />
- )
+ );
})}
- )
+ );
}
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..2b621c0b
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,148 @@
+# Changelog
+
+## v5.6.1
+
+- fixed linear gradient issue due to `react-native-svg` lib update
+- added handling for datasets data is null to use last line coordinates
+- updated to Expo SDK 37 and add clarification on usage to README.md
+
+## v5.6.0
+
+- added `showValuesOnTopOfBars` prop to `BarChart`
+- fixed decimalPlaces being 0 and not applied in `BarChart`
+
+## v5.5.0
+
+- added `useShadowColorFromDataset` to `chartConfig` to make `LineChart` shadow same as line color
+
+## v5.4.2
+
+- fixed decimalPlaces not being sent with barChart
+
+## v5.4.0
+
+- added strokeWidth & radius as props for ProgressChart
+
+## v5.3.1
+
+- TS type fixes
+
+## v5.3.0
+
+- added missing ContributionGraph props
+- added `withScrollableDot` to LineChart and a whole bunch of props to `chartConfig`. New feature for Line Chart - scrollable dot. It allows to navigate through chart using gesture and see value at dot's current position.
+
+## v5.2.0
+
+- `propsForDots` added to `ChartConfig` interface
+
+## 5.1.1
+
+- add some safe default values in BarChart's `chartConfig` to avoid potential null pointers
+
+## 5.1.0
+
+- added a withDots property to each dataset in LineChart to disable dots on these lines
+- removed `prop-types`
+- added `onDayPress` to ContributionGraph
+
+## 5.0.0
+
+- made ContributionGraph opacity distribution even through range between the min and max values
+- added `getMonthLabel` to ContributionGraph
+- added `yAxisInterval` to LineChart, it allows you to skip vertical lines in the background
+- expaned StackedBarChart if it has no legend
+
+## 4.5.0
+
+- removed `.babelrc` from distribution
+- made decimalPlaces work for StackedBar Chart
+
+## 4.4.0
+
+- added ability to add custom segments on the Y-Axis
+- implemented barRadius config in BarChart
+- added showBarTops prop to BarChart
+
+## 4.3.0
+
+- added `barPercentage?: number; hideLegend: boolean;` props to StackedBarChart
+- added `barRadius` to chart config
+- added `renderDotContent` to LineChart
+
+## 4.2.0
+
+- line chart supports legend
+
+## 4.1.0
+
+- add `hideLegend` to ProgressChart
+
+## v4.0.0
+
+- patched a lot of indirect dependencies
+- improved ProgressChartProps types
+- added item index to some color calls
+- added an optional bottom padding to LineChart
+- POTENTIALLY BREAKING for typescript: added some typedefs to "LineChart", "BarChart", and "StackedBarChart". Also added some typedefs for styles.
+- corrected the line-chart & progress-chart wrong width calculation
+
+## v3.12.0
+
+- added `formatXLabel`, `formatYLabel`, and `getDotProps` to `LineChart`
+
+## v3.11.0
+
+- added optional props: `xAxisLabel`, `yAxisSuffix`, `yLabelsOffset`, `xLabelsOffset`, and `hidePointsAtIndex` to `LineChart`
+- added optional prop `withInnerLines` to `BarChart`
+- added optional `fillShadowGradient` color and `fillShadowGradientOpacity` to chart config for customizing the area under the data points in `LinChart` and `BarChart`
+
+## v3.10.0
+
+- added type for chart config
+- added props config for Dots in the line chart
+
+## v3.9.0
+
+- added propsForLabels to chartConfig
+- added labelColor to chartConfig as a shortcut for propsForLabels / fill
+
+## v3.8.0
+
+- added dot cx, cy in the onDataPointClick functions arguments
+- fixed for horizontal label position when there is only one data point and fromZero prop is true
+
+## v3.7.0
+
+- expose paddingTop and paddingRight via the style prop
+- style the chart background lines with chartConfig's propsForBackgroundLines
+
+## v3.6.0
+
+- added barPercentage property to chartConfig (by @dchirutac)
+- added dot color callback prop (by @stephenc222)
+- added bar chart label rotations (by @stephenc222)
+
+## v3.5.0
+
+- added `horizontalLabelRotation` and `verticalLabelRotation` props to `LineChart`
+
+## v3.4.0
+
+- added `chartConfig` `backgroundGradientFromOpacity` and `backgroundGradientToOpacity`
+
+## 3.3.0
+
+- added `index` to `onDataPointClick`
+
+## 3.2.0
+
+- added optional labels for ProgressChart
+
+## 3.1.0
+
+- added withVerticalLabels and withHorizontalLabels to LineChart, BarChart and StackedBarChart
+
+## 3.0.0
+
+- added typescript types
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..2b472bfd
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 indiespirit
+
+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.
diff --git a/README.md b/README.md
index c5c4a304..84822dcb 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,18 @@
+If you're looking to **build a website or a cross-platform mobile app** – we will be happy to help you! Send a note to clients@ui1.io and we will be in touch with you shortly.
+

+[📲See example app](https://github.com/indiespirit/react-native-chart-kit-example)
+
+To try the examples in Expo, please change `main` to `./node_modules/expo/AppEntry.js` in `package.json` before starting things with `expo run`. You'll need to have `expo-cli` installed via `npm install -g expo-cli`.
+
# React Native Chart Kit Documentation
## Import components
+
1. `yarn add react-native-chart-kit`
-2. Use with ES6 syntax to import components
+2. `yarn add react-native-svg` install peer dependencies
+3. Use with ES6 syntax to import components
```js
import {
@@ -12,40 +20,51 @@ import {
BarChart,
PieChart,
ProgressChart,
- ContributionGraph
-} from 'react-native-chart-kit'
-
+ ContributionGraph,
+ StackedBarChart
+} from "react-native-chart-kit";
```
## Quick Example
+
```jsx
-
- Bezier Line Chart
-
+ Bezier Line Chart
`rgba(255, 255, 255, ${opacity})`,
+ labelColor: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
style: {
borderRadius: 16
+ },
+ propsForDots: {
+ r: "6",
+ strokeWidth: "2",
+ stroke: "#ffa726"
}
}}
bezier
@@ -58,26 +77,58 @@ import {
```
## Chart style object
+
Define a chart style object with following properies as such:
+
```js
const chartConfig = {
- backgroundGradientFrom: '#1E2923',
- backgroundGradientTo: '#08130D',
- color: (opacity = 1) => `rgba(26, 255, 146, ${opacity})`
-}
+ backgroundGradientFrom: "#1E2923",
+ backgroundGradientFromOpacity: 0,
+ backgroundGradientTo: "#08130D",
+ backgroundGradientToOpacity: 0.5,
+ color: (opacity = 1) => `rgba(26, 255, 146, ${opacity})`,
+ strokeWidth: 2, // optional, default 3
+ barPercentage: 0.5,
+ useShadowColorFromDataset: false, // optional
+ gutterTop: 10, // optional, default dynamic size: 10% * innerHeight after paddingTop and paddingBottom
+ horizontalLabelWidth: 30, // optional, default dynamic size:20% * innerHeight after paddingTop and paddingBottom
+ verticalLabelHeight: 30, // optional, default dynamic size: 15% * innerWidth after paddingLeft and paddingRight
+ chartStyle: { //optional
+ borderRadius: 10, //default 0
+ paddingTop: 10, //default 0
+ paddingBottom: 10,
+ paddingLeft: 10,
+ paddingRight: 10,
+ },
+};
```
-| Property | Type | Description |
-| ------------- |-------------| -----|
-| backgroundGradientFrom | string | Defines the first color in the linear gradient of a chart's background |
-| backgroundGradientTo | string | Defines the second color in the linear gradient of a chart's background |
-| color | function => string | Defines the base color function that is used to calculate colors of labels and sectors used in a chart |
+| Property | Type | Description |
+| ----------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------ |
+| backgroundGradientFrom | string | Defines the first color in the linear gradient of a chart's background |
+| backgroundGradientFromOpacity | Number | Defines the first color opacity in the linear gradient of a chart's background |
+| backgroundGradientTo | string | Defines the second color in the linear gradient of a chart's background |
+| backgroundGradientToOpacity | Number | Defines the second color opacity in the linear gradient of a chart's background |
+| fillShadowGradient | string | Defines the color of the area under data |
+| fillShadowGradientOpacity | Number | Defines the initial opacity of the area under data |
+| useShadowColorFromDataset | Boolean | Defines the option to use color from dataset to each chart data. Default is false |
+| color | function => string | Defines the base color function that is used to calculate colors of labels and sectors used in a chart |
+| strokeWidth | Number | Defines the base stroke width in a chart |
+| barPercentage | Number | Defines the percent (0-1) of the available width each bar width in a chart |
+| barRadius | Number | Defines the radius of each bar |
+| propsForBackgroundLines | props | Override styles of the background lines, refer to react-native-svg's Line documentation |
+| propsForLabels | props | Override styles of the labels, refer to react-native-svg's Text documentation |
+| gutterTop | number | Define the gap between highest coordinate and padding |
+| horizontalLabelWidth | number | Define the width of horizontal labels |
+| verticalLabelHeight | number | Define the height of vertical labels |
## Responsive charts
+
To render a responsive chart, use `Dimensions` react-native library to get the width of the screen of your device like such
+
```js
-import { Dimensions } from 'react-native'
-const screenWidth = Dimensions.get('window').width
+import { Dimensions } from "react-native";
+const screenWidth = Dimensions.get("window").width;
```
## Line Chart
@@ -86,14 +137,19 @@ const screenWidth = Dimensions.get('window').width
```js
const data = {
- labels: ['January', 'February', 'March', 'April', 'May', 'June'],
- datasets: [{
- data: [ 20, 45, 28, 80, 99, 43 ]
- }]
-}
+ labels: ["January", "February", "March", "April", "May", "June"],
+ datasets: [
+ {
+ data: [20, 45, 28, 80, 99, 43],
+ color: (opacity = 1) => `rgba(134, 65, 244, ${opacity})`, // optional
+ strokeWidth: 2 // optional
+ }
+ ],
+ legend: ["Rainy Days", "Sunny Days", "Snowy Days"] // optional
+};
```
-```html
+```jsx
```
-| Property | Type | Description |
-| ------------- |-------------| -----|
-| data | Object | Data for the chart - see example above |
-| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
-| height | Number | Height of the chart |
-| chartConfig | Object | Configuration object for the chart, see example config object above |
+| Property | Type | Description |
+| ----------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| data | Object | Data for the chart - see example above |
+| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
+| height | Number | Height of the chart |
+| withDots | boolean | Show dots on the line - default: True |
+| withShadow | boolean | Show shadow for line - default: True |
+| withInnerLines | boolean | Show inner dashed lines - default: True |
+| withOuterLines | boolean | Show outer dashed lines - default: True |
+| withVerticalLabels | boolean | Show vertical labels - default: True |
+| withHorizontalLabels | boolean | Show horizontal labels - default: True |
+| fromZero | boolean | Render charts from 0 not from the minimum value. - default: False |
+| yAxisLabel | string | Prepend text to horizontal labels -- default: '' |
+| yAxisSuffix | string | Append text to horizontal labels -- default: '' |
+| xAxisLabel | string | Prepend text to vertical labels -- default: '' |
+| yAxisInterval | string | Display y axis line every {x} input. -- default: 1 |
+| chartConfig | Object | Configuration object for the chart, see example config object above |
+| decorator | Function | This function takes a [whole bunch](https://github.com/indiespirit/react-native-chart-kit/blob/master/src/line-chart/line-chart.js#L292) of stuff and can render extra elements, such as data point info or additional markup. |
+| onDataPointClick | Function | Callback that takes `{value, dataset, getColor}` |
+| horizontalLabelRotation | number (degree) | Rotation angle of the horizontal labels - default 0 |
+| verticalLabelRotation | number (degree) | Rotation angle of the vertical labels - default 0 |
+| getDotColor | function => string | Defines the dot color function that is used to calculate colors of dots in a line chart and takes `(dataPoint, dataPointIndex)` |
+| renderDotContent | Function | Render additional content for the dot. Takes `({x, y, index})` as arguments. |
+| yLabelsOffset | number | Offset for Y axis labels |
+| xLabelsOffset | number | Offset for X axis labels |
+| hidePointsAtIndex | number[] | Indices of the data points you don't want to display |
+| formatYLabel | Function | This function change the format of the display value of the Y label. Takes the Y value as argument and should return the desirable string. |
+| formatXLabel | Function | This function change the format of the display value of the X label. Takes the X value as argument and should return the desirable string. |
+| getDotProps | (value, index) => props | This is an alternative to chartConfig's propsForDots |
+| segments | number | The amount of horizontal lines - default 4 |
## Bezier Line Chart

-```html
+```jsx
```
-| Property | Type | Description |
-| ------------- |-------------| -----|
-| bezier | boolean | Add this prop to make the line chart smooth and curvy |
+| Property | Type | Description |
+| -------- | ------- | ----------------------------------------------------- |
+| bezier | boolean | Add this prop to make the line chart smooth and curvy |
## Progress Ring
@@ -133,23 +214,33 @@ const data = {
```js
// each value represents a goal ring in Progress chart
-const data = [0.4, 0.6, 0.8]
+const data = {
+ labels: ["Swim", "Bike", "Run"], // optional
+ data: [0.4, 0.6, 0.8]
+};
```
-```html
+```jsx
```
-| Property | Type | Description |
-| ------------- |-------------| -----|
-| data | Object | Data for the chart - see example above |
-| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
-| height | Number | Height of the chart |
-| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
+
+| Property | Type | Description |
+| ----------- | ------- | ------------------------------------------------------------------------------------------- |
+| data | Object | Data for the chart - see example above |
+| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
+| height | Number | Height of the chart |
+| strokeWidth | Number | Width of the stroke of the chart - default: 16 |
+| radius | Number | Inner radius of the chart - default: 32 |
+| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
+| hideLegend | Boolean | Switch to hide chart legend (defaults to false) |
## Bar chart
@@ -157,14 +248,62 @@ const data = [0.4, 0.6, 0.8]
```js
const data = {
- labels: ['January', 'February', 'March', 'April', 'May', 'June'],
- datasets: [{
- data: [ 20, 45, 28, 80, 99, 43 ]
- }]
-}
+ labels: ["January", "February", "March", "April", "May", "June"],
+ datasets: [
+ {
+ data: [20, 45, 28, 80, 99, 43]
+ }
+ ]
+};
```
-```html
+
+```jsx
+```
+
+| Property | Type | Description |
+| ----------------------- | --------------- | ------------------------------------------------------------------------------------------- |
+| data | Object | Data for the chart - see example above |
+| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
+| height | Number | Height of the chart |
+| withVerticalLabels | boolean | Show vertical labels - default: True |
+| withHorizontalLabels | boolean | Show horizontal labels - default: True |
+| fromZero | boolean | Render charts from 0 not from the minimum value. - default: False |
+| withInnerLines | boolean | Show inner dashed lines - default: True |
+| yAxisLabel | string | Prepend text to horizontal labels -- default: '' |
+| yAxisSuffix | string | Append text to horizontal labels -- default: '' |
+| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
+| horizontalLabelRotation | number (degree) | Rotation angle of the horizontal labels - default 0 |
+| verticalLabelRotation | number (degree) | Rotation angle of the vertical labels - default 0 |
+| showBarTops | boolean | Show bar tops |
+| showValuesOnTopOfBars | boolean | Show value above bars |
+
+## StackedBar chart
+
+
+
+```js
+const data = {
+ labels: ["Test1", "Test2"],
+ legend: ["L1", "L2", "L3"],
+ data: [
+ [60, 60, 60],
+ [30, 30, 60]
+ ],
+ barColors: ["#dfe4ea", "#ced6e0", "#a4b0be"]
+};
+```
+
+```jsx
+
```
-| Property | Type | Description |
-| ------------- |-------------| -----|
-| data | Object | Data for the chart - see example above |
-| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
-| height | Number | Height of the chart |
-| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
+| Property | Type | Description |
+| -------------------- | ------- | ------------------------------------------------------------------------------------------- |
+| data | Object | Data for the chart - see example above |
+| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
+| height | Number | Height of the chart |
+| withVerticalLabels | boolean | Show vertical labels - default: True |
+| withHorizontalLabels | boolean | Show horizontal labels - default: True |
+| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
+| barPercentage | Number | Defines the percent (0-1) of the available width each bar width in a chart |
+| showLegend | boolean | Show legend - default: True |
## Pie chart

+### Modified Pie Chart Screenshot
+
+
+
```js
const data = [
- { name: 'Toronto', population: 2800000 },
- { name: 'Dublin', population: 527612 },
- { name: 'New York', population: 8538000 },
- { name: 'Beijing', population: 21500000 },
- { name: 'Moscow', population: 11920000 }
-]
+ {
+ name: "Seoul",
+ population: 21500000,
+ color: "rgba(131, 167, 234, 1)",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ },
+ {
+ name: "Toronto",
+ population: 2800000,
+ color: "#F00",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ },
+ {
+ name: "Beijing",
+ population: 527612,
+ color: "red",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ },
+ {
+ name: "New York",
+ population: 8538000,
+ color: "#ffffff",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ },
+ {
+ name: "Moscow",
+ population: 11920000,
+ color: "rgb(0, 0, 255)",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ }
+];
```
-```html
+
+```jsx
```
-| Property | Type | Description |
-| ------------- |-------------| -----|
-| data | Object | Data for the chart - see example above |
-| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
-| height | Number | Height of the chart |
-| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
-| accessor | string | Property in the `data` object from which the number values are taken |
+| Property | Type | Description |
+| ----------- | ------- | ------------------------------------------------------------------------------------------- |
+| data | Object | Data for the chart - see example above |
+| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
+| height | Number | Height of the chart |
+| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
+| accessor | string | Property in the `data` object from which the number values are taken |
+| bgColor | string | background color - if you want to set transparent, input `transparent` or `none`. |
+| paddingLeft | string | left padding of the pie chart |
+| absolute | boolean | shows the values as absolute numbers |
+| hasLegend | boolean | Defaults to `true`, set it to `false` to remove the legend |
## Contribution graph (heatmap)
@@ -219,40 +404,57 @@ This type of graph is often use to display a developer contribution activity. Ho
```js
const commitsData = [
- { date: '2017-01-02', count: 1 },
- { date: '2017-01-03', count: 2 },
- { date: '2017-01-04', count: 3 },
- { date: '2017-01-05', count: 4 },
- { date: '2017-01-06', count: 5 },
- { date: '2017-01-30', count: 2 },
- { date: '2017-01-31', count: 3 },
- { date: '2017-03-01', count: 2 },
- { date: '2017-04-02', count: 4 },
- { date: '2017-03-05', count: 2 },
- { date: '2017-02-30', count: 4 }
-]
+ { date: "2017-01-02", count: 1 },
+ { date: "2017-01-03", count: 2 },
+ { date: "2017-01-04", count: 3 },
+ { date: "2017-01-05", count: 4 },
+ { date: "2017-01-06", count: 5 },
+ { date: "2017-01-30", count: 2 },
+ { date: "2017-01-31", count: 3 },
+ { date: "2017-03-01", count: 2 },
+ { date: "2017-04-02", count: 4 },
+ { date: "2017-03-05", count: 2 },
+ { date: "2017-02-30", count: 4 }
+];
```
-```html
+```jsx
```
+Extra chartStyle for heatmap
+```js
+const chartConfig = {
+ chartStyle: {
+ justifyContent: 'start' || 'center' || 'end', //optional, defualt is 'start';
+ alignItems: 'start' || 'center' || 'end', //optional, default is 'start';
+ },
+};
+```
-| Property | Type | Description |
-| ------------- |-------------| -----|
-| data | Object | Data for the chart - see example above |
-| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
-| height | Number | Height of the chart |
-| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
-| accessor | string | Property in the `data` object from which the number values are taken |
+| Property | Type | Description |
+| ------------------ | -------- | ------------------------------------------------------------------------------------------- |
+| data | Object | Data for the chart - see example above |
+| width | Number | Width of the chart, use 'Dimensions' library to get the width of your screen for responsive |
+| height | Number | Height of the chart |
+| gutterSize | Number | Size of the gutters between the squares in the chart |
+| squareSize | Number | Optional, Size of the squares in the chart, dynamic size will be auto applied if prop is not provided |
+| horizontal | boolean | Should graph be laid out horizontally? Defaults to `true` |
+| showMonthLabels | boolean | Should graph include labels for the months? Defaults to `true` |
+| showOutOfRangeDays | boolean | Should graph be filled with squares, including days outside the range? Defaults to `false` |
+| chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file |
+| accessor | string | Property in the `data` object from which the number values are taken; defaults to `count` |
+| getMonthLabel | function | Function which returns the label for each month, taking month index (0 - 11) as argument |
+| onDayPress | function | Callback invoked when the user clicks a day square on the chart; takes a value-item object |
## More styling
+
Every charts also accepts `style` props, which will be applied to parent `svg` or `View` component of each chart.
## Abstract Chart
@@ -262,7 +464,9 @@ Every charts also accepts `style` props, which will be applied to parent `svg` o
The following methods are available:
### renderHorizontalLines(config)
+
Renders background horizontal lines like in the Line Chart and Bar Chart. Takes a config object with following properties:
+
```js
{
// width of your chart
@@ -271,15 +475,15 @@ Renders background horizontal lines like in the Line Chart and Bar Chart. Takes
height: Number,
// how many lines to render
count: Number,
- // how many labels there will be on X axes - used to calculate offsets between the lines
- labelCount: Number,
// top padding from the chart top edge
paddingTop: Number
}
```
### renderVerticalLabels(config)
+
Render background vertical lines. Takes a config object with following properties:
+
```js
{
// data needed to calculate the number of lines to render
@@ -294,7 +498,9 @@ Render background vertical lines. Takes a config object with following propertie
```
### renderDefs(config)
+
Render definitions of background and shadow gradients
+
```js
{
// width of your chart
@@ -303,13 +509,23 @@ Render definitions of background and shadow gradients
height: Number,
// first color of background gradient
backgroundGradientFrom: String,
+ // first color opacity of background gradient (0 - 1.0)
+ backgroundGradientFromOpacity: Number,
// second color of background gradient
- backgroundGradientTo: String
+ backgroundGradientTo: String,
+ // second color opacity of background gradient (0 - 1.0)
+ backgroundGradientToOpacity: Number,
}
```
## More information
+
This library is built on top of the following open-source projects:
-* react-native-svg (https://github.com/react-native-community/react-native-svg)
-* paths-js (https://github.com/andreaferretti/paths-js)
-* react-native-calendar-heatmap (https://github.com/ayooby/react-native-calendar-heatmap)
+
+- react-native-svg (https://github.com/react-native-community/react-native-svg)
+- paths-js (https://github.com/andreaferretti/paths-js)
+- react-native-calendar-heatmap (https://github.com/ayooby/react-native-calendar-heatmap)
+
+## Contribute
+
+See the [contribution guide](contributing.md) and join [the contributors](https://github.com/indiespirit/react-native-chart-kit/graphs/contributors)!
diff --git a/app.json b/app.json
index 967d41c5..306ca483 100644
--- a/app.json
+++ b/app.json
@@ -1,5 +1,3 @@
{
- "expo": {
- "sdkVersion": "23.0.0"
- }
+ "expo": {}
}
diff --git a/contributing.md b/contributing.md
new file mode 100644
index 00000000..96c7f95d
--- /dev/null
+++ b/contributing.md
@@ -0,0 +1,26 @@
+# Contributing to React Native Chart Kit
+
+👍🎉 First off, thanks for taking the time to contribute! 🎉👍
+
+Suggestions and pull requests are highly encouraged! Have a look at the [open issues](https://github.com/indiespirit/react-native-chart-kit/issues).
+
+## Workflow
+
+First clone:
+
+```sh
+git clone git@github.com:indiespirit/react-native-chart-kit.git
+cd react-native-chart-kit
+yarn install
+```
+
+In order to run it, you are gonna have to flip values for "main" and "_main" in package json. This is nessesary because both npm and expo have a notion of a main file, but for npm it's the file that you run when you import this library in your app; and for expo it's the file that it uses to display the example app.
+
+Don't forget to flip it back before commiting.
+
+**After you update fix the package.json**
+
+```sh
+yarn start # And get you expo app ready on your phone
+```
+
diff --git a/data.js b/data.js
index a3dae7a1..d9f8c9b9 100644
--- a/data.js
+++ b/data.js
@@ -1,47 +1,97 @@
// Mock data object used for LineChart and BarChart
const data = {
- labels: ['January', 'February', 'March', 'April', 'May', 'June'],
- datasets: [{
- data: [
- Math.random() * 100,
- Math.random() * 100,
- Math.random() * 100,
- Math.random() * 100,
- Math.random() * 100,
- Math.random() * 100
- ]
- }]
-}
+ labels: ["January", "February", "March", "April", "May", "June"],
+ datasets: [
+ {
+ data: [-50, -20, -2, 86, 71, 100],
+ color: (opacity = 1) => `rgba(134, 65, 244, ${opacity})` // optional
+ },
+ {
+ data: [20, 10, 4, 56, 87, 90],
+ color: (opacity = 1) => `rgba(0, 255, 255, ${opacity})` // optional
+ },
+ {
+ data: [30, 90, 67, 54, 10, 2]
+ }
+ ],
+ legend: ["Rainy Days", "Sunny Days", "Snowy Days"] // optional
+};
// Mock data object used for Contribution Graph
const contributionData = [
- { date: '2016-01-02', count: 1 },
- { date: '2016-01-03', count: 2 },
- { date: '2016-01-04', count: 3 },
- { date: '2016-01-05', count: 4 },
- { date: '2016-01-06', count: 5 },
- { date: '2016-01-30', count: 2 },
- { date: '2016-01-31', count: 3 },
- { date: '2016-03-01', count: 2 },
- { date: '2016-04-02', count: 4 },
- { date: '2016-03-05', count: 2 },
- { date: '2016-02-30', count: 4 }
-]
+ { date: "2016-01-02", count: 1 },
+ { date: "2016-01-03", count: 2 },
+ { date: "2016-01-04", count: 3 },
+ { date: "2016-01-05", count: 4 },
+ { date: "2016-01-06", count: 5 },
+ { date: "2016-01-30", count: 2 },
+ { date: "2016-01-31", count: 3 },
+ { date: "2016-03-01", count: 2 },
+ { date: "2016-04-02", count: 4 },
+ { date: "2016-03-05", count: 2 },
+ { date: "2016-02-30", count: 4 }
+];
// Mock data object for Pie Chart
const pieChartData = [
- { name: 'Italy', population: Math.random() * 10000 },
- { name: 'Mexico', population: Math.random() * 10000 },
- { name: 'France', population: Math.random() * 10000 },
- { name: 'Argentina', population: Math.random() * 10000 },
- { name: 'Japan', population: Math.random() * 10000 }
-]
+ {
+ name: "Seoul",
+ population: 21500000,
+ color: "rgba(131, 167, 234, 1)",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ },
+ {
+ name: "Toronto",
+ population: 2800000,
+ color: "#F00",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ },
+ {
+ name: "Beijing",
+ population: 527612,
+ color: "red",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ },
+ {
+ name: "New York",
+ population: 8538000,
+ color: "#ffffff",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ },
+ {
+ name: "Moscow",
+ population: 11920000,
+ color: "rgb(0, 0, 255)",
+ legendFontColor: "#7F7F7F",
+ legendFontSize: 15
+ }
+];
// Mock data object for Progress
-const progressChartData = [0.4, 0.6, 0.8]
+const progressChartData = {
+ labels: ["Swim", "Bike", "Run"], // optional
+ data: [0.2, 0.5, 0.3]
+};
-export { data, contributionData, pieChartData, progressChartData }
+const stackedBarGraphData = {
+ labels: ["Test1", "Test2"],
+ legend: ["L1", "L2", "L3"],
+ data: [[60, 60, 60], [30, 30, 60]],
+ barColors: ["#dfe4ea", "#ced6e0", "#a4b0be"]
+};
+
+export {
+ data,
+ contributionData,
+ pieChartData,
+ progressChartData,
+ stackedBarGraphData
+};
diff --git a/index.d.ts b/index.d.ts
new file mode 100644
index 00000000..f0701a74
--- /dev/null
+++ b/index.d.ts
@@ -0,0 +1,445 @@
+// Type definitions for ReactNativeChartKit 2.6
+// Project: https://github.com/indiespirit/react-native-chart-kit
+// TypeScript Version: 3.0
+
+import * as React from "react";
+import { ViewStyle } from "react-native";
+import { TextProps, CircleProps, TextStyle } from "react-native-svg";
+
+export interface Dataset {
+ /** The data corresponding to the x-axis label. */
+ data: number[];
+ /** A function returning the color of the stroke given an input opacity value. */
+ color?: (opacity: number) => string;
+ /** The width of the stroke. Defaults to 2. */
+ strokeWidth?: number;
+
+ /** A boolean indicating whether to render dots for this line */
+ withDots?: boolean;
+}
+
+export interface ChartData {
+ /** The x-axis labels */
+ labels: string[];
+ datasets: Dataset[];
+}
+
+export interface LineChartData extends ChartData {
+ legend?: string[];
+}
+
+// LineChart
+export interface LineChartProps {
+ /**
+ * Data for the chart.
+ *
+ * Example from [docs](https://github.com/indiespirit/react-native-chart-kit#line-chart):
+ *
+ * ```javascript
+ * const data = {
+ * labels: ['January', 'February', 'March', 'April', 'May', 'June'],
+ * datasets: [{
+ * data: [ 20, 45, 28, 80, 99, 43 ],
+ * color: (opacity = 1) => `rgba(134, 65, 244, ${opacity})`, // optional
+ * strokeWidth: 2 // optional
+ * }],
+ * legend: ["Rainy Days", "Sunny Days", "Snowy Days"] // optional
+ * }
+ * ```
+ */
+ data: LineChartData;
+ /**
+ * Width of the chart, use 'Dimensions' library to get the width of your screen for responsive.
+ */
+ width: number;
+ /**
+ * Height of the chart.
+ */
+ height: number;
+ /**
+ * Show dots on the line - default: True.
+ */
+ withDots?: boolean;
+ /**
+ * Show shadow for line - default: True.
+ */
+ withShadow?: boolean;
+ /**
+ * Show inner dashed lines - default: True.
+ */
+
+ defMax?: number;
+ defMin?: number;
+ withScrollableDot?: boolean;
+ withInnerLines?: boolean;
+ /**
+ * Show outer dashed lines - default: True.
+ */
+ withOuterLines?: boolean;
+ /**
+ * Show vertical labels - default: True.
+ */
+ withVerticalLabels?: boolean;
+ /**
+ * Show horizontal labels - default: True.
+ */
+ withHorizontalLabels?: boolean;
+ /**
+ * Render charts from 0 not from the minimum value. - default: False.
+ */
+ fromZero?: boolean;
+ /**
+ * Prepend text to horizontal labels -- default: ''.
+ */
+ yAxisLabel?: string;
+ /**
+ * Append text to horizontal labels -- default: ''.
+ */
+ yAxisSuffix?: string;
+ /**
+ * Prepend text to vertical labels -- default: ''.
+ */
+ xAxisLabel?: string;
+ /**
+ * Configuration object for the chart, see example:
+ *
+ * ```javascript
+ * const chartConfig = {
+ * backgroundGradientFrom: "#1E2923",
+ * backgroundGradientFromOpacity: 0,
+ * backgroundGradientTo: "#08130D",
+ * backgroundGradientToOpacity: 0.5,
+ * color: (opacity = 1) => `rgba(26, 255, 146, ${opacity})`,
+ * labelColor: (opacity = 1) => `rgba(26, 255, 146, ${opacity})`,
+ * strokeWidth: 2, // optional, default 3
+ * barPercentage: 0.5
+ * };
+ * ```
+ */
+ chartConfig: ChartConfig;
+
+ /**
+ * Divide axis quantity by the input number -- default: 1.
+ */
+ yAxisInterval?: number;
+
+ /**
+ * Defines if chart is transparent
+ */
+ transparent?: boolean;
+ /**
+ * This function takes a [whole bunch](https://github.com/indiespirit/react-native-chart-kit/blob/master/src/line-chart.js#L266)
+ * of stuff and can render extra elements,
+ * such as data point info or additional markup.
+ */
+ decorator?: Function;
+ /**
+ * Callback that is called when a data point is clicked.
+ */
+ onDataPointClick?: (data: {
+ index: number;
+ value: number;
+ dataset: Dataset;
+ x: number;
+ y: number;
+ getColor: (opacity: number) => string;
+ }) => void;
+ /**
+ * Style of the container view of the chart.
+ */
+ style?: ViewStyle;
+ /**
+ * Add this prop to make the line chart smooth and curvy.
+ *
+ * [Example](https://github.com/indiespirit/react-native-chart-kit#bezier-line-chart)
+ */
+ bezier?: boolean;
+ /**
+ * Defines the dot color function that is used to calculate colors of dots in a line chart.
+ * Takes `(dataPoint, dataPointIndex)` as arguments.
+ */
+ getDotColor?: (dataPoint: any, index: number) => string;
+ /**
+ * Renders additional content for dots in a line chart.
+ * Takes `({x, y, index})` as arguments.
+ */
+ renderDotContent?: (params: {
+ x: number;
+ y: number;
+ index: number;
+ }) => React.ReactNode;
+ /**
+ * Rotation angle of the horizontal labels - default 0 (degrees).
+ */
+ horizontalLabelRotation?: number;
+ /**
+ * Rotation angle of the vertical labels - default 0 (degrees).
+ */
+ verticalLabelRotation?: number;
+ /**
+ * Offset for Y axis labels.
+ */
+ yLabelsOffset?: number;
+ /**
+ * Offset for X axis labels.
+ */
+ xLabelsOffset?: number;
+ /**
+ * Array of indices of the data points you don't want to display.
+ */
+ hidePointsAtIndex?: number[];
+ /**
+ * This function change the format of the display value of the Y label.
+ * Takes the y value as argument and should return the desirable string.
+ */
+ formatYLabel?: (yValue: string) => string;
+ /**
+ * This function change the format of the display value of the X label.
+ * Takes the X value as argument and should return the desirable string.
+ */
+ formatXLabel?: (xValue: string) => string;
+ /**
+ * Provide props for a data point dot.
+ */
+ getDotProps?: (dataPoint: any, index: number) => object;
+ /**
+ * The number of horizontal lines
+ */
+ segments?: number;
+}
+
+export class LineChart extends React.Component {}
+
+// ProgressChart
+
+export type ProgressChartData =
+ | Array
+ | { labels?: Array; data: Array };
+export interface ProgressChartProps {
+ data: ProgressChartData;
+ width: number;
+ height: number;
+ chartConfig?: ChartConfig;
+ hideLegend?: boolean;
+ strokeWidth?: number;
+ radius?: number;
+}
+
+export class ProgressChart extends React.Component {}
+
+// BarChart
+export interface BarChartProps {
+ data: ChartData;
+ width: number;
+ height: number;
+ defMax?: number;
+ defMin?: number;
+ withInnerLines?: boolean;
+ yAxisLabel: string;
+ yAxisSuffix: string;
+ chartConfig: ChartConfig;
+ style?: ViewStyle;
+ horizontalLabelRotation?: number;
+ verticalLabelRotation?: number;
+ hideLabelsAtIndex?: (number | null)[];
+ barWidth?: number;
+ decorator?: ({}:any) => JSX.Element;
+ /**
+ * The number of horizontal lines
+ */
+ segments?: number;
+ showBarTops?: boolean;
+ showValuesOnTopOfBars?: boolean;
+ withHorizontalLabels?: boolean;
+ withVerticalLabels?: boolean;
+}
+
+export class BarChart extends React.Component {}
+
+// StackedBarChart
+export interface StackedBarChartData {
+ labels: string[];
+ legend: string[];
+ data: number[][];
+ barColors: string[];
+}
+
+export interface Size {
+ width: number;
+ height: number;
+}
+
+export interface StackedBarChartProps {
+ /**
+ * E.g.
+ * ```javascript
+ * const data = {
+ * labels: ["Test1", "Test2"],
+ * legend: ["L1", "L2", "L3"],
+ * data: [[60, 60, 60], [30, 30, 60]],
+ * barColors: ["#dfe4ea", "#ced6e0", "#a4b0be"]
+ * };
+ * ```
+ */
+ data: StackedBarChartData;
+ width: number;
+ height: number;
+ chartConfig: ChartConfig;
+ style?: ViewStyle;
+ barPercentage?: number;
+ hideLegend: boolean;
+ /**
+ * The number of horizontal lines
+ */
+ segments?: number;
+}
+
+export class StackedBarChart extends React.Component {}
+
+// PieChart
+export interface PieChartProps {
+ data: Array;
+ width: number;
+ height: number;
+ chartConfig: ChartConfig;
+ accessor: string;
+ backgroundColor: string;
+ paddingLeft: string;
+ center?: Array;
+ absolute?: boolean;
+ hasLegend?: boolean;
+}
+
+export class PieChart extends React.Component {}
+
+// ContributionGraph
+export interface ContributionGraphProps {
+ style?: ViewStyle;
+ values: Array;
+ endDate: Date;
+ numDays: number;
+ width: number;
+ height: number;
+ gutterSize?: number;
+ squareSize?: number;
+ horizontal?: boolean;
+ showMonthLabels?: boolean;
+ showOutOfRangeDays?: boolean;
+ chartConfig: ChartConfig;
+ accessor?: string;
+ getMonthLabel?: (monthIndex: number) => string;
+ onDayPress?: ({ count: number, date: Date }) => void;
+ toggleTooltip?: boolean;
+ tooltipContent?: (dateInfo: { date: string, [accessor: string]: string},
+ args: {x:number, y:number, index:number}) => JSX.Element;
+}
+
+export class ContributionGraph extends React.Component<
+ ContributionGraphProps
+> {}
+
+// AbstractChart
+export class AbstractChart extends React.Component {}
+
+// ChartConfig
+export interface ChartConfig {
+ backgroundColor?: string;
+ /**
+ * Defines the first color in the linear gradient of a chart's background
+ */
+ backgroundGradientFrom?: string;
+ /**
+ * Defines the first color opacity in the linear gradient of a chart's background
+ */
+ backgroundGradientFromOpacity?: number;
+ /**
+ * Defines the second color in the linear gradient of a chart's background
+ */
+ backgroundGradientTo?: string;
+ /**
+ * Defines the second color opacity in the linear gradient of a chart's background
+ */
+ backgroundGradientToOpacity?: number;
+ fillShadowGradient?: string;
+ fillShadowGradientOpacity?: number;
+ /**
+ * Defines the option to use color from dataset to each chart data
+ */
+ useShadowColorFromDataset?: boolean;
+ /**
+ * Defines the base color function that is used to calculate colors of labels and sectors used in a chart
+ */
+ color?: (opacity: number, index?: number) => string;
+ /**
+ * Defines the function that is used to calculate the color of the labels used in a chart.
+ */
+ labelColor?: (opacity: number) => string;
+ /**
+ * Defines the base stroke width in a chart
+ */
+ strokeWidth?: number;
+ /**
+ * Defines the percent (0-1) of the available width each bar width in a chart
+ */
+ barPercentage?: number;
+ barRadius?: number;
+ /**
+ * Override styles of the background lines, refer to react-native-svg's Line documentation
+ */
+ propsForBackgroundLines?: object;
+ /**
+ * Override styles of the labels, refer to react-native-svg's Text documentation
+ */
+ propsForLabels?: TextProps;
+ /**
+ * Override styles of the dots, refer to react-native-svg's Text documentation
+ */
+ propsForDots?: CircleProps;
+ decimalPlaces?: number;
+ style?: ViewStyle;
+
+ /**
+ * Define stroke line join type
+ */
+ linejoinType?: "round" | "butt" | "square";
+
+ /**
+ * Define fill color for scrollable dot
+ */
+ scrollableDotFill?: string;
+
+ /**
+ * Define stroke color for scrollable dot
+ */
+ scrollableDotStrokeColor?: string;
+
+ /**
+ * Define stroke width for scrollable dot
+ */
+ scrollableDotStrokeWidth?: number;
+
+ /**
+ * Define radius for scrollable dot
+ */
+ scrollableDotRadius?: number;
+
+ /**
+ * Override style for additional info view upper scrollable dot
+ */
+ scrollableInfoViewStyle?: ViewStyle;
+
+ /**
+ * Override text style for additional info view upper scrollable dot
+ */
+ scrollableInfoTextStyle?: TextStyle;
+
+ /**
+ * Set Info View offset
+ */
+ scrollableInfoOffset?: number;
+
+ /**
+ * Set Info View size
+ */
+ scrollableInfoSize?: Size;
+}
diff --git a/index.js b/index.js
index 60c1647d..038a99ce 100644
--- a/index.js
+++ b/index.js
@@ -1,9 +1,10 @@
-import AbstractChart from './src/abstract-chart'
-import LineChart from './src/line-chart'
-import BarChart from './src/bar-chart'
-import PieChart from './src/pie-chart'
-import ProgressChart from './src/progress-chart'
-import ContributionGraph from './src/contribution-graph'
+import AbstractChart from "./src/abstract-chart";
+import LineChart from "./src/line-chart";
+import BarChart from "./src/bar-chart";
+import PieChart from "./src/pie-chart";
+import ProgressChart from "./src/progress-chart";
+import ContributionGraph from "./src/contribution-graph";
+import StackedBarChart from "./src/stackedbar-chart";
export {
AbstractChart,
@@ -11,5 +12,6 @@ export {
LineChart,
PieChart,
ProgressChart,
- ContributionGraph
-}
+ ContributionGraph,
+ StackedBarChart
+};
diff --git a/package.json b/package.json
index a568ff74..f9fd739c 100644
--- a/package.json
+++ b/package.json
@@ -1,62 +1,54 @@
{
"name": "react-native-chart-kit",
- "version": "0.1.3",
+ "version": "5.6.1",
"devDependencies": {
- "babel-eslint": "^8.0.2",
- "eslint-config-xo-react": "^0.15.0",
- "eslint-plugin-react": "^7.4.0",
- "jest-expo": "23.0.0",
- "react-native-scripts": "1.8.1",
- "react-test-renderer": "16.0.0",
- "xo": "^0.18.2"
+ "babel-eslint": "10.x",
+ "babel-plugin-module-resolver": "^3.1.1",
+ "babel-polyfill": "^6.26.0",
+ "eslint": "6.x",
+ "eslint-config-react-app": "^5.0.2",
+ "eslint-plugin-flowtype": "^4.3.0",
+ "eslint-plugin-import": "2.x",
+ "eslint-plugin-jsx-a11y": "6.x",
+ "eslint-plugin-react": "7.x",
+ "eslint-plugin-react-hooks": "1.x",
+ "expo": "^37.0.0",
+ "husky": "^3.0.7",
+ "jest-expo": "^37.0.0",
+ "prettier": "^1.18.2",
+ "pretty-quick": "^1.11.1",
+ "react": "16.9.0",
+ "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
+ "react-native-flash-message": "^0.1.10",
+ "react-native-scrollable-tab-view": "^1.0.0",
+ "react-native-svg": "11.0.1",
+ "react-test-renderer": "16.7.0"
},
- "_main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
+ "_main": "./node_modules/expo/AppEntry.js",
"main": "./index.js",
"scripts": {
- "start": "react-native-scripts start",
- "eject": "react-native-scripts eject",
- "android": "react-native-scripts android",
- "ios": "react-native-scripts ios",
- "test": "node node_modules/jest/bin/jest.js --watch"
+ "start": "expo start",
+ "eject": "expo eject",
+ "android": "expo start --android",
+ "ios": "expo start --ios",
+ "test": "jest"
},
"jest": {
"preset": "jest-expo"
},
+ "peerDependencies": {
+ "react": "> 16.7.0",
+ "react-native": ">= 0.50.0",
+ "react-native-svg": "> 6.4.1"
+ },
"dependencies": {
- "babel-polyfill": "^6.26.0",
- "expo": "^23.0.4",
- "google-palette": "^1.0.0",
- "lodash": "^4.17.4",
- "paths-js": "^0.4.5",
- "point-in-polygon": "^1.0.1",
- "prop-types": "^15.6.0",
- "react": "16.0.0",
- "react-native": "0.50.3",
- "react-native-scrollable-tab-view": "^0.8.0",
- "react-native-svg": "5.5.1"
+ "lodash": "^4.17.13",
+ "paths-js": "^0.4.10",
+ "point-in-polygon": "^1.0.1"
},
- "xo": {
- "extends": "xo-react",
- "parser": "babel-eslint",
- "space": true,
- "semicolon": false,
- "rules": {
- "camelcase": "off",
- "capitalized-comments": "off",
- "new-cap": "off",
- "object-curly-spacing": [
- "error",
- "always"
- ],
- "import/no-unassigned-import": 0,
- "react/forbid-component-props": "off",
- "react/prop-types": [
- 0
- ]
- },
- "envs": [
- "node",
- "browser"
- ]
+ "husky": {
+ "hooks": {
+ "pre-commit": "pretty-quick --staged"
+ }
}
}
diff --git a/src/abstract-chart.js b/src/abstract-chart.js
index 508abd0c..c24e3e93 100644
--- a/src/abstract-chart.js
+++ b/src/abstract-chart.js
@@ -1,101 +1,322 @@
-import React, { Component } from 'react'
+import React, { Component } from "react";
-import {
- LinearGradient,
- Line,
- Text,
- Defs,
- Stop
-} from 'react-native-svg'
+import { LinearGradient, Line, Text, Defs, Stop } from "react-native-svg";
class AbstractChart extends Component {
+ calcScaler = data => {
+ const defMin = this.props.defMin ?? Math.min(...data);
+ const defMax = this.props.defMax ?? Math.max(...data);
+ return Math.max(...data, defMin, defMax) - Math.min(...data, defMin, defMax) || 1;
+ };
+
+ calcBaseHeight = (data, height) => {
+ const defMin = this.props.defMin ?? Math.min(...data);
+ const defMax = this.props.defMax ?? Math.max(...data);
+ const min = Math.min(...data, defMin, defMax);
+ const max = Math.max(...data, defMin, defMax);
+ if (min >= 0 && max >= 0) {
+ return height;
+ } else if (min < 0 && max <= 0) {
+ return 0;
+ } else if (min < 0 && max > 0) {
+ return (height * max) / this.calcScaler(data);
+ }
+ };
+
+ calcHeight = (val, data, height) => {
+ const defMin = this.props.defMin ?? Math.min(...data);
+ const defMax = this.props.defMax ?? Math.max(...data);
+ const max = Math.max(...data, defMin, defMax);
+ const min = Math.min(...data, defMin, defMax);
+ if (min < 0 && max > 0) {
+ return height * (val / this.calcScaler(data));
+ } else if (min >= 0 && max >= 0) {
+ return height * ((val - min) / this.calcScaler(data));
+ } else if (min < 0 && max <= 0) {
+ return height * ((val - max) / this.calcScaler(data));
+ }
+ };
+
+ getPropsForBackgroundLines() {
+ const { propsForBackgroundLines = {} } = this.props.chartConfig;
+ return {
+ stroke: this.props.chartConfig.color(0.2),
+ strokeDasharray: "5, 10",
+ strokeWidth: 1,
+ ...propsForBackgroundLines
+ };
+ }
+
+ getPropsForLabels() {
+ const {
+ propsForLabels = {},
+ color,
+ labelColor = color
+ } = this.props.chartConfig;
+ return {
+ fontSize: 12,
+ fill: labelColor(0.8),
+ ...propsForLabels,
+ };
+ }
+
renderHorizontalLines = config => {
- const { count, width, height, labelCount, paddingTop } = config
- return [...Array(count)].map((_, i) => {
+ const { count, width, height, gutterTop, horizontalLabelWidth, verticalLabelHeight,
+ chartStyle: { paddingTop, paddingLeft, paddingRight, paddingBottom },
+ } = config;
+ const basePosition = height - verticalLabelHeight - paddingBottom;
+ const totalLineHeight = basePosition - paddingTop - gutterTop;
+ const x1 = horizontalLabelWidth + paddingLeft;
+ const x2 = width - paddingRight;
+ const lineGap = (count - 1) || 1; //handle divided by zero
+ return [...new Array(count)].map((_, i) => {
+ const y = basePosition - totalLineHeight / lineGap * i
return (
- )
- })
- }
+ );
+ });
+ };
renderHorizontalLabels = config => {
- const { count, data, width, height, labelsCount, paddingTop, yLabelsOffset = 12 } = config
- return [...Array(count)].map((_, i) => {
+ const {
+ count,
+ data,
+ height,
+ gutterTop,
+ horizontalLabelWidth,
+ horizontalLabelRotation = 0,
+ verticalLabelHeight,
+ decimalPlaces = 2,
+ formatYLabel = yLabel => yLabel,
+ chartStyle: { paddingTop, paddingLeft, paddingRight, paddingBottom },
+ } = config;
+
+ const {
+ yAxisLabel = "",
+ yAxisSuffix = "",
+ yLabelsOffset = 12,
+ defMin = Math.min(...data),
+ defMax = Math.max(...data),
+ } = this.props;
+
+ const basePosition = height - verticalLabelHeight - paddingBottom;
+ const totalLineHeight = basePosition - paddingTop - gutterTop;
+ const lineGap = (count - 1) || 1;
+
+ return [...Array(count === 1 ? 1 : count).keys()].map((i, _) => {
+ let yLabel = i * count;
+
+ const label = this.calcScaler(data) / lineGap * i + Math.min(...data, defMin, defMax);
+ yLabel = `${yAxisLabel}${formatYLabel(
+ label.toFixed(decimalPlaces)
+ )}${yAxisSuffix}`;
+
+ const x = horizontalLabelWidth - yLabelsOffset;
+ const y = basePosition - totalLineHeight / lineGap * i;
+
return (
{(((Math.max(...data) - Math.min(...data)) / 4 * i) + Math.min(...data)).toFixed(2)}
+ y={y}
+ {...this.getPropsForLabels()}
+ >
+ {yLabel}
- )
- })
- }
+ );
+ });
+ };
renderVerticalLabels = config => {
- const { labels, width, height, paddingRight, paddingTop, horizontalOffset = 0 } = config
- const fontSize = 12
+ const {
+ labels = [],
+ width,
+ height,
+ horizontalLabelWidth,
+ verticalLabelHeight,
+ gutterTop,
+ horizontalOffset = 0,
+ stackedBar = false,
+ verticalLabelRotation = 0,
+ formatXLabel = xLabel => xLabel,
+ chartStyle: { paddingTop, paddingLeft, paddingRight, paddingBottom },
+ midPoint = 0,
+ } = config;
+
+ const {
+ xAxisLabel = "",
+ xLabelsOffset = 0,
+ hideLabelsAtIndex = []
+ } = this.props;
+ const fontSize = 12;
+ let fac = 1;
+ if (stackedBar) {
+ fac = 0.71;
+ }
+
+ const labelWidth = (width - horizontalLabelWidth - paddingRight - paddingLeft) / labels.length;
+
+ const y = height - paddingBottom - verticalLabelHeight + xLabelsOffset + fontSize*1.5;
+
return labels.map((label, i) => {
+ if (hideLabelsAtIndex.includes(i)) {
+ return null;
+ }
+
+ const x = (paddingLeft + horizontalLabelWidth + labelWidth * i + midPoint + horizontalOffset) * fac;
+
return (
{label}
+ x={x}
+ y={y}
+ textAnchor={verticalLabelRotation === 0 ? "middle" : "start"}
+ {...this.getPropsForLabels()}
+ >
+ {`${formatXLabel(label)}${xAxisLabel}`}
- )
- })
- }
+ );
+ });
+ };
renderVerticalLines = config => {
- const { data, width, height, paddingTop, paddingRight } = config
- return [...Array(data.length)].map((_, i) => {
- return (
-
- )
- })
- }
+ const { data, width, height, gutterTop, horizontalLabelWidth, verticalLabelHeight,
+ chartStyle: { paddingTop, paddingLeft, paddingRight, paddingBottom },
+ } = config;
+ const {
+ yAxisInterval = 1,
+ adjustment = 1,
+ innerLines,
+ } = this.props;
+ const innerWidth = width - horizontalLabelWidth - paddingLeft - paddingRight;
+
+ const lineNum = innerLines || data.length;
+
+ const gap = innerWidth / (lineNum / yAxisInterval);
+
+ return [...new Array(Math.ceil(lineNum / yAxisInterval))].map(
+ (_, i) => {
+ return (
+
+ );
+ }
+ );
+ };
renderDefs = config => {
- const { width, height, backgroundGradientFrom, backgroundGradientTo } = config
+ const {
+ width,
+ height,
+ backgroundGradientFrom,
+ backgroundGradientTo,
+ useShadowColorFromDataset,
+ data
+ } = config;
+
+ const fromOpacity = config.hasOwnProperty("backgroundGradientFromOpacity")
+ ? config.backgroundGradientFromOpacity
+ : 1.0;
+
+ const toOpacity = config.hasOwnProperty("backgroundGradientToOpacity")
+ ? config.backgroundGradientToOpacity
+ : 1.0;
+
+ const fillShadowGradient = config.hasOwnProperty("fillShadowGradient")
+ ? config.fillShadowGradient
+ : this.props.chartConfig.color();
+
+ const fillShadowGradientOpacity = config.hasOwnProperty(
+ "fillShadowGradientOpacity"
+ )
+ ? config.fillShadowGradientOpacity
+ : 0.1;
+
return (
-
-
-
-
-
-
-
+
+
+
+ {
+ useShadowColorFromDataset ? (
+ data.map((dataset, index) => (
+
+
+
+
+ ))
+ ) : (
+
+
+
+
+ )
+ }
- )
- }
+ );
+ };
}
-export default AbstractChart
+export default AbstractChart;
diff --git a/src/bar-chart.js b/src/bar-chart.js
index 3683ab70..68e6cae2 100644
--- a/src/bar-chart.js
+++ b/src/bar-chart.js
@@ -1,103 +1,238 @@
-import React from 'react'
-import { View } from 'react-native'
-import {
- Svg,
- Rect
-} from 'react-native-svg'
-import AbstractChart from './abstract-chart'
+import React from "react";
+import { View } from "react-native";
+import { Svg, Rect, G, Text } from "react-native-svg";
+import AbstractChart from "./abstract-chart";
-const barWidth = 32
+const BAR_RATIO = {
+ gutterTop: 0.1 ,
+ horizontalLabelWidth: 0.2,
+ verticalLabelHeight: 0.15,
+}
class BarChart extends AbstractChart {
+ getBarPercentage = () => {
+ const { barPercentage = 1 } = this.props.chartConfig;
+ return barPercentage;
+ };
+
+ barPosSetup = (config) => {
+ const { data, width, height, gutterTop, horizontalLabelWidth, verticalLabelHeight,
+ chartStyle: { paddingTop, paddingLeft, paddingRight, paddingBottom },
+ } = config;
+ const innerHeight = (height - paddingTop - paddingBottom - verticalLabelHeight - gutterTop);
+ const baseHeight = this.calcBaseHeight(data, innerHeight);
+ const labelWidth = (width - horizontalLabelWidth - paddingRight - paddingLeft) / data.length;
+ const midPoint = labelWidth / 2;
+ const barWidth = this.props.barWidth * this.getBarPercentage();
+ return { innerHeight, baseHeight, labelWidth, midPoint, barWidth };
+ }
+
renderBars = config => {
- const { data, width, height, paddingTop, paddingRight } = config
- return data.map((x, i) => {
- const barHeight = height / 4 * 3 * ((x - Math.min(...data)) / (Math.max(...data) - Math.min(...data)))
- const barWidth = 32
+ const { data, width, height, gutterTop, horizontalLabelWidth, verticalLabelHeight, barRadius,
+ chartStyle: { paddingTop, paddingLeft, paddingRight, paddingBottom },
+ } = config;
+
+ const { innerHeight, baseHeight, labelWidth, midPoint, barWidth } = this.barPosSetup(config);
+
+ return data.map((value, i) => {
+ const barHeight = this.calcHeight(value, data, innerHeight);
+ const x = horizontalLabelWidth + paddingLeft + labelWidth * i + midPoint - barWidth/2;
+ const y = (barHeight > 0 ? baseHeight - barHeight : baseHeight) + gutterTop + paddingTop;
return (
)
- })
- }
+ />
+ );
+ });
+ };
renderBarTops = config => {
- const { data, width, height, paddingTop, paddingRight } = config
- return data.map((x, i) => {
- const barHeight = height / 4 * 3 * ((x - Math.min(...data)) / (Math.max(...data) - Math.min(...data)))
+ const { data, width, height, gutterTop, horizontalLabelWidth, verticalLabelHeight,
+ chartStyle: { paddingTop, paddingLeft, paddingRight, paddingBottom },
+ } = config;
+
+ const { innerHeight, baseHeight, labelWidth, midPoint, barWidth } = this.barPosSetup(config);
+
+ return data.map((value, i) => {
+ const barHeight = this.calcHeight(value, data, innerHeight);
+ const x = horizontalLabelWidth + paddingLeft + labelWidth * i + midPoint - barWidth/2;
+ const y = baseHeight - barHeight + gutterTop + paddingTop;
return (
)
- })
- }
+ />
+ );
+ });
+ };
+
+ renderValuesOnTopOfBars = config => {
+ const { data, width, height, gutterTop, horizontalLabelWidth, verticalLabelHeight,
+ chartStyle: { paddingTop, paddingLeft, paddingRight, paddingBottom },
+ } = config;
+
+ const { innerHeight, baseHeight, labelWidth, midPoint, barWidth } = this.barPosSetup(config);
+
+ return data.map((value, i) => {
+ const barHeight = this.calcHeight(value, data, innerHeight);
+ const x = horizontalLabelWidth + paddingLeft + labelWidth * i + midPoint;
+ const y = baseHeight - barHeight + gutterTop + paddingTop - 2;
+ return (
+
+ {data[i]}
+
+ );
+ });
+ };
render() {
- const paddingTop = 16
- const paddingRight = 32
- const { width, height, data, style = {} } = this.props
- const config = {
+ const {
width,
- height
+ height,
+ data,
+ style = {},
+ withHorizontalLabels = true,
+ withVerticalLabels = true,
+ verticalLabelRotation = 0,
+ horizontalLabelRotation = 0,
+ withInnerLines = true,
+ showBarTops = true,
+ showValuesOnTopOfBars = false,
+ segments = 5
+ } = this.props;
+
+ const defaultChartStyle = {
+ borderRadius: 0,
+ paddingTop: 0,
+ paddingBottom: 0,
+ paddingRight: 0,
+ paddingLeft: 0,
}
+
+ const config = {
+ width,
+ height,
+ chartStyle: {
+ ...defaultChartStyle,
+ ...this.props.chartConfig.chartStyle,
+ },
+ verticalLabelRotation,
+ horizontalLabelRotation,
+ horizontalOffset: this.props.horizontalOffset || 0,
+ barRadius:
+ (this.props.chartConfig && this.props.chartConfig.barRadius) || 0,
+ decimalPlaces:
+ (this.props.chartConfig && this.props.chartConfig.decimalPlaces) ?? 2,
+ formatYLabel:
+ (this.props.chartConfig && this.props.chartConfig.formatYLabel) ||
+ function(label) {
+ return label;
+ },
+ formatXLabel:
+ (this.props.chartConfig && this.props.chartConfig.formatXLabel) ||
+ function(label) {
+ return label;
+ }
+ };
+
+ //auto dynamic size if user dont set the following props
+ config.gutterTop = this.props.chartConfig.gutterTop ??
+ (height - config.chartStyle.paddingTop - config.chartStyle.paddingBottom) * BAR_RATIO.gutterTop;
+
+ config.horizontalLabelWidth = this.props.chartConfig.horizontalLabelWidth ??
+ (width - config.chartStyle.paddingRight - config.chartStyle.paddingLeft) * BAR_RATIO.horizontalLabelWidth;
+
+ config.verticalLabelHeight = this.props.chartConfig.verticalLabelHeight ??
+ (height - config.chartStyle.paddingTop - config.chartStyle.paddingBottom) * BAR_RATIO.verticalLabelHeight;
+
+ const labelWidth = (config.width - config.horizontalLabelWidth -
+ config.chartStyle.paddingRight - config.chartStyle.paddingLeft) / data.labels.length;
+
return (
-
-