Skip to content

Commit

Permalink
add more d3-cloud props support
Browse files Browse the repository at this point in the history
  • Loading branch information
chentsulin committed Aug 25, 2021
1 parent c8b66e1 commit ac12177
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 38 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ module.exports = {
jest: true,
browser: true,
},
rules: {},
rules: {
'react/sort-prop-types': 'off',
},
};
32 changes: 18 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ const data = [
{ text: "duck", value: 10 },
];

const fontSizeMapper = (word) => Math.log2(word.value) * 5;
const fontSize = (word) => Math.log2(word.value) * 5;
const rotate = (word) => word.value % 360;

render(
<WordCloud data={data} fontSizeMapper={fontSizeMapper} rotate={rotate} />,
<WordCloud data={data} fontSize={fontSize} rotate={rotate} />,
document.getElementById("root")
);
```
Expand All @@ -41,18 +41,22 @@ for more detailed props, please refer to below:

## Props

| name | description | type | required | default |
| --------------- | ------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | -------- | --------------------- |
| data | The input data for rendering | Array<{ text: string, value: number }> ||
| width | Width of component (px) | number | | 700 |
| height | Height of component (px) | number | | 600 |
| fontSizeMapper | Map each element of `data` to font size (px) | Function: `(word: string, idx: number): number` | | `word => word.value;` |
| rotate | Map each element of `data` to font rotation degree. Or simply provide a number for global rotation. (degree) | Function \| number | | 0 |
| padding | Map each element of `data` to font padding. Or simply provide a number for global padding. (px) | Function \| number | | 5 |
| font | The font of text shown | Function \| string | | serif |
| onWordClick | Function called when click event triggered on a word | Function: `word => {}` | | null |
| onWordMouseOver | Function called when mouseover event triggered on a word | Function: `word => {}` | | null |
| onWordMouseOut | Function called when mouseout event triggered on a word | Function: `word => {}` | | null |
| name | description | type | required | default |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------ | -------------- | ---------------------------------------- | ---------- |
| data | The words array | `{ text: string, value: number }>[]` ||
| width | Width of the layout (px) | `number` | | `700` |
| height | Height of the layout (px) | `number` | | `600` |
| font | The font accessor function, which indicates the font face for each word. A constant may be specified instead of a function. | `string | (d) => string` | | `serif` |
| fontStyle | The fontStyle accessor function, which indicates the font style for each word. A constant may be specified instead of a function. | `string | (d) => string` | | `'normal'` |
| fontWeight | The fontWeight accessor function, which indicates the font weight for each word. A constant may be specified instead of a function. | `string | (d) => string` | | `'normal'` |
| fontSize | The fontSize accessor function, which indicates the numerical font size for each word. | `(d) => number` | | `(d) => Math.sqrt(d.value)` |
| rotate | The rotate accessor function, which indicates the rotation angle (in degrees) for each word. | `(d) => number` | | `() => (~~(Math.random() * 6) - 3) * 30` |
| spiral | The current type of spiral used for positioning words. This can either be one of the two built-in spirals, "archimedean" and "rectangular", or an arbitrary spiral generator can be used | `([width, height]) => t => [x, y]` | | `'archimedean'` |
| padding | The padding accessor function, which indicates the numerical padding for each word. | `number | (d) => number` | | `1` |
| random | The internal random number generator, used for selecting the initial position of each word, and the clockwise/counterclockwise direction of the spiral for each word. This should return a number in the range `[0, 1)`. | `(d) => number` | | `Math.random` |
| onWordClick | The function will be called when `click` event is triggered on a word | `word => {}` | | null |
| onWorwordMouseOver | The function will be called when `mouseover` event is triggered on a word | `word => {}` | | null |
| onWordMouseOut | The function will be called when `mouseout` event is triggered on a word | `word => {}` | | null |

## Build

Expand Down
43 changes: 29 additions & 14 deletions src/WordCloud.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { schemeCategory10 } from 'd3-scale-chromatic';
import { select } from 'd3-selection';
import { useRef } from 'react';

import { defaultFontSizeMapper } from './defaultMappers';

const fill = scaleOrdinal(schemeCategory10);

function WordCloud(props) {
Expand All @@ -23,10 +21,14 @@ function WordCloud(props) {
data,
width,
height,
padding,
font,
fontSizeMapper,
fontStyle,
fontWeight,
fontSize,
rotate,
spiral,
padding,
random,
onWordClick,
onWordMouseOver,
onWordMouseOut,
Expand All @@ -37,12 +39,16 @@ function WordCloud(props) {

// render based on new data
const layout = cloud()
.words(data)
.size([width, height])
.font(font)
.words(data)
.padding(padding)
.fontStyle(fontStyle)
.fontWeight(fontWeight)
.fontSize(fontSize)
.rotate(rotate)
.fontSize(fontSizeMapper)
.spiral(spiral)
.padding(padding)
.random(random)
.on('end', (words) => {
const texts = select(el)
.append('svg')
Expand Down Expand Up @@ -87,12 +93,16 @@ WordCloud.propTypes = {
value: PropTypes.number.isRequired,
})
).isRequired,
font: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
fontSizeMapper: PropTypes.func,
width: PropTypes.number,
height: PropTypes.number,
font: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
fontStyle: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
fontWeight: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
fontSize: PropTypes.func,
rotate: PropTypes.func,
spiral: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
padding: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
rotate: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
width: PropTypes.number,
random: PropTypes.func,
onWordClick: PropTypes.func,
onWordMouseOut: PropTypes.func,
onWordMouseOver: PropTypes.func,
Expand All @@ -101,10 +111,15 @@ WordCloud.propTypes = {
WordCloud.defaultProps = {
width: 700,
height: 600,
padding: 5,
font: 'serif',
fontSizeMapper: defaultFontSizeMapper,
rotate: 0,
fontStyle: 'normal',
fontWeight: 'normal',
fontSize: (d) => Math.sqrt(d.value),
// eslint-disable-next-line no-bitwise
rotate: () => (~~(Math.random() * 6) - 3) * 30,
spiral: 'archimedean',
padding: 1,
random: Math.random,
onWordClick: null,
onWordMouseOver: null,
onWordMouseOut: null,
Expand Down
10 changes: 5 additions & 5 deletions src/__tests__/WordCloud.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ const data = [
{ text: 'duck', value: 10 },
];

it('should call custom fontSizeMapper', () => {
const fontSizeMapper = jest.fn().mockReturnValue(10);
renderer.create(<WordCloud data={data} fontSizeMapper={fontSizeMapper} />);
expect(fontSizeMapper).toHaveBeenCalledTimes(data.length);
it('should call custom fontSize', () => {
const fontSize = jest.fn().mockReturnValue(10);
renderer.create(<WordCloud data={data} fontSize={fontSize} />);
expect(fontSize).toHaveBeenCalledTimes(data.length);
});

it('should call custom rotater', () => {
it('should call custom rotate', () => {
const rotate = jest.fn().mockReturnValue(1);
renderer.create(<WordCloud data={data} rotate={rotate} />);
expect(rotate).toHaveBeenCalledTimes(data.length);
Expand Down
Empty file removed src/defaultMappers/__tests__/.keep
Empty file.
3 changes: 0 additions & 3 deletions src/defaultMappers/defaultFontSizeMapper.js

This file was deleted.

1 change: 0 additions & 1 deletion src/defaultMappers/index.js

This file was deleted.

0 comments on commit ac12177

Please sign in to comment.