From f364673388274c04f2af2d046c7d802cd5c1371f Mon Sep 17 00:00:00 2001 From: Jeff Avallone Date: Sat, 17 Feb 2018 12:06:35 -0500 Subject: [PATCH] Adding promisified setState and simplfying reflow code for SVG stuff --- src/components/SVG/Base.js | 13 +++++-- src/components/SVG/Box.js | 34 ++++++++--------- src/components/SVG/HorizontalLayout.js | 34 ++++++++--------- src/components/SVG/Image.js | 12 +++--- src/components/SVG/Loop.js | 52 +++++++++++++------------- src/components/SVG/Pin.js | 17 +++------ src/components/SVG/Text.js | 16 ++++---- src/components/SVG/VerticalLayout.js | 42 ++++++++++----------- 8 files changed, 103 insertions(+), 117 deletions(-) diff --git a/src/components/SVG/Base.js b/src/components/SVG/Base.js index b7c1f91..429c4e4 100644 --- a/src/components/SVG/Base.js +++ b/src/components/SVG/Base.js @@ -6,7 +6,13 @@ class Base extends React.PureComponent { return this.tempBBox ? this.tempBBox : (this.state || {}).bbox; } - setBBox(box, recalculate = {}) { + setStateAsync(state) { + return new Promise(resolve => { + this.setState(state, resolve); + }); + } + + async setBBox(box, recalculate = {}) { let bbox = this._currentBBox() || Map({ width: 0, height: 0}); bbox = bbox.merge(box); @@ -24,9 +30,8 @@ class Base extends React.PureComponent { } this.tempBBox = bbox; // Want to get the updated bbox while setState is pending - this.setState({ bbox }, () => { - this.tempBBox = null; - }); + await this.setStateAsync({ bbox }); + this.tempBBox = null; } getBBox() { diff --git a/src/components/SVG/Box.js b/src/components/SVG/Box.js index 81b3259..dcf76c0 100644 --- a/src/components/SVG/Box.js +++ b/src/components/SVG/Box.js @@ -16,26 +16,24 @@ class Box extends Base { } reflow() { - return new Promise(resolve => { - const { padding, useAnchors } = this.props; - const box = this.contained.getBBox(); - const labelBox = this.label ? this.label.getBBox() : { width: 0, height: 0}; + const { padding, useAnchors } = this.props; + const box = this.contained.getBBox(); + const labelBox = this.label ? this.label.getBBox() : { width: 0, height: 0}; - this.setBBox({ - width: Math.max(box.width + 2 * padding, labelBox.width), - height: box.height + 2 * padding + labelBox.height, - axisY: (useAnchors ? box.axisY : box.height / 2) + padding + labelBox.height, - axisX1: useAnchors ? box.axisX1 + padding : 0, - axisX2: useAnchors ? box.axisX2 + padding : box.width + 2 * padding - }); + this.setBBox({ + width: Math.max(box.width + 2 * padding, labelBox.width), + height: box.height + 2 * padding + labelBox.height, + axisY: (useAnchors ? box.axisY : box.height / 2) + padding + labelBox.height, + axisX1: useAnchors ? box.axisX1 + padding : 0, + axisX2: useAnchors ? box.axisX2 + padding : box.width + 2 * padding + }); - this.setState({ - width: this.getBBox().width, - height: box.height + 2 * padding, - contentTransform: `translate(${ padding } ${ padding + labelBox.height })`, - rectTransform: `translate(0 ${ labelBox.height })`, - labelTransform: `translate(0 ${ labelBox.height })` - }, resolve); + return this.setStateAsync({ + width: this.getBBox().width, + height: box.height + 2 * padding, + contentTransform: `translate(${ padding } ${ padding + labelBox.height })`, + rectTransform: `translate(0 ${ labelBox.height })`, + labelTransform: `translate(0 ${ labelBox.height })` }); } diff --git a/src/components/SVG/HorizontalLayout.js b/src/components/SVG/HorizontalLayout.js index 615a62a..a001bba 100644 --- a/src/components/SVG/HorizontalLayout.js +++ b/src/components/SVG/HorizontalLayout.js @@ -50,27 +50,25 @@ class HorizontalLayout extends Base { return; } - return new Promise(resolve => { - const { spacing, withConnectors } = this.props; + const { spacing, withConnectors } = this.props; - const childBoxes = this.children.map(child => child.getBBox()); - const verticalCenter = childBoxes.reduce((center, box) => Math.max(center, box.axisY), 0); - const width = childBoxes.reduce((width, box) => width + box.width, 0) + (childBoxes.length - 1) * spacing; - const height = childBoxes.reduce((ascHeight, box) => Math.max(ascHeight, box.axisY), 0) + - childBoxes.reduce((decHeight, box) => Math.max(decHeight, box.height - box.axisY), 0); - this.setBBox({ width, height, axisY: verticalCenter }, { axisX1: true, axisX2: true }); + const childBoxes = this.children.map(child => child.getBBox()); + const verticalCenter = childBoxes.reduce((center, box) => Math.max(center, box.axisY), 0); + const width = childBoxes.reduce((width, box) => width + box.width, 0) + (childBoxes.length - 1) * spacing; + const height = childBoxes.reduce((ascHeight, box) => Math.max(ascHeight, box.axisY), 0) + + childBoxes.reduce((decHeight, box) => Math.max(decHeight, box.height - box.axisY), 0); + this.setBBox({ width, height, axisY: verticalCenter }, { axisX1: true, axisX2: true }); - let offset = 0; - childBoxes.forEach(box => { - box.offsetX = offset; - box.offsetY = this.getBBox().axisY - box.axisY; - offset += box.width + spacing; - }); + let offset = 0; + childBoxes.forEach(box => { + box.offsetX = offset; + box.offsetY = this.getBBox().axisY - box.axisY; + offset += box.width + spacing; + }); - this.setState({ - childTransforms: this.updateChildTransforms(childBoxes), - connectorPaths: withConnectors ? this.updateConnectorPaths(childBoxes) : '' - }, resolve); + this.setStateAsync({ + childTransforms: this.updateChildTransforms(childBoxes), + connectorPaths: withConnectors ? this.updateConnectorPaths(childBoxes) : '' }); } diff --git a/src/components/SVG/Image.js b/src/components/SVG/Image.js index 4caf920..e93179f 100644 --- a/src/components/SVG/Image.js +++ b/src/components/SVG/Image.js @@ -37,14 +37,12 @@ class Image extends Base { } reflow() { - return new Promise(resolve => { - const { padding } = this.props; - const box = this.contained.getBBox(); + const { padding } = this.props; + const box = this.contained.getBBox(); - this.setState({ - width: Math.round(box.width + 2 * padding), - height: Math.round(box.height + 2 * padding) - }, resolve); + return this.setStateAsync({ + width: Math.round(box.width + 2 * padding), + height: Math.round(box.height + 2 * padding) }); } diff --git a/src/components/SVG/Loop.js b/src/components/SVG/Loop.js index 6ad5a9f..d228402 100644 --- a/src/components/SVG/Loop.js +++ b/src/components/SVG/Loop.js @@ -73,37 +73,35 @@ class Loop extends Base { } reflow() { - return new Promise(resolve => { - const { skip, repeat, greedy } = this.props; - const box = this.contained.getBBox(); - const labelBox = this.label ? this.label.getBBox() : { width: 0, height: 0 }; + const { skip, repeat, greedy } = this.props; + const box = this.contained.getBBox(); + const labelBox = this.label ? this.label.getBBox() : { width: 0, height: 0 }; - let height = box.height + labelBox.height; - if (skip) { - height += 10; - } - if (repeat) { - height += 10; - } + let height = box.height + labelBox.height; + if (skip) { + height += 10; + } + if (repeat) { + height += 10; + } - this.setBBox({ - width: box.width + this.contentOffset.x * 2, - height, - axisY: box.axisY + this.contentOffset.y, - axisX1: box.axisX1 + this.contentOffset.x, - axisX2: box.axisX2 + this.contentOffset.x - }); + this.setBBox({ + width: box.width + this.contentOffset.x * 2, + height, + axisY: box.axisY + this.contentOffset.y, + axisX1: box.axisX1 + this.contentOffset.x, + axisX2: box.axisX2 + this.contentOffset.x + }); - box.offsetX = this.contentOffset.x; - box.offsetY = this.contentOffset.y; + box.offsetX = this.contentOffset.x; + box.offsetY = this.contentOffset.y; - this.setState({ - labelTransform: `translate(${ this.getBBox().width - labelBox.width - 10 } ${ this.getBBox().height + 2 })`, - loopPaths: [ - skip && skipPath(box, greedy), - repeat && repeatPath(box, greedy) - ].filter(Boolean).join('') - }, resolve); + return this.setStateAsync({ + labelTransform: `translate(${ this.getBBox().width - labelBox.width - 10 } ${ this.getBBox().height + 2 })`, + loopPaths: [ + skip && skipPath(box, greedy), + repeat && repeatPath(box, greedy) + ].filter(Boolean).join('') }); } diff --git a/src/components/SVG/Pin.js b/src/components/SVG/Pin.js index 8f7ab80..0c39c56 100644 --- a/src/components/SVG/Pin.js +++ b/src/components/SVG/Pin.js @@ -11,28 +11,21 @@ class Pin extends Base { } reflow() { - return new Promise(resolve => { - const { radius } = this.props; + const { radius } = this.props; - this.setBBox({ - width: radius * 2, - height: radius * 2 - }); - - this.setState({ - transform: `translate(${ radius } ${ radius })` - }, resolve); + return this.setBBox({ + width: radius * 2, + height: radius * 2 }); } render() { const { radius } = this.props; - const { transform } = this.state || {}; const circleProps = { r: radius, style: style.pin, - transform + transform: `translate(${ radius } ${ radius })` }; return ; diff --git a/src/components/SVG/Text.js b/src/components/SVG/Text.js index cb98eda..ef70626 100644 --- a/src/components/SVG/Text.js +++ b/src/components/SVG/Text.js @@ -7,17 +7,15 @@ import style from './style'; /** @extends React.PureComponent */ class Text extends Base { reflow() { - return new Promise(resolve => { - const box = this.text.getBBox(); + const box = this.text.getBBox(); - this.setBBox({ - width: box.width, - height: box.height - }); + this.setBBox({ + width: box.width, + height: box.height + }); - this.setState({ - transform: `translate(${-box.x} ${-box.y})` - }, resolve); + return this.setStateAsync({ + transform: `translate(${-box.x} ${-box.y})` }); } diff --git a/src/components/SVG/VerticalLayout.js b/src/components/SVG/VerticalLayout.js index a59890f..3150afa 100644 --- a/src/components/SVG/VerticalLayout.js +++ b/src/components/SVG/VerticalLayout.js @@ -88,31 +88,29 @@ class VerticalLayout extends Base { return Promise.resolve(); } - return new Promise(resolve => { - const { spacing, withConnectors } = this.props; + const { spacing, withConnectors } = this.props; - const childBoxes = this.children.map(child => child.getBBox()); - const horizontalCenter = childBoxes.reduce((center, box) => Math.max(center, box.width / 2), 0); - const margin = withConnectors ? connectorMargin : 0; - const width = childBoxes.reduce((width, box) => Math.max(width, box.width), 0) + 2 * margin; - const height = childBoxes.reduce((height, box) => height + box.height, 0) + (childBoxes.length - 1) * spacing; - this.setBBox({ width, height }, { axisY: true, axisX1: true, axisX2: true }); + const childBoxes = this.children.map(child => child.getBBox()); + const horizontalCenter = childBoxes.reduce((center, box) => Math.max(center, box.width / 2), 0); + const margin = withConnectors ? connectorMargin : 0; + const width = childBoxes.reduce((width, box) => Math.max(width, box.width), 0) + 2 * margin; + const height = childBoxes.reduce((height, box) => height + box.height, 0) + (childBoxes.length - 1) * spacing; + this.setBBox({ width, height }, { axisY: true, axisX1: true, axisX2: true }); - let offset = 0; - childBoxes.forEach(box => { - box.offsetX = horizontalCenter - box.width / 2 + margin; - box.offsetY = offset; - offset += spacing + box.height; - }); + let offset = 0; + childBoxes.forEach(box => { + box.offsetX = horizontalCenter - box.width / 2 + margin; + box.offsetY = offset; + offset += spacing + box.height; + }); - this.setState({ - childTransforms: this.updateChildTransforms(childBoxes), - connectorPaths: withConnectors ? [ - ...childBoxes.map(box => this.makeCurve(box)), - this.makeSide(childBoxes[0]), - this.makeSide(childBoxes[childBoxes.length - 1]) - ].join('') : '' - }, resolve); + return this.setStateAsync({ + childTransforms: this.updateChildTransforms(childBoxes), + connectorPaths: withConnectors ? [ + ...childBoxes.map(box => this.makeCurve(box)), + this.makeSide(childBoxes[0]), + this.makeSide(childBoxes[childBoxes.length - 1]) + ].join('') : '' }); }