Skip to content

Commit 663af0d

Browse files
Legend addition with component separation and changes in Readme
2 parents b251387 + d181e5e commit 663af0d

File tree

11 files changed

+271
-104
lines changed

11 files changed

+271
-104
lines changed

README.md

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<a href="https://www.npmjs.com/package/react-dot-matrix-chart"><img src="https://badgen.net/npm/v/react-dot-matrix-chart?color=blue" alt="npm version"></a> <a href="https://www.npmjs.com/package/react-dot-matrix-chart" ><img src="https://img.shields.io/npm/dw/react-dot-matrix-chart?label=Downloads" /></a> <a href="https://github.com/KeyValueSoftwareSystems/react-dot-matrix-chart"><img src="https://github.com/KeyValueSoftwareSystems/react-dot-matrix-chart/actions/workflows/deploy.yml/badge.svg" alt="" /></a>
88

99
<div align="center">
10-
<img src="./screenshot.png" alt="" width="416" height="199"/>
10+
<img src="./screenshot.png" alt="" width="573" height="199"/>
1111
</div>
1212

1313

@@ -19,7 +19,7 @@ Try tweaking a dot matrix using this codesandbox link <a href="https://codesandb
1919

2020
The easiest way to use react-dot-matrix-chart is to install it from npm and build it into your app with Webpack.
2121

