Browse Source

feature(map): built own map with d3

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
169f0525af
  1. 30
      app/app.global.scss
  2. 22
      app/components/Network/CanvasNetworkGraph.css
  3. 259
      app/components/Network/CanvasNetworkGraph.js
  4. 10
      app/components/Network/NetworkGraph.js
  5. 5
      app/components/Network/NetworkGraph.scss
  6. 3
      app/routes/network/components/Network.js
  7. 2
      package.json
  8. BIN
      resources/bin/darwin/lnd
  9. 279
      yarn.lock

30
app/app.global.scss

@ -163,3 +163,33 @@ body {
padding: 10px 5px;
font-size: 15px;
}
// network
@keyframes dash {
to {
stroke-dashoffset: 1000;
}
}
// each node in the map
.network-node {
}
// each channel in the map
.network-link {
opacity: 0.6;
}
.active-peer {
fill: #5589F3;
}
.active-channel {
opacity: 1;
stroke: #88D4A2;
stroke-width: 15;
stroke-dasharray: 100;
animation: dash 2.5s infinite linear;
}

22
app/components/Network/CanvasNetworkGraph.css

@ -0,0 +1,22 @@
.network {
width: 100%;
height: 100vh;
animation: fadein 0.5s;
animation-timing-function:linear;
animation-fill-mode: forwards;
animation-iteration-count: 1;
}
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: black ;
stroke-width: 0px;
}
.active-peer {
fill: pink;
}

259
app/components/Network/CanvasNetworkGraph.js

