diff --git a/App.js b/App.js index f7538e5c..89854d5a 100644 --- a/App.js +++ b/App.js @@ -1,14 +1,21 @@ import 'babel-polyfill' import React from 'react' -import {ScrollView, StatusBar, Dimensions, Text, View} from 'react-native' +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} from './data' +import { + data, + contributionData, + pieChartData, + progressChartData, + stackedBarGraphData +} from './data' // in Expo - swipe left to see the following styling, or create your own const chartConfigs = [ @@ -117,7 +124,7 @@ export default class App extends React.Component { data={data} width={width} height={height} - yAxisLabel={'$'} + yAxisLabel="$" chartConfig={chartConfig} style={graphStyle} onDataPointClick={({value, getColor}) => @@ -142,10 +149,18 @@ export default class App extends React.Component { width={width} height={height} data={data} - yAxisLabel={'$'} + yAxisLabel="$" chartConfig={chartConfig} style={graphStyle} /> + Stacked Bar Graph + Pie Chart diff --git a/README.md b/README.md index 2f6bdba2..3e52d44a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ import { BarChart, PieChart, ProgressChart, - ContributionGraph + ContributionGraph, + StackedBarChart } from 'react-native-chart-kit' ``` @@ -199,6 +200,38 @@ const data = { | yAxisLabel | string | Prepend text to horizontal labels -- default: '' | | chartConfig | Object | Configuration object for the chart, see example config in the beginning of this file | +## StackedBar chart + +![StackedBar_Chart](https://imgur.com/JkBtxt8.jpg) + +```js +const data ={ + labels: ['Test1', 'Test2'], + legend: ['L1', 'L2', 'L3'], + data: [ + [60, 60, 60], + [30,30,60], + ], + barColors: ['#dfe4ea', '#ced6e0', '#a4b0be'], + } +``` +```html + +``` + +| 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 | + ## Pie chart ![Pie Chart](https://i.imgur.com/JMz3obk.jpg) diff --git a/data.js b/data.js index 426e61bc..1b00817d 100644 --- a/data.js +++ b/data.js @@ -2,65 +2,91 @@ const data = { 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 - ] - }, { - data: [ - 30, - 90, - 67, - 54, - 10, - 2 - ] - }] + datasets: [ + { + data: [50, 20, 2, 86, 71, 100], + color: (opacity = 1) => `rgba(134, 65, 244, ${opacity})` // optional + }, + { + data: [20, 10, 4, 56, 87, 90] + }, + { + data: [30, 90, 67, 54, 10, 2] + } + ] } // 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: '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 } + { + 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] -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.js b/index.js index 60c1647d..2199fb36 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ 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 304315e2..4a56d1ea 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "react-test-renderer": "16.7.0", "xo": "^0.24.0" }, - "_main": "./node_modules/expo/AppEntry.js", - "main": "./index.js", + "main": "./node_modules/expo/AppEntry.js", + "_main": "./index.js", "scripts": { "start": "expo start", "eject": "expo eject", diff --git a/src/abstract-chart.js b/src/abstract-chart.js index 520bfdf3..d7965e31 100644 --- a/src/abstract-chart.js +++ b/src/abstract-chart.js @@ -84,17 +84,24 @@ class AbstractChart extends Component { height, paddingRight, paddingTop, - horizontalOffset = 0 + horizontalOffset = 0, + stackedBar = false } = config const fontSize = 12 + let fac = 1 + if (stackedBar) { + fac = 0.71 + } + return labels.map((label, i) => { return ( { + const { + data, + width, + height, + paddingTop, + paddingRight, + border, + colors + } = config + return data.map((x, i) => { + const barWidth = 32 + const ret = [] + let h = 0 + let st = paddingTop + for (let z = 0; z < x.length; z++) { + h = (height - 55) * (x[z] / border) + const y = (height / 4) * 3 - h + st + const xC = + (paddingRight + + (i * (width - paddingRight)) / data.length + + barWidth / 2) * + 0.7 + ret.push( + + ) + ret.push( + 15 ? y + 15 : y + 7} + fontSize={12} + fill="#fff" + > + {x[z]} + + ) + + st -= h + } + + return ret + }) + } + + renderLegend = config => { + const {legend, colors, width, height} = config + return legend.map((x, i) => { + return ( + + + + {x} + + + ) + }) + } + + render() { + const paddingTop = 15 + const paddingRight = 50 + const {width, height, style = {}, data} = this.props + const {borderRadius = 0} = style + const config = { + width, + height + } + let border = 0 + for (let i = 0; i < data.data.length; i++) { + const actual = data.data[i].reduce((pv, cv) => pv + cv, 0) + if (actual > border) { + border = actual + } + } + + return ( + + + {this.renderDefs({ + ...config, + ...this.props.chartConfig + })} + + + {this.renderHorizontalLines({ + ...config, + count: 4, + paddingTop + })} + + + {this.renderHorizontalLabels({ + ...config, + count: 4, + data: [0, border], + paddingTop, + paddingRight + })} + + + {this.renderVerticalLabels({ + ...config, + labels: data.labels, + paddingRight: paddingRight + 28, + stackedBar: true, + paddingTop, + horizontalOffset: barWidth + })} + + + {this.renderBars({ + ...config, + data: data.data, + border, + colors: this.props.data.barColors, + paddingTop, + paddingRight: paddingRight + 20 + })} + + {this.renderLegend({ + ...config, + legend: data.legend, + colors: this.props.data.barColors + })} + + + ) + } +} +export default StackedBarChart