22-
```
22+
```bash
2323
npm install react-dot-matrix-chart
2424
```
2525

@@ -33,7 +33,7 @@ You’ll need to install React separately since it isn't included in the package
3333

3434
React Dot Matrix Chart can run in a very basic mode by just providing the `dataPoints` like given below:
3535

36-
```
36+
```jsx
3737

3838
import DotMatrix from 'react-dot-matrix-chart';
3939

@@ -53,9 +53,8 @@ The datapoints is an array of objects with the following keys:
5353

5454
An example for dataPoints array is shown below:
5555

56-
```
57-
58-
dataPointsArray = [
56+
```jsx
57+
const dataPointsArray = [
5958
{
6059
name: 'Category 1',
6160
count: 10,
@@ -77,32 +76,39 @@ dataPointsArray = [
7776

7877
You can use `title` prop to add a Title value to the dot matrix chart
7978

80-
```
81-
79+
```jsx
8280
<DotMatrix
8381
dataPoints={dataPointsArray}
8482
title="Dot Matrix"
8583
/>
86-
8784
```
8885

8986
You can specify the number of rows or columns to be present in the chart as well using the dimensions prop.
9087

91-
```
88+
```jsx
9289
<DotMatrix
9390
dataPoints={dataPointsArray}
9491
dimensions={
9592
rows: 5,
9693
columns: 10
9794
}
9895
/>
99-
10096
```
10197

10298
If the count given in the dataPoints array results in a partial percentage (decimal value), a gradient dot will be displayed as shown below
99+
<div align="center">
100+
<img src="./screenshotPartial.png" alt="" width="208" height="199"/>
101+
</div>
103102

104-
103+
We can also control the display of the legend consisting of the details regarding the colour distribution using the props 'showLegend' and 'legendPosition' as follows.
105104

105+
```jsx
106+
<DotMatrix
107+
dataPoints={dataPointsArray}
108+
showLegend={true}
109+
legendPosition="top"
110+
/>
111+
```
106112
## Props
107113

108114

@@ -146,6 +152,20 @@ Props that can be passed to the component are listed below:
146152
</td>
147153
<td><code>undefined</code></td>
148154
</tr>
155+
<tr>
156+
<td><code><b>showLegend?:</b> boolean</code></td>
157+
<td>
158+
To specify whether to show the legend or not
159+
</td>
160+
<td><code>false</code></td>
161+
</tr>
162+
<tr>
163+
<td><code><b>legendPosition?:</b> string</code></td>
164+
<td>
165+
To specify the position of the legend. The values that can be passes using this prop are 'left', 'right', 'top' and 'bottom'
166+
</td>
167+
<td><code>right</code></td>
168+
</tr>
149169
</tbody>
150170
</table>
151171

@@ -155,18 +175,24 @@ Props that can be passed to the component are listed below:
155175
All the default styles provided by this package are overridable using the `style` prop.
156176
the below code shows all the overridable styles:
157177

158-
```
178+
```jsx
159179
<DotMatrix
160180
dataPoints={dataPointsArray}
161181
styles={{
162-
Title: () => ({...styles}),
163182
Container: () => ({...styles}),
164-
Dot: () => ({...styles})
183+
DotsContainer: () => ({...styles}),
184+
Dot: () => ({...styles}),
185+
LegendContainer: () => ({...styles}),
186+
LegendName: () => ({...styles}),
187+
LegendDot: () => ({...styles})
165188
}}
166189
/>
167190

168191
```
169192

170-
- `Title` - overrides the chart title style
171193
- `Container` - overrides the dot matrix chart container style
172-
- `Dot` - overrides the style of each dot in the chart
194+
- `DotsContainer` - overrides the dot matrix chart dots container style
195+
- `Dot` - overrides the style of each dot in the chart
196+
- `LegendContainer` - overrides the legend (details) container style
197+
- `LegendName` - overrides the legend name style
198+
- `LegendDot` - overrides the legend dot style

screenshot.png

11.2 KB
Loading

screenshotPartial.png

6.94 KB
Loading

src/lib/dot-matrix/Chart.tsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React from 'react';
2+
import { v4 } from 'uuid';
3+
import {
4+
getNumberOfDots,
5+
getContainerWidth,
6+
getStyles,
7+
hasOverlapping
8+
} from './utils/utils';
9+
import {
10+
Elements,
11+
DEFAULT_COLUMNS,
12+
DEFAULT_ROWS
13+
} from "./constants";
14+
import { ChartProps, DataPointType } from './types';
15+
import classes from './styles.module.scss';
16+
17+
const Chart = (props: ChartProps) : JSX.Element => {
18+
const {
19+
dimensions = {},
20+
styles,
21+
data,
22+
overlappingValues,
23+
total
24+
} = props;
25+
const {
26+
rows = DEFAULT_ROWS,
27+
columns = DEFAULT_COLUMNS
28+
} = dimensions;
29+
30+
return (
31+
<div
32+
className={classes.dotsContainer}
33+
style={{
34+
width: `${getContainerWidth(columns)}rem`,
35+
...getStyles(Elements.DotsContainer, styles)
36+
}}
37+
>
38+
{data?.map((dataItem: DataPointType, rowIndex: number) => (
39+
<React.Fragment key={v4()}>
40+
{dataItem && Array.apply(null, Array(getNumberOfDots(dataItem, rows, columns, total))).map((item: null, columnIndex: number) => (
41+
<div id="dot-matrix-dots" key={v4()}>
42+
{(hasOverlapping(overlappingValues, rowIndex, columnIndex) && (
43+
<div
44+
className={classes.eachDot}
45+
style={{
46+
backgroundImage: `linear-gradient(to right, ${data[rowIndex - 1].color} 20%, ${dataItem?.color} 50%)`,
47+
...(getStyles(Elements.Dot, styles))
48+
}}
49+
/>
50+
)) || (
51+
<div
52+
className={classes.eachDot}
53+
style={{
54+
backgroundColor: dataItem?.color,
55+
...(getStyles(Elements.Dot, styles))
56+
}}
57+
key={v4()}
58+
id={`each-category-${rowIndex}-${columnIndex}`}
59+
/>
60+
)}
61+
</div>
62+
))}
63+
</React.Fragment>
64+
))}
65+
</div>
66+
)
67+
};
68+
export default Chart;

src/lib/dot-matrix/DotMatrix.tsx

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,51 @@
11
import React from "react";
2-
import { v4 } from 'uuid';
32
import classes from './styles.module.scss';
4-
import { DotMatrixPropType, DataPointType } from "./types";
3+
import { DotMatrixPropType } from "./types";
54
import { useDotMatrix } from './custom-hooks/useDotMatrix';
5+
import Chart from './Chart';
6+
import Legend from './Legend';
7+
import { getLegendPosition, getStyles } from "./utils/utils";
68
import {
79
Elements,
810
DEFAULT_COLUMNS,
9-
DEFAULT_ROWS
11+
DEFAULT_ROWS,
12+
DEFAULT_LEGEND_POSITION
1013
} from "./constants";
11-
import { getNumberOfDots, getContainerWidth } from './utils/utils';
1214
const DotMatrix = (props: DotMatrixPropType): JSX.Element => {
1315
const {
1416
dataPoints,
1517
dimensions = {
1618
rows: DEFAULT_ROWS,
1719
columns: DEFAULT_COLUMNS
1820
},
19-
styles = {}
21+
styles = {},
22+
showLegend,
23+
legendPosition = DEFAULT_LEGEND_POSITION
2024
} = props;
2125

22-
const {
23-
rows = DEFAULT_ROWS,
24-
columns = DEFAULT_ROWS
25-
} = dimensions;
26-
2726
const [data, total, overlappingValues] = useDotMatrix(dataPoints, dimensions);
28-
const getStyles = (element: Elements): object => {
29-
const getElementStyle = styles[element];
30-
if (getElementStyle) {
31-
return getElementStyle();
32-
}
33-
return {};
34-
};
35-
36-
3727
return (
3828
<div className={classes.container}>
3929
<div
40-
className={classes.dotsContainer}
30+
className={classes.dotsWithLegend}
4131
style={{
42-
width: `${getContainerWidth(columns)}rem`,
43-
...getStyles(Elements.Container)
32+
...getStyles(Elements.Container, styles),
33+
...(getLegendPosition(legendPosition) as React.CSSProperties)
4434
}}
4535
>
46-
{data?.map((eachPoint: DataPointType, rowIndex: number) => (
47-
<React.Fragment key={v4()}>
48-
{eachPoint && Array.apply(null, Array(getNumberOfDots(eachPoint, rows, columns, total))).map((item: null, columnIndex: number) => (
49-
<div id="dot-matrix-dots" key={v4()}>
50-
{(columnIndex === 0 && rowIndex > 0 && overlappingValues[rowIndex - 1] < 1 && overlappingValues[rowIndex - 1] !== 0 && (
51-
<div
52-
className={classes.eachDot}
53-
style={{
54-
backgroundImage: `linear-gradient(to right, ${data[rowIndex - 1].color} 20%, ${eachPoint?.color} 50%)`,
55-
...(getStyles(Elements.Dot))
56-
}}
57-
/>
58-
)) || (
59-
<div
60-
className={classes.eachDot}
61-
style={{
62-
backgroundColor: eachPoint?.color,
63-
...(getStyles(Elements.Dot))
64-
}}
65-
key={v4()}
66-
id={`each-category-${rowIndex}-${columnIndex}`}
67-
/>
68-
)}
69-
</div>
70-
))}
71-
</React.Fragment>
72-
))}
36+
<Chart
37+
styles={styles}
38+
dimensions={dimensions}
39+
data={data}
40+
total={total}
41+
overlappingValues={overlappingValues}
42+
/>
43+
{showLegend && (
44+
<Legend
45+
styles={styles}
46+
data={data}
47+
/>
48+
)}
7349
</div>
7450
</div>
7551
)

src/lib/dot-matrix/Legend.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from 'react';
2+
import { v4 } from 'uuid';
3+
import { getStyles } from './utils/utils';
4+
import { DataPointType, LegendProps } from "./types";
5+
import {
6+
Elements
7+
} from './constants';
8+
import classes from './styles.module.scss';
9+
10+
const Legend = (props: LegendProps): JSX.Element => {
11+
const {
12+
styles,
13+
data
14+
} = props;
15+
return (
16+
<div
17+
className={classes.legends}
18+
style={{ ...getStyles(Elements.LegendContainer, styles)}}
19+
>
20+
{data?.map((point: DataPointType) => (
21+
<div className={classes.legend} key={v4()}>
22+
<div
23+
className={classes.legendDot}
24+
style={{
25+
backgroundColor: point?.color,
26+
...(getStyles(Elements.LegendDot, styles))
27+
}}
28+
/>
29+
<div
30+
className={classes.name}
31+
style={{ ...getStyles(Elements.LegendName, styles)}}
32+
>
33+
{point.name}
34+
</div>
35+
</div>
36+
))}
37+
</div>
38+
)
39+
};
40+
41+
export default Legend;

src/lib/dot-matrix/constants.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,17 @@ export const COLOR_PALATTE = [
2323

2424
export enum Elements {
2525
Container = "Container",
26-
Dot = "Dot"
26+
DotsContainer = "DotsContainer",
27+
Dot = "Dot",
28+
LegendContainer = "LegendContainer",
29+
LegendDot = "LegendDot",
30+
LegendName = "LegendName"
2731
}
2832

2933
export const DEFAULT_ROWS = 5;
3034

3135
export const DEFAULT_COLUMNS = 12;
3236

37+
export const DEFAULT_LEGEND_POSITION = 'right';
38+
3339
export const CONTAINER_WIDTH_CONVERSION_FACTOR = 2.6;

0 commit comments

Comments
 (0)