Skip to content

Commit

Permalink
feat: add options prop to Chart component (#2063)
Browse files Browse the repository at this point in the history
* feat: add options prop to Chart component

* fix: improve docs

Co-authored-by: Tahimi <tahimileon@gmail.com>
  • Loading branch information
HellWolf93 and TahimiLeonBravo committed Dec 27, 2020
1 parent 09326ff commit 5981410
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 1 deletion.
37 changes: 37 additions & 0 deletions src/components/Chart/helpers/__test__/merge.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import merge from '../merge';

describe('merge', () => {
it('should merge the objects recursively', () => {
const obj1 = {
key1: 'value1',
key2: {
subKey1: true,
},
};
const obj2 = {
key2: {
subKey2: 25,
},
key3: 'value3',
};
const resultObj = {
key1: 'value1',
key2: {
subKey1: true,
subKey2: 25,
},
key3: 'value3',
};
expect(merge(obj1, obj2)).toEqual(resultObj);
});

it('should overwrite existing keys', () => {
const obj1 = {
key: 'value',
};
const obj2 = {
key: true,
};
expect(merge(obj1, obj2)).toEqual(obj2);
});
});
30 changes: 30 additions & 0 deletions src/components/Chart/helpers/merge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const merge = (...args) => {
// create a new object
const target = {};

// deep merge the object into the target object
const merger = obj => {
const keys = Object.keys(obj);
keys.forEach(prop => {
if (Object.prototype.toString.call(obj[prop]) === '[object Object]') {
// if the property is a nested object
target[prop] = merge(target[prop], obj[prop]);
} else {
// for regular property
target[prop] = obj[prop];
}
});
};

// iterate through all objects and
// deep merge them with target
args.forEach(obj => {
if (obj) {
merger(obj);
}
});

return target;
};

export default merge;
6 changes: 6 additions & 0 deletions src/components/Chart/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ Chart.propTypes = {
maintainAspectRatio: PropTypes.bool,
/** Plugins to customize the Chart. */
plugins: PropTypes.arrayOf(PropTypes.object),
/** An object with options to pass to Chart.js; Options in this object
* will have precedence over any other option.
* See: https://www.chartjs.org/docs/2.7.3/general/
*/
options: PropTypes.object,
/** A CSS class for the outer element, in addition to the component's base classes. */
className: PropTypes.string,
/** An object with custom style applied for the outer element. */
Expand Down Expand Up @@ -147,6 +152,7 @@ Chart.defaultProps = {
disableYAxisTickLabels: false,
maintainAspectRatio: true,
plugins: undefined,
options: {},
className: undefined,
style: undefined,
children: undefined,
Expand Down
119 changes: 119 additions & 0 deletions src/components/Chart/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -1078,3 +1078,122 @@ const containerStyles = {
</div>
</div>
```

##### Bar chart with options object:

```js
import React from 'react';
import { Chart, Dataset } from 'react-rainbow-components';
import datalabels from 'chartjs-plugin-datalabels';
import colorschemes from 'chartjs-plugin-colorschemes';

function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}

function getRandomValues(len, min, max) {
return Array(len)
.fill(0)
.map(() => getRandomInt(min, max));
}

const labels = [
'07/21',
'07/22',
'07/23',
'07/24',
'07/25',
'07/26',
'07/27',
'07/28',
'07/29',
'07/30',
'08/01',
'08/02',
];
const options = {
maintainAspectRatio: true,
scales: {
xAxes: [
{
id: 'axis1',
stacked: true,
type: 'category',
barThickness: 27,
gridLines: {
display: false,
}
},
{
id: 'axis2',
stacked: true,
type: 'category',
gridLines: {
display: false,
},
display: false,
}
],
yAxes: [{
gridLines: {
display: false,
},
scaleLabel: {
display: true,
labelString: 'SMS',
fontFamily: 'Lato',
fontSize: 14,
fontStyle: 'bold',
fontColor: '#000',
},
ticks: {
suggestedMin: 0,
suggestedMax: 50,
}
}]
}
}
const plugins = [datalabels, colorschemes];
const containerStyles = {
maxWidth: 800,
};
const datalabelsConf = { anchor: 'end', align: 'top' };

const ChartWithOptionsObjectExample = () => {
return (
<div className="rainbow-p-vertical_large rainbow-m_auto" style={containerStyles}>
<div className="rainbow-align-content_center">
<Chart
plugins={plugins}
datalabels={datalabelsConf}
labels={labels}
type="bar"
className="rainbow-m-horizontal_xx-large rainbow-m-top_x-large"
disableXAxisGridLines
disableYAxisGridLines
options={options}
>
<Dataset
id="data1"
title="SMS Delivered"
values={getRandomValues(12, 10, 30)}
backgroundColor="#68c4e4"
xAxisId="axis1"
datalabels={{ color: '#68c4e4' }}
/>
<Dataset
id="data2"
title="SMS Sent"
values={getRandomValues(12, 30, 40)}
backgroundColor="#dce5e4"
xAxisId="axis2"
datalabels={{ color: '#cad5d5' }}
/>
</Chart>
</div>
</div>
)
}

<ChartWithOptionsObjectExample />;
```
4 changes: 3 additions & 1 deletion src/components/Chart/resolveOptions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { replaceAlpha } from '../../styles/helpers/color';
import defaultTheme from '../../styles/defaultTheme';
import getPluginsConf from './helpers/getPluginsConf';
import merge from './helpers/merge';

export default function resolveOptions(conditions) {
const {
Expand All @@ -20,6 +21,7 @@ export default function resolveOptions(conditions) {
theme,
type,
plugins,
options: nativeOptions,
...rest
} = conditions;
const palette = theme ? theme.rainbow.palette : defaultTheme.palette;
Expand Down Expand Up @@ -161,5 +163,5 @@ export default function resolveOptions(conditions) {
};
}

return options;
return merge(options, nativeOptions);
}

0 comments on commit 5981410

Please sign in to comment.