I am trying to incorporate d3-lasso into a d3 project with React, and I see a lot of people are having similar problems to me, but I can't find a solution that works. To remove any complicating factors, I'm trying to simply get this example to work in React. I've tried several permutations with Stack and Github solutions, but I always get Attempted import error: 'lasso' is not exported from 'd3' (imported as 'd3').
Here is my code:
import React, { useRef } from 'react'
import * as d3 from 'd3'
import ReactSlider from 'react-slider'
import * as lasso from 'd3-lasso'
// import { lasso } from 'd3-lasso' also doesn’t work
// import lasso from 'd3-lasso' also doesn't work
import './styles.css'
import './LineChart.css'
const ClusterViewer = () => {
const d3Chart = useRef(null)
const createChart = () => {
const data = [['Arsenal', -0.0032967741593940836, 0.30399753945657115], ['Chelsea', 0.2752159801936051, -0.0389675484210763], ['Liverpool', -0.005096951348655329, 0.026678627680541075], ['Manchester City', -0.004715381791104284, -0.12338379196523988], ['Manchester United', 0.06877966010653305, -0.0850615090351779], ['Tottenham', -0.3379518099485709, -0.09933664174939877]]
const colours = d3.scaleOrdinal()
.domain(data)
.range(['#F8B195', '#F67280', '#C06C84', '#6C5B7B', '#355C7D', '#2A363B'])
const canvasW = 675
const canvasH = 400
const w = 365
const h = 365
const xPadding = 30
const yPadding = 20
const padding = 10
const xScale = d3.scaleLinear()
.range([xPadding, w - padding])
.domain([-1, 1])
const yScale = d3.scaleLinear()
.range([h - yPadding, padding])
.domain([-1, 1])
const svg = d3.select('body')
.append('svg')
.attr('width', canvasW)
.attr('height', canvasH)
const circles = svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('r', 7)
.attr('cx', d => xScale(d[1]))
.attr('cy', d => yScale(d[2]))
.attr('fill', d => {
let result = null
if (data.indexOf(d) >= 0) {
result = colours(d)
} else {
result = 'white'
}
return result
})
const graphLasso = d3.lasso()
.closePathDistance(75)
.closePathSelect(true)
.targetArea(svg)
.items(circles)
.on('start', lasso_start)
.on('draw', lasso_draw)
.on('end', lasso_end)
function lasso_start() {
graphLasso.items()
.attr('r', 7)
.classed('not_possible', true)
.classed('selected', false)
}
function lasso_draw() {
graphLasso.possibleItems()
.classed('not_possible', false)
.classed('possible', true)
graphLasso.notPossibleItems()
.classed('not_possible', true)
.classed('possible', false)
}
function lasso_end() {
graphLasso.items()
.classed('not_possible', false)
.classed('possible', false)
graphLasso.selectedItems()
.classed('selected', true)
.attr('r', 7)
graphLasso.notSelectedItems()
.attr('r', 3.5)
}
const legend = svg.selectAll('.legend')
.data(colours.domain())
.enter()
.append('g')
.attr('class', 'legend')
.attr('transform', (d, i) => `translate(0,${i * 29})`)
legend.append('rect')
.attr('x', canvasW - 184)
.attr('y', 11)
.attr('width', 18)
.attr('height', 18)
.style('fill', colours)
legend.append('text')
.attr('x', canvasW - 194)
.attr('y', 20)
.attr('dy', '.35em')
.style('text-anchor', 'end')
.text(d => d[0])
svg.call(graphLasso)
}
// ...
return (
<div>
<h1>
Cluster Viewer
</h1>
<div>
<script src="https://d3js.org/d3.v4.min.js" />
<svg ref={d3Chart} />
</div>
</div>
)
}
export default ClusterViewer