National Public Mania

    @seracio/thirdact

    0.9.0 • Public • Published

    thirdAct

    A set of react components that encapsulate d3-selection api

    Disclaimer

    thirdact is still on a very early stage. It is born of our frustration of using the different workflows that mix React and d3 together.

    d3's general update pattern is quite incompatible with React's data binding as React only keeps track of the current data.

    This is an experimental attempt to express the d3-selection API in a jsx style. This way, we can mix d3 and React into the render method, without using React hooks such as componentDidUpdate to manage d3 instructions.

    • It uses the d3-selection API under the hood, we are just transforming jsx components to d3 instructions
    • React's Virtual DOM is not involved or aware of the generated DOM, but we isolate it into an empty React element

    A first overview

    you can find a full example here

    import { scaleLinear } from 'd3-scale';
    import React from 'react';
    import {
        SelectAll,
        Transition,
        Selection,
        Append,
        Remove
    } from '@seracio/thirdact';
    
    const App = ({ data }) => {
        const size = 500;
    
        const scaleX = scaleLinear()
            .domain([0, data.length - 1])
            .range([100, 400]);
    
        return (
            <svg
                preserveAspectRatio="xMinYMin meet"
                viewBox={`0 0 ${size} ${size}`}
            >
                <text
                    x={size / 2}
                    y={50}
                    style={{
                        alignmentBaseline: 'middle',
                        textAnchor: 'middle',
                        fontFamily: 'sans-serif'
                    }}
                >
                    Hello thirdact
                </text>
                <SelectAll data={data} selector={'.circle'} root={<g />}>                
                    <Selection type="enter">
                        <Append>
                            {/* use react conventions to specify your data */}
                            <circle
                                className="circle"
                                cx={(d, i) => scaleX(i)}
                                cy={100}
                                r={10}
                                style={{ fill: 'transparent' }}
                            />
                        </Append>
                        {/* on a transition, only specify the attr, styles or events you want to update */}
                        <Transition duration={1000}>
                            <circle cy={200} style={{ fill: d => d }} />
                        </Transition>
                    </Selection>
                    <Selection type="update">
                        <Transition duration={1000}>
                            <circle cx={(d, i) => scaleX(i)} />
                        </Transition>
                    </Selection>
                    <Selection type="exit">
                        {/* you can chain transitions */}
                        <Transition duration={500}>
                            <circle cy={250} r={5} />
                        </Transition>
                        <Transition duration={500}>
                            <circle cy={400} style={{ fill: 'transparent' }} />
                        </Transition>
                        <Remove />
                    </Selection>
                </SelectAll>        
            </svg>
        );
    };

    Install

    yarn add react react-dom d3-selection d3-selection-multi d3-transition lodash.kebabcase
    yarn add @seracio/thirdact

    Usage

    First of all - and if you use d3 modules - you'll need to patch d3-selection-multi and d3-transition to d3 in your root file:

    import * as d3 from 'd3-selection';
    import 'd3-selection-multi';
    import 'd3-transition';

    Then you can import the different components of thirdact:

    import {
        SelectAll,
        Transition,
        Selection,
        Append,
        Remove
    } from '@seracio/thirdact';

    API

    SelectAll

    SelectAll is the root component, it takes several props:

    name type description
    data Array
    selector string the equivalent of the d3's selector in d3.selectAll(selector)
    getKey (d,i) => string an optional function to get the key of the current datum
    root React$Element the react element where the DOM managed by d3 will be

    Selection

    Selection is the only component allowed as direct child of SelectAll.
    It allows you to use d3's data join by specifying a type props:

    name type description
    type string enter or update or exit (and soon enter+exit)

    Once you have split your data into selections thanks to the general update pattern, you can finally do the mapping between your data and the DOM thans to modifiers:

    • Append to create items
    • Remove to remove them
    • Transition for updating them
    • Call to apply them a function

    You can chain modifiers.

    Append

    Append is used to add new tags to the DOM, define their attributes and styles or attach events. thirdact's API is here quite different to its d3 counterpart:

    <Append>
        <rect className="toto" 
            x={0} 
            y={(d,i) => i*10} 
            width={(d,i) => d} 
            height={10} 
            styles={{strokeWidth: 2}}
            onClick={(d,i) => console.log(d)}
            />
    </Append>

    will be transcripted on:

    selection.append('rect')
        .attr('class', 'toto')
        .attr('x', 0)
        .attr('y', i*10)
        .attr('width', (d,i) => d)
        .attr('height', 10)
        .style('stroke-width', 2)
        .on('click', (d,i) => console.log(d));

    Transitions

    Transition currently support these props:

    name type description
    duration number

    You just have to specify the attributes or styles you want to update:

    <Transition duration={500}>
        <path
            style={{fill: 'blue'}}
            tween-d={tween}
            />
    </Transition>

    Note the equivalent of d3's attrTween: tween-[attr name]

    Remove

    Remove has no props

    Call

    Call uses a function as a children

    <Selection type="enter">
        <Append>
            {/**/}
        </Append>
        <Call>
        {function(selection){
            // ...
        }}
        </Call>
    </Selection>

    Chaining transformations

    <Selection type="enter">
        <Append>
            <circle
                className="circle"
                cx={(d, i) => scaleX(i)}
                cy={100}
                r={10}
                style={{ fill: 'transparent' }}
            />
        </Append>
        <Transition duration={1000}>
            <circle cy={200} style={{ fill: d => d }} />
        </Transition>
    </Selection>

    License

    MIT License

    Copyright (c) 2017 serac.io

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Keywords

    none

    Install

    npm i @seracio/thirdact

    DownloadsWeekly Downloads

    3

    Version

    0.9.0

    License

    MIT

    Last publish

    Collaborators

    • seracio