Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
React + Redux + d3
Teemu Kurppa, ŌURA
teemu@ouraring.com
www.ouraring.com
the world's first wellness ring
Head of Cloud
I work at
• Declarative UI Library
• Battle-tested by Facebook
• Component-based
• Inline HTML with JSX
• Predictable state management for JS Apps
• Great tooling: logging, hot loading, time travel,…
d3.js
d3 - a lot of good stuff
• Handling data: Scales, Interpolators, Time Intervals, Time & Number formats
• Drawing: Paths, A...
d3 - problems
• No components: code gets unwieldy very quickly
• State management mixed with UI code
d3 class pattern
class D3SeriesBarChart {
constructor(el, props, state) {
// setup code
}
update(el, props, state) {
// da...
React wrapper for d3
class SeriesBarChart extends Component {
componentDidMount() {
this.chart = new D3SeriesBarChart(this...
React wrapper for d3
class SeriesBarChart extends Component {
componentDidMount() {
this.chart = new D3SeriesBarChart(this...
React wrapper for d3
var T = React.PropTypes;
SeriesBarChart.propTypes = {
width: T.number.isRequired,
height: T.number.is...
Demo Component
class Demo extends Component {
render() {
return (
<div className={classNames(styles.demo)}>
<form>
{this.m...
Demo Component
class Demo extends Component {
// …
makeRadio(mode, onChange) {
return (
<label><input type=“radio"
name=“m...
Redu Reducer
// reducers.js
const initialState = {
data: createData(),
mode: 'grouped'
};
function demo(state = initialSta...
Component CSS
// SeriesBarChart.jsx
import classNames from 'classnames';
const styles = require('./SeriesBarChart.scss');
...
Component CSS
// SeriesBarChart.scss
.seriesbarchart {
:global {
.axis text {
fill: blue;
}
}
}
Thanks! Questions?
We are hiring:
Python backend developers
web front-end developers
Follow @teemu on Twitter to stay in t...
React + Redux + d3.js
Upcoming SlideShare
Loading in …5
×

React + Redux + d3.js

1,271 views

Published on

Talk about combining React, Redux and d3.js. Given in ReactJS Helsinki in 2017.

Published in: Software
  • Be the first to comment

React + Redux + d3.js

  1. 1. React + Redux + d3 Teemu Kurppa, ŌURA
  2. 2. teemu@ouraring.com www.ouraring.com the world's first wellness ring Head of Cloud I work at
  3. 3. • Declarative UI Library • Battle-tested by Facebook • Component-based • Inline HTML with JSX
  4. 4. • Predictable state management for JS Apps • Great tooling: logging, hot loading, time travel,…
  5. 5. d3.js
  6. 6. d3 - a lot of good stuff • Handling data: Scales, Interpolators, Time Intervals, Time & Number formats • Drawing: Paths, Areas, Shapes, Curves, Axes • Data Structures for Visualization: Voronoi, Stack, Quadtrees, Polygons • Drawing maps: Projections, Spherical Math, Geopaths • Animations and Behaviour: Transitions, Easing, Zooming, Dragging, Forces
  7. 7. d3 - problems • No components: code gets unwieldy very quickly • State management mixed with UI code
  8. 8. d3 class pattern class D3SeriesBarChart { constructor(el, props, state) { // setup code } update(el, props, state) { // data-dependent code } }
  9. 9. React wrapper for d3 class SeriesBarChart extends Component { componentDidMount() { this.chart = new D3SeriesBarChart(this.svg, this.props, this.state); } componentDidUpdate() { this.chart.update(this.svg, this.props, this.state); } render() { return ( <svg ref={svg => this.svg = svg} width={this.props.width} height={this.props.height}> </svg> ); } }
  10. 10. React wrapper for d3 class SeriesBarChart extends Component { componentDidMount() { this.chart = new D3SeriesBarChart(this.svg, this.props, this.state); } componentDidUpdate() { this.chart.update(this.svg, this.props, this.state); } render() { return ( <svg ref={svg => this.svg = svg} width={this.props.width} height={this.props.height}> </svg> ); } }
  11. 11. React wrapper for d3 var T = React.PropTypes; SeriesBarChart.propTypes = { width: T.number.isRequired, height: T.number.isRequired, data: T.shape({ x: T.arrayOf(T.number), y: T.arrayOf(T.arrayOf(T.number)), }).isRequired, mode: T.string.isRequired }
  12. 12. Demo Component class Demo extends Component { render() { return ( <div className={classNames(styles.demo)}> <form> {this.makeRadio('grouped', this.props.onSelectGrouped)} {this.makeRadio('stacked', this.props.onSelectStacked)} </form> <SeriesBarChart width={960} height={500} data={this.props.data} mode={this.props.mode}/> <div> <button onClick={this.props.onGenerateData}> Generate Data </button> </div> </div> ); } // … }
  13. 13. Demo Component class Demo extends Component { // … makeRadio(mode, onChange) { return ( <label><input type=“radio" name=“mode" value={mode} onChange={onChange} checked={this.props.mode === mode}/> {mode} </label> ) } }
  14. 14. Redu Reducer // reducers.js const initialState = { data: createData(), mode: 'grouped' }; function demo(state = initialState, action) { switch (action.type) { case CHANGE_MODE: return { ...state, mode: action.mode }; case GENERATE_DATA: return { ...state, data: createData() }; default: return state; } } const rootReducer = combineReducers({ demo, }); export default rootReducer;
  15. 15. Component CSS // SeriesBarChart.jsx import classNames from 'classnames'; const styles = require('./SeriesBarChart.scss'); class SeriesBarChart extends Component { render() { return ( <svg className={classNames(styles.seriesbarchart)} ref={svg => this.svg = svg} width={this.props.width} height={this.props.height}> </svg> ); } }
  16. 16. Component CSS // SeriesBarChart.scss .seriesbarchart { :global { .axis text { fill: blue; } } }
  17. 17. Thanks! Questions? We are hiring: Python backend developers web front-end developers Follow @teemu on Twitter to stay in touch. Email: teemu@ouraring.com

×