@ -0,0 +1,259 @@
import { findDOMNode } from 'react-dom'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import * as d3 from 'd3'
// import './CanvasNetworkGraph.css'
function generateSimulationData(nodes, edges) {
const resNodes = nodes.map(node => Object.assign(node, { id: node.pub_key }))
const resEdges = edges.map(node => Object.assign(node, { source: node.node1_pub, target: node.node2_pub }))
return {
nodes: resNodes,
links: resEdges
}
}
class CanvasNetworkGraph extends Component {
constructor(props) {
super(props)
this.state = {
width: 800,
height: 800,
simulation: {},
simulationData: {
nodes: [],
links: []
}
}
this._startSimulation = this._startSimulation.bind(this)
this._zoomActions = this._zoomActions.bind(this)
this._ticked = this._ticked.bind(this)
this._restart = this._restart.bind(this)
}
componentDidMount() {
// wait for the svg to me in the DOM before we start the simulation
const svgInterval = setInterval(() => {
if (document.getElementById('map')) {
this._startSimulation()
clearInterval(svgInterval)
}
}, 1000)
}
componentDidUpdate(prevProps, prevState) {
const {
network: { nodes, edges },
selectedPeerPubkeys,
selectedChannelIds,
currentRouteChanIds
} = this.props
const prevNodes = prevProps.network.nodes
const prevEdges = prevProps.network.edges
// update the simulationData only if the nodes or edges have changed
if (prevNodes.length !== nodes.length || prevEdges.length !== edges.length) {
this.setState({
simulationData: generateSimulationData(nodes, edges)
})
}
if (prevProps.selectedPeerPubkeys.length !== selectedPeerPubkeys.length) {
this._updateSelectedPeers()
}
if (prevProps.selectedChannelIds.length !== selectedChannelIds.length) {
this._updateSelectedChannels()
}
if (prevProps.currentRouteChanIds.length !== currentRouteChanIds.length) {
this._renderSelectedRoute()
}
}
componentWillUnmount() {
d3.select('#map')
.selectAll('*')
.remove()
}
_updateSelectedPeers() {
const { selectedPeerPubkeys } = this.props
// remove active class
d3.selectAll('.active-peer')
.each(function(d) {
d3.select(this).classed('active-peer', false)
})
// add active class to all selected peers
selectedPeerPubkeys.forEach(pubkey => {
const node = d3.select(`#node-${pubkey}`).classed('active-peer', true)
})
}
_updateSelectedChannels() {
const { selectedChannelIds } = this.props
// remove active class
d3.selectAll('.active-channel')
.each(function(d) {
d3.select(this).classed('active-channel', false)
})
// add active class to all selected peers
selectedChannelIds.forEach(chanid => {
const node = d3.select(`#link-${chanid}`).classed('active-channel', true)
})
}
_renderSelectedRoute() {
const { currentRouteChanIds } = this.props
// remove all route animations before rendering new ones
d3.selectAll('.animated-route-circle')
.each(function(d) {
d3.select(this).remove()
})
currentRouteChanIds.forEach(chanId => {
const link = document.getElementById(`link-${chanId}`)
if (!link) { return }
const x1 = link.x1.baseVal.value
const x2 = link.x2.baseVal.value
const y1 = link.y1.baseVal.value
const y2 = link.y2.baseVal.value
// create the circle that represent btc traveling through a channel
const circle = this.g
.append('circle')
.attr('id', `circle-${chanId}`)
.attr('class', 'animated-route-circle')
.attr('r', 50)
.attr('cx', x1)
.attr('cy', y1)
.attr('fill', '#FFDC53')
// we want the animation to repeat back and forth, this function executes that visually
const repeat = () => {
d3.select(`#circle-${chanId}`)
.transition()
.attr('cx', x2 )
.attr('cy', y2 )
.duration(1000)
.transition()
.duration(1000)
.attr('cx', x1)
.attr('cy', y1)
.on('end', repeat)
}
// call repeat to animate the circle
repeat()
})
}
_startSimulation() {
const { simulationData: { nodes, links } } = this.state
// grab the svg el along with the attributes
const svg = d3.select('#map'),
width = +svg.attr('width'),
height = +svg.attr('height')
this.g = svg.append('g').attr('transform', `translate(${width / 2},${height / 2})`)
this.link = this.g.append('g').attr('stroke', 'white').attr('stroke-width', 1.5).selectAll('.link')
this.node = this.g.append('g').attr('stroke', 'silver').attr('stroke-width', 1.5).selectAll('.node')
this.simulation = d3.forceSimulation(nodes)
.force('charge', d3.forceManyBody().strength(-750))
.force('link', d3.forceLink(links).id(d => d.pub_key).distance(500))
.force('collide', d3.forceCollide(300))
.on('tick', this._ticked)
// zoom
const zoom_handler = d3.zoom().on('zoom', this._zoomActions)
zoom_handler(svg)
this._restart()
}
_zoomActions() {
this.g.attr('transform', d3.event.transform)
}
_ticked() {
this.node.attr('cx', d => d.x)
.attr('cy', d => d.y)
this.link.attr('x1', d => d.source.x)
.attr('y1', d => d.source.y)
.attr('x2', d => d.target.x)
.attr('y2', d => d.target.y)
}
_restart() {
const { identity_pubkey } = this.props
const {
simulation,
simulationData: { nodes, links }
} = this.state
// Apply the general update pattern to the nodes.
this.node = this.node.data(nodes, d => d.pub_key)
this.node.exit().remove()
this.node = this.node.enter()
.append('circle')
.attr('stroke', d => 'silver')
.attr('fill', d => d.pub_key === identity_pubkey ? '#FFF' : '#353535')
.attr('r', d => 100)
.attr('id', d => `node-${d.pub_key}`)
.attr('class', 'network-node')
.merge(this.node)
// Apply the general update pattern to the links.
this.link = this.link.data(links, d => `${d.source.id}-${d.target.id}`)
this.link.exit().remove()
this.link =
this.link.enter()
.append('line')
.attr('id', d => `link-${d.channel_id}`)
.attr('class','network-link')
.merge(this.link)
// Update and restart the simulation.
this.simulation.nodes(nodes)
this.simulation.force('link').links(links)
this.simulation.restart()
}
render() {
const { simulationData } = this.state
const {
network: { nodes, edges, selectedChannel, networkLoading },
selectedPeerPubkeys,
selectedChannelIds,
currentRouteChanIds,
identity_pubkey
} = this.props
return (
<div id='mapContainer' style={{ display: 'inline' }}>
<svg width='800' height='800' id='map'></svg>
</div>
)
}
}
CanvasNetworkGraph.propTypes = {
network: PropTypes.object.isRequired
}
export default CanvasNetworkGraph

10
app/components/Network/NetworkGraph.js

