mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-22 09:36:43 +03:00
Add redux-devtools-chart-monitor package (#555)
* Add redux-devtools-chart-monitor * Changes * ref
This commit is contained in:
parent
fead81ca9e
commit
681b11b500
4
packages/redux-devtools-chart-monitor/.babelrc
Normal file
4
packages/redux-devtools-chart-monitor/.babelrc
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"presets": ["@babel/preset-env", "@babel/preset-react"],
|
||||
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-export-default-from"]
|
||||
}
|
74
packages/redux-devtools-chart-monitor/README.md
Normal file
74
packages/redux-devtools-chart-monitor/README.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
Redux DevTools Chart Monitor
|
||||
=========================
|
||||
|
||||
A chart monitor for [Redux DevTools](https://github.com/gaearon/redux-devtools). Created by [@romseguy](https://github.com/romseguy) and merged from [`reduxjs/redux-devtools-chart-monitor`](https://github.com/reduxjs/redux-devtools-chart-monitor).
|
||||
|
||||
It shows a real-time view of the store aka the current state of the app.
|
||||
|
||||
:rocket: Now with immutable-js support.
|
||||
|
||||
[Demo](http://romseguy.github.io/redux-store-visualizer/) [(Source)](https://github.com/romseguy/redux-store-visualizer)
|
||||
|
||||
![Chart Monitor](https://camo.githubusercontent.com/19aebaeba929e97f97225115c49dc994299cb76e/687474703a2f2f692e696d6775722e636f6d2f4d53677655366c2e676966)
|
||||
|
||||
### Installation
|
||||
|
||||
```
|
||||
yarn add --dev redux-devtools-chart-monitor
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
You can use `ChartMonitor` as the only monitor in your app:
|
||||
|
||||
##### `containers/DevTools.js`
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import { createDevTools } from 'redux-devtools';
|
||||
import ChartMonitor from 'redux-devtools-chart-monitor';
|
||||
|
||||
export default createDevTools(
|
||||
<ChartMonitor />
|
||||
);
|
||||
```
|
||||
|
||||
Then you can render `<DevTools>` to any place inside app or even into a separate popup window.
|
||||
|
||||
Alternatively, you can use it together with [`DockMonitor`](https://github.com/gaearon/redux-devtools-dock-monitor) to make it dockable.
|
||||
Consult the [`DockMonitor` README](https://github.com/gaearon/redux-devtools-dock-monitor) for details of this approach.
|
||||
|
||||
[Read how to start using Redux DevTools.](https://github.com/reduxjs/redux-devtools)
|
||||
|
||||
### Features
|
||||
|
||||
### Props
|
||||
|
||||
#### ChartMonitor props
|
||||
|
||||
You can read the React component [propTypes](https://github.com/reduxjs/redux-devtools/blob/master/packages/redux-devtools-chart-monitor/src/Chart.js#L11) in addition to the details below:
|
||||
|
||||
Name | Description
|
||||
------------- | -------------
|
||||
`defaultIsVisible` | By default, set to `true`.
|
||||
`transitionDuration` | By default, set to `750`, in milliseconds.
|
||||
`heightBetweenNodesCoeff` | By default, set to `1`.
|
||||
`widthBetweenNodesCoeff` | By default, set to `1.3`.
|
||||
`isSorted` | By default, set to `false`.
|
||||
`style` | {<br> width: '100%', height: '100%', // i.e fullscreen for [`DockMonitor`](https://github.com/gaearon/redux-devtools-dock-monitor)<br> text: {<br> colors: {<br> 'default': `theme.base0D`,<br> hover: `theme.base06`<br> }<br> },<br> node: {<br> colors: {<br> 'default': `theme.base0B`,<br> collapsed: `theme.base0B`,<br> parent: `theme.base0E`<br> },<br> radius: 7<br> }<br>}
|
||||
`onClickText` | Function called with a reference to the clicked node as first argument when clicking on the text next to a node.
|
||||
`tooltipOptions` | {<br> disabled: false,<br> indentationSize: 2,<br> style: {<br> 'background-color': `theme.base06`,<br> 'opacity': '0.7',<br> 'border-radius': '5px',<br> 'padding': '5px'<br> }<br>}<br>[More info](https://github.com/reduxjs/redux-devtools/tree/master/packages/d3tooltip#api).
|
||||
|
||||
|
||||
|
||||
#### Redux DevTools props
|
||||
|
||||
Name | Description
|
||||
------------- | -------------
|
||||
`theme` | Either a string referring to one of the themes provided by [redux-devtools-themes](https://github.com/gaearon/redux-devtools-themes) (feel free to contribute!) or a custom object of the same format. Optional. By default, set to [`'nicinabox'`](https://github.com/gaearon/redux-devtools-themes/blob/master/src/nicinabox.js).
|
||||
`invertTheme` | Boolean value that will invert the colors of the selected theme. Optional. By default, set to `false`
|
||||
`select` | A function that selects the slice of the state for DevTools to show. For example, `state => state.thePart.iCare.about`. Optional. By default, set to `state => state`.
|
||||
|
||||
### License
|
||||
|
||||
MIT
|
55
packages/redux-devtools-chart-monitor/package.json
Normal file
55
packages/redux-devtools-chart-monitor/package.json
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"name": "redux-devtools-chart-monitor",
|
||||
"version": "1.7.0",
|
||||
"description": "Chart monitor for Redux DevTools",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"clean": "rimraf lib",
|
||||
"build": "babel src --out-dir lib",
|
||||
"prepare": "npm run build",
|
||||
"prepublishOnly": "npm run lint && npm run clean && npm run build"
|
||||
},
|
||||
"files": [
|
||||
"lib",
|
||||
"src"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reduxjs/redux-devtools.git"
|
||||
},
|
||||
"keywords": [
|
||||
"redux",
|
||||
"devtools",
|
||||
"flux",
|
||||
"react",
|
||||
"chart"
|
||||
],
|
||||
"author": "romseguy",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/reduxjs/redux-devtools/issues"
|
||||
},
|
||||
"homepage": "https://github.com/reduxjs/redux-devtools",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.10.5",
|
||||
"@babel/core": "^7.11.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.10.4",
|
||||
"@babel/preset-env": "^7.11.0",
|
||||
"@babel/preset-react": "^7.10.4",
|
||||
"babel-loader": "^8.1.0",
|
||||
"rimraf": "^2.7.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.3.0",
|
||||
"react-dom": "^16.3.0",
|
||||
"redux-devtools": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"d3-state-visualizer": "^1.3.2",
|
||||
"deepmerge": "^0.2.10",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-pure-render": "^1.0.2",
|
||||
"redux-devtools-themes": "^1.0.0"
|
||||
}
|
||||
}
|
86
packages/redux-devtools-chart-monitor/src/Chart.js
vendored
Normal file
86
packages/redux-devtools-chart-monitor/src/Chart.js
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
import React, { Component, createRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { tree } from 'd3-state-visualizer';
|
||||
|
||||
const wrapperStyle = {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
};
|
||||
|
||||
class Chart extends Component {
|
||||
static propTypes = {
|
||||
state: PropTypes.object,
|
||||
rootKeyName: PropTypes.string,
|
||||
pushMethod: PropTypes.oneOf(['push', 'unshift']),
|
||||
tree: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
children: PropTypes.array
|
||||
}),
|
||||
id: PropTypes.string,
|
||||
style: PropTypes.shape({
|
||||
node: PropTypes.shape({
|
||||
colors: PropTypes.shape({
|
||||
'default': PropTypes.string,
|
||||
parent: PropTypes.string,
|
||||
collapsed: PropTypes.string
|
||||
}),
|
||||
radius: PropTypes.number
|
||||
}),
|
||||
text: PropTypes.shape({
|
||||
colors: PropTypes.shape({
|
||||
'default': PropTypes.string,
|
||||
hover: PropTypes.string
|
||||
})
|
||||
}),
|
||||
link: PropTypes.object
|
||||
}),
|
||||
size: PropTypes.number,
|
||||
aspectRatio: PropTypes.number,
|
||||
margin: PropTypes.shape({
|
||||
top: PropTypes.number,
|
||||
right: PropTypes.number,
|
||||
bottom: PropTypes.number,
|
||||
left: PropTypes.number
|
||||
}),
|
||||
isSorted: PropTypes.bool,
|
||||
heightBetweenNodesCoeff: PropTypes.number,
|
||||
widthBetweenNodesCoeff: PropTypes.number,
|
||||
transitionDuration: PropTypes.number,
|
||||
onClickText: PropTypes.func,
|
||||
tooltipOptions: PropTypes.shape({
|
||||
disabled: PropTypes.bool,
|
||||
left: PropTypes.number,
|
||||
top: PropTypes.number,
|
||||
offset: PropTypes.shape({
|
||||
left: PropTypes.number,
|
||||
top: PropTypes.number
|
||||
}),
|
||||
indentationSize: PropTypes.number,
|
||||
style: PropTypes.object
|
||||
})
|
||||
};
|
||||
|
||||
divRef = createRef();
|
||||
|
||||
componentDidMount() {
|
||||
const { select, state, defaultIsVisible } = this.props;
|
||||
this.renderChart = tree(this.divRef.current, this.props);
|
||||
if (defaultIsVisible) {
|
||||
this.renderChart(select(state));
|
||||
}
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
const { state, select, monitorState } = nextProps;
|
||||
|
||||
if (monitorState.isVisible !== false) {
|
||||
this.renderChart(select(state));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div style={wrapperStyle} ref={this.divRef}/>;
|
||||
}
|
||||
}
|
||||
|
||||
export default Chart;
|
175
packages/redux-devtools-chart-monitor/src/ChartMonitor.js
Normal file
175
packages/redux-devtools-chart-monitor/src/ChartMonitor.js
Normal file
|
@ -0,0 +1,175 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import shouldPureComponentUpdate from 'react-pure-render/function';
|
||||
import * as themes from 'redux-devtools-themes';
|
||||
import { ActionCreators } from 'redux-devtools';
|
||||
import deepmerge from 'deepmerge';
|
||||
|
||||
import reducer from './reducers';
|
||||
import Chart from './Chart';
|
||||
const { reset, rollback, commit, sweep, toggleAction } = ActionCreators;
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
fontFamily: 'monaco, Consolas, Lucida Console, monospace',
|
||||
position: 'relative',
|
||||
overflowY: 'hidden',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
minWidth: 300
|
||||
}
|
||||
};
|
||||
|
||||
function invertColors(theme) {
|
||||
return {
|
||||
...theme,
|
||||
base00: theme.base07,
|
||||
base01: theme.base06,
|
||||
base02: theme.base05,
|
||||
base03: theme.base04,
|
||||
base04: theme.base03,
|
||||
base05: theme.base02,
|
||||
base06: theme.base01,
|
||||
base07: theme.base00
|
||||
};
|
||||
}
|
||||
|
||||
class ChartMonitor extends Component {
|
||||
static update = reducer;
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func,
|
||||
computedStates: PropTypes.array,
|
||||
currentStateIndex: PropTypes.number,
|
||||
actionsById: PropTypes.object,
|
||||
stagedActionIds: PropTypes.array,
|
||||
skippedActionIds: PropTypes.array,
|
||||
monitorState: PropTypes.shape({
|
||||
initialScrollTop: PropTypes.number
|
||||
}),
|
||||
|
||||
preserveScrollTop: PropTypes.bool,
|
||||
select: PropTypes.func.isRequired,
|
||||
theme: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.string
|
||||
]),
|
||||
invertTheme: PropTypes.bool
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
select: (state) => state,
|
||||
theme: 'nicinabox',
|
||||
preserveScrollTop: true,
|
||||
invertTheme: false
|
||||
};
|
||||
|
||||
shouldComponentUpdate = shouldPureComponentUpdate;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleToggleAction = this.handleToggleAction.bind(this);
|
||||
this.handleReset = this.handleReset.bind(this);
|
||||
this.handleRollback = this.handleRollback.bind(this);
|
||||
this.handleSweep = this.handleSweep.bind(this);
|
||||
this.handleCommit = this.handleCommit.bind(this);
|
||||
}
|
||||
|
||||
handleRollback() {
|
||||
this.props.dispatch(rollback());
|
||||
}
|
||||
|
||||
handleSweep() {
|
||||
this.props.dispatch(sweep());
|
||||
}
|
||||
|
||||
handleCommit() {
|
||||
this.props.dispatch(commit());
|
||||
}
|
||||
|
||||
handleToggleAction(id) {
|
||||
this.props.dispatch(toggleAction(id));
|
||||
}
|
||||
|
||||
handleReset() {
|
||||
this.props.dispatch(reset());
|
||||
}
|
||||
|
||||
getTheme() {
|
||||
let { theme, invertTheme } = this.props;
|
||||
if (typeof theme !== 'string') {
|
||||
return invertTheme ? invertColors(theme) : theme;
|
||||
}
|
||||
|
||||
if (typeof themes[theme] !== 'undefined') {
|
||||
return invertTheme ? invertColors(themes[theme]) : themes[theme];
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('DevTools theme ' + theme + ' not found, defaulting to nicinabox');
|
||||
return invertTheme ? invertColors(themes.nicinabox) : themes.nicinabox;
|
||||
}
|
||||
|
||||
getChartStyle() {
|
||||
const theme = this.getTheme();
|
||||
|
||||
return {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
node: {
|
||||
colors: {
|
||||
'default': theme.base0B,
|
||||
collapsed: theme.base0B,
|
||||
parent: theme.base0E
|
||||
},
|
||||
radius: 7
|
||||
},
|
||||
text: {
|
||||
colors: {
|
||||
'default': theme.base0D,
|
||||
hover: theme.base06
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getChartOptions(props = this.props) {
|
||||
const { computedStates } = props;
|
||||
const theme = this.getTheme();
|
||||
|
||||
const tooltipOptions = {
|
||||
disabled: false,
|
||||
offset: {left: 30, top: 10},
|
||||
indentationSize: 2,
|
||||
style: {
|
||||
'background-color': theme.base06,
|
||||
'opacity': '0.7',
|
||||
'border-radius': '5px',
|
||||
'padding': '5px'
|
||||
}
|
||||
};
|
||||
|
||||
const defaultOptions = {
|
||||
state: computedStates.length ? computedStates[props.currentStateIndex].state : null,
|
||||
isSorted: false,
|
||||
heightBetweenNodesCoeff: 1,
|
||||
widthBetweenNodesCoeff: 1.3,
|
||||
tooltipOptions,
|
||||
style: this.getChartStyle()
|
||||
};
|
||||
|
||||
return deepmerge(defaultOptions, props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const theme = this.getTheme();
|
||||
|
||||
return (
|
||||
<div style={{...styles.container, backgroundColor: theme.base07}}>
|
||||
<Chart {...this.getChartOptions()} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ChartMonitor;
|
1
packages/redux-devtools-chart-monitor/src/actions.js
Normal file
1
packages/redux-devtools-chart-monitor/src/actions.js
Normal file
|
@ -0,0 +1 @@
|
|||
export const TOGGLE_VISIBILITY = '@@redux-devtools-log-monitor/TOGGLE_VISIBILITY';
|
1
packages/redux-devtools-chart-monitor/src/index.js
Normal file
1
packages/redux-devtools-chart-monitor/src/index.js
Normal file
|
@ -0,0 +1 @@
|
|||
export default from './ChartMonitor';
|
19
packages/redux-devtools-chart-monitor/src/reducers.js
Normal file
19
packages/redux-devtools-chart-monitor/src/reducers.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { TOGGLE_VISIBILITY } from './actions';
|
||||
|
||||
function toggleVisibility(props, state = props.defaultIsVisible, action) {
|
||||
if (action.type === TOGGLE_VISIBILITY) {
|
||||
return !state;
|
||||
}
|
||||
|
||||
if (props.defaultIsVisible !== undefined) {
|
||||
return props.defaultIsVisible;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export default function reducer(props, state = {}, action) {
|
||||
return {
|
||||
isVisible: toggleVisibility(props, state.isVisible, action)
|
||||
};
|
||||
}
|
13
yarn.lock
13
yarn.lock
|
@ -5860,7 +5860,7 @@ cyclist@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
||||
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
|
||||
|
||||
d3-state-visualizer@^1.3.1, d3-state-visualizer@^1.3.2:
|
||||
d3-state-visualizer@^1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/d3-state-visualizer/-/d3-state-visualizer-1.3.2.tgz#8e3ac418aa7ee7e3f46025309f9d1c215ee385eb"
|
||||
integrity sha512-XgTRC6FXeoTt8l79cc2f3Zaah+K7DUQb3GL0zfbvoIi7zWWHV4l7OfuX9/JxxvwilKApMZwHMBJ7cJ2yWAc5IQ==
|
||||
|
@ -13734,17 +13734,6 @@ redent@^3.0.0:
|
|||
indent-string "^4.0.0"
|
||||
strip-indent "^3.0.0"
|
||||
|
||||
redux-devtools-chart-monitor@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/redux-devtools-chart-monitor/-/redux-devtools-chart-monitor-1.7.0.tgz#bf6356f480142e3576f5bbbeead433a1598c5e7f"
|
||||
integrity sha512-1knxXASbo7ukukyf1rGNnME7gOgKY1XVZ4hoSzUjY6QFIC8iEneivXznCupxjfX5TDXLjZgQrFBrbGano1WK7g==
|
||||
dependencies:
|
||||
d3-state-visualizer "^1.3.1"
|
||||
deepmerge "^0.2.10"
|
||||
prop-types "^15.6.0"
|
||||
react-pure-render "^1.0.2"
|
||||
redux-devtools-themes "^1.0.0"
|
||||
|
||||
redux-devtools-dock-monitor@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/redux-devtools-dock-monitor/-/redux-devtools-dock-monitor-1.1.3.tgz#1205e823c82536570aac8551a1c4b70972cba6aa"
|
||||
|
|
Loading…
Reference in New Issue
Block a user