@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
import { ForceGraph, ForceGraphNode, ForceGraphLink } from 'react-vis-force'
import { FaCircle } from 'react-icons/lib/fa'
import Isvg from 'react-inlinesvg'
import LoadingBolt from 'components/LoadingBolt'
import bitcoinIcon from 'icons/skinny_bitcoin.svg'
import styles from './NetworkGraph.scss'
@ -31,8 +32,7 @@ class NetworkGraph extends Component {
identity_pubkey
} = this.props
if (!ready || networkLoading) {
console.log('hi!')
if ((!nodes.length || !edges.length) || networkLoading) {
return (
<section className={styles.network}>
<div className={styles.networkLoading}>
@ -57,9 +57,13 @@ class NetworkGraph extends Component {
}
labelAttr='label'
opacityFactor={1}
highlightDependencies
zoomOptions={{ minScale: 0.1, maxScale: 5, scale: 0.2 }}
zoom
highlightDependencies
ref={(el) => {
console.log('el: ', el)
this.fg = el
}}
>
{
nodes.map(node =>

5
app/components/Network/NetworkGraph.scss

@ -22,6 +22,11 @@
animation-timing-function:linear;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
// visibility: hidden;
&.active {
// visibility: visible;
}
h1 {
font-size: 22px;

3
app/routes/network/components/Network.js

@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import { InteractiveForceGraph, ForceGraphNode, ForceGraphLink } from 'react-vis-force'
import CanvasNetworkGraph from 'components/Network/CanvasNetworkGraph'
import NetworkGraph from 'components/Network/NetworkGraph'
import PeersList from 'components/Network/PeersList'
import ChannelsList from 'components/Network/ChannelsList'
@ -85,7 +86,7 @@ class Network extends Component {
return (
<div className={styles.container}>
<NetworkGraph
<CanvasNetworkGraph
className={styles.network}
network={network}
identity_pubkey={identity_pubkey}

2
package.json

@ -193,6 +193,7 @@
"bitcoinjs-lib": "^3.2.0",
"bitcore-lib": "^0.14.0",
"copy-to-clipboard": "^3.0.8",
"d3": "^4.12.0",
"devtron": "^1.4.0",
"electron-debug": "^1.2.0",
"font-awesome": "^4.7.0",
@ -211,6 +212,7 @@
"react-router": "^4.1.1",
"react-router-dom": "^4.1.1",
"react-router-redux": "^5.0.0-alpha.6",
"react-vis": "^1.8.0",
"react-vis-force": "^0.3.1",
"redux": "^3.7.1",
"redux-electron-ipc": "^1.1.10",

BIN
resources/bin/darwin/lnd

Binary file not shown.

279
yarn.lock

@ -2082,6 +2082,10 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
commander@2:
version "2.12.2"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
commander@2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.6.0.tgz#9df7e52fb2a0cb0fb89058ee80c3104225f37e1d"
@ -2282,6 +2286,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.3, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
create-react-class@^15.5.2:
version "15.6.2"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
object-assign "^4.1.1"
create-react-class@^15.5.3:
version "15.5.3"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.5.3.tgz#fb0f7cae79339e9a179e194ef466efa3923820fe"
@ -2528,15 +2540,69 @@ currently-unhandled@^0.4.1:
dependencies:
array-find-index "^1.0.1"
d3-collection@1:
d3-array@1, d3-array@1.2.1, d3-array@^1.1.1, d3-array@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc"
d3-axis@1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.8.tgz#31a705a0b535e65759de14173a31933137f18efa"
d3-brush@1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.4.tgz#00c2f238019f24f6c0a194a26d41a1530ffe7bc4"
dependencies:
d3-dispatch "1"
d3-drag "1"
d3-interpolate "1"
d3-selection "1"
d3-transition "1"
d3-chord@1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.4.tgz#7dec4f0ba886f713fe111c45f763414f6f74ca2c"
dependencies:
d3-array "1"
d3-path "1"
d3-collection@1, d3-collection@1.0.4, d3-collection@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.4.tgz#342dfd12837c90974f33f1cc0a785aea570dcdc2"
d3-dispatch@1:
d3-color@1, d3-color@1.0.3, d3-color@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b"
d3-contour@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.1.2.tgz#21f5456fcf57645922d69a27a58e782c91f842b3"
dependencies:
d3-array "^1.1.1"
d3-dispatch@1, d3-dispatch@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.3.tgz#46e1491eaa9b58c358fce5be4e8bed626e7871f8"
d3-force@^1.0.2:
d3-drag@1, d3-drag@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.2.1.tgz#df8dd4c502fb490fc7462046a8ad98a5c479282d"
dependencies:
d3-dispatch "1"
d3-selection "1"
d3-dsv@1, d3-dsv@1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.8.tgz#907e240d57b386618dc56468bacfe76bf19764ae"
dependencies:
commander "2"
iconv-lite "0.4"
rw "1"
d3-ease@1, d3-ease@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e"
d3-force@1.1.0, d3-force@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.1.0.tgz#cebf3c694f1078fcc3d4daf8e567b2fbd70d4ea3"
dependencies:
@ -2545,14 +2611,165 @@ d3-force@^1.0.2:
d3-quadtree "1"
d3-timer "1"
d3-quadtree@1:
d3-format@1, d3-format@1.2.1, d3-format@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.2.1.tgz#4e19ecdb081a341dafaf5f555ee956bcfdbf167f"
d3-geo@1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.9.0.tgz#15c7d7a8ea9346e59ed150dc7b1f7f95479056e9"
dependencies:
d3-array "1"
d3-geo@^1.6.4:
version "1.9.1"
resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.9.1.tgz#157e3b0f917379d0f73bebfff3be537f49fa7356"
dependencies:
d3-array "1"
d3-hierarchy@1.1.5, d3-hierarchy@^1.1.4:
version "1.1.5"
resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz#a1c845c42f84a206bcf1c01c01098ea4ddaa7a26"
d3-interpolate@1, d3-interpolate@1.1.6, d3-interpolate@^1.1.4:
version "1.1.6"
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6"
dependencies:
d3-color "1"
d3-path@1, d3-path@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764"
d3-polygon@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.3.tgz#16888e9026460933f2b179652ad378224d382c62"
d3-quadtree@1, d3-quadtree@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.3.tgz#ac7987e3e23fe805a990f28e1b50d38fcb822438"
d3-timer@1:
d3-queue@3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.7.tgz#c93a2e54b417c0959129d7d73f6cf7d4292e7618"
d3-random@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.0.tgz#6642e506c6fa3a648595d2b2469788a8d12529d3"
d3-request@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/d3-request/-/d3-request-1.0.6.tgz#a1044a9ef4ec28c824171c9379fae6d79474b19f"
dependencies:
d3-collection "1"
d3-dispatch "1"
d3-dsv "1"
xmlhttprequest "1"
d3-sankey@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/d3-sankey/-/d3-sankey-0.7.1.tgz#d229832268fc69a7fec84803e96c2256a614c521"
dependencies:
d3-array "1"
d3-collection "1"
d3-shape "^1.2.0"
d3-scale@1.0.7, d3-scale@^1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.7.tgz#fa90324b3ea8a776422bd0472afab0b252a0945d"
dependencies:
d3-array "^1.2.0"
d3-collection "1"
d3-color "1"
d3-format "1"
d3-interpolate "1"
d3-time "1"
d3-time-format "2"
d3-selection@1, d3-selection@1.2.0, d3-selection@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.2.0.tgz#1b8ec1c7cedadfb691f2ba20a4a3cfbeb71bbc88"
d3-shape@1.2.0, d3-shape@^1.1.0, d3-shape@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777"
dependencies:
d3-path "1"
d3-time-format@2, d3-time-format@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.1.1.tgz#85b7cdfbc9ffca187f14d3c456ffda268081bb31"
dependencies:
d3-time "1"
d3-time@1, d3-time@1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.8.tgz#dbd2d6007bf416fe67a76d17947b784bffea1e84"
d3-timer@1, d3-timer@1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.7.tgz#df9650ca587f6c96607ff4e60cc38229e8dd8531"
d3-transition@1, d3-transition@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.1.1.tgz#d8ef89c3b848735b060e54a39b32aaebaa421039"
dependencies:
d3-color "1"
d3-dispatch "1"
d3-ease "1"
d3-interpolate "1"
d3-selection "^1.1.0"
d3-timer "1"
d3-voronoi@1.1.2, d3-voronoi@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c"
d3-zoom@1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.7.1.tgz#02f43b3c3e2db54f364582d7e4a236ccc5506b63"
dependencies:
d3-dispatch "1"
d3-drag "1"
d3-interpolate "1"
d3-selection "1"
d3-transition "1"
d3@^4.12.0:
version "4.12.0"
resolved "https://registry.yarnpkg.com/d3/-/d3-4.12.0.tgz#75eccb39ea40f6018de8cfa2752905bee7daa46f"
dependencies:
d3-array "1.2.1"
d3-axis "1.0.8"
d3-brush "1.0.4"
d3-chord "1.0.4"
d3-collection "1.0.4"
d3-color "1.0.3"
d3-dispatch "1.0.3"
d3-drag "1.2.1"
d3-dsv "1.0.8"
d3-ease "1.0.3"
d3-force "1.1.0"
d3-format "1.2.1"
d3-geo "1.9.0"
d3-hierarchy "1.1.5"
d3-interpolate "1.1.6"
d3-path "1.0.5"
d3-polygon "1.0.3"
d3-quadtree "1.0.3"
d3-queue "3.0.7"
d3-random "1.1.0"
d3-request "1.0.6"
d3-scale "1.0.7"
d3-selection "1.2.0"
d3-shape "1.2.0"
d3-time "1.0.8"
d3-time-format "2.1.1"
d3-timer "1.0.7"
d3-transition "1.1.1"
d3-voronoi "1.1.2"
d3-zoom "1.7.1"
d@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
@ -4068,7 +4285,7 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, gl
once "^1.3.0"
path-is-absolute "^1.0.0"
global@^4.3.0:
global@^4.3.0, global@^4.3.1:
version "4.3.2"
resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
dependencies:
@ -4460,6 +4677,10 @@ humanize-plus@^1.8.1:
version "1.8.2"
resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030"
iconv-lite@0.4:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
iconv-lite@0.4.13:
version "0.4.13"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
@ -6527,6 +6748,10 @@ performance-now@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
pify@^2.0.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@ -7062,6 +7287,12 @@ querystringify@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb"
raf@^3.1.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
dependencies:
performance-now "^2.1.0"
randomatic@^1.1.3:
version "1.1.7"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"
@ -7143,6 +7374,15 @@ react-moment@^0.6.0:
version "0.6.1"
resolved "https://registry.yarnpkg.com/react-moment/-/react-moment-0.6.1.tgz#f32063c4d5e94416334fd61aa4299cddd380e55f"
react-motion@^0.4.8:
version "0.4.8"
resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.4.8.tgz#23bb2dd27c2d8e00d229e45572d105efcf40a35e"
dependencies:
create-react-class "^15.5.2"
performance-now "^0.2.0"
prop-types "^15.5.8"
raf "^3.1.0"
react-proxy@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a"
@ -7224,6 +7464,27 @@ react-vis-force@^0.3.1:
lodash.reduce "^4.6.0"
prop-types "^15.5.10"
react-vis@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/react-vis/-/react-vis-1.8.0.tgz#e78d04dd82fcfe57145ff7378b6d2c765932834b"
dependencies:
d3-array "^1.2.0"
d3-collection "^1.0.3"
d3-color "^1.0.3"
d3-contour "^1.1.0"
d3-format "^1.2.0"
d3-geo "^1.6.4"
d3-hierarchy "^1.1.4"
d3-interpolate "^1.1.4"
d3-sankey "^0.7.1"
d3-scale "^1.0.5"
d3-shape "^1.1.0"
d3-voronoi "^1.1.2"
deep-equal "^1.0.1"
global "^4.3.1"
prop-types "^15.5.8"
react-motion "^0.4.8"
react@^15.6.1:
version "15.6.1"
resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
@ -7594,6 +7855,10 @@ run-async@^2.2.0:
dependencies:
is-promise "^2.1.0"
rw@1:
version "1.3.3"
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
rx-lite-aggregates@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
@ -9180,7 +9445,7 @@ xmldom@0.1.x:
version "0.1.27"
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
xmlhttprequest@*:
xmlhttprequest@*, xmlhttprequest@1:
version "1.8.0"
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"

Loading…
Cancel
Save