Skip to content

Instantly share code, notes, and snippets.

@nautilytics
Created May 15, 2020 01:14
Show Gist options
  • Save nautilytics/fca43aaa8c920bfe49507f591c632e08 to your computer and use it in GitHub Desktop.
Save nautilytics/fca43aaa8c920bfe49507f591c632e08 to your computer and use it in GitHub Desktop.
An example of using an SVG mask to effectively handle mousing over an area chart
import React from 'react';
import {area as d3_area, curveBasis} from 'd3-shape';
const AreaChart = ({data, xScale, yScale, selectedItem, setSelectedItem, barWidth = 0}) => {
// Set up an area chart generator
const area = d3_area()
.curve(curveBasis)
.x(d => d.x)
.y0(d => d.y0)
.y1(d => d.y1);
// Handle mouse over, i.e. which <rect/> element the user moused over
const onMouseOver = item => () => setSelectedItem(item);
return (
<g className="area-chart">
<defs>
<mask
id='mask-for-area-chart'
maskUnits="userSpaceOnUse"
maskContentUnits="userSpaceOnUse"
>
<path className="area-mask"
d={area(
data.map(f => {
return {
x: xScale(f.x),
y0: yScale(0),
y1: yScale(f.y)
};
})
)}
/>
</mask>
</defs>
<rect
mask='url(#mask-for-area-chart)'
className="area-chart"
width={xScale.range()[1]}
height={yScale.range()[0]}
/>
<g className="hover-section">
{data.map((f, i) => {
return (
<rect
key={`hover-section-for-${i}`}
onMouseOver={onMouseOver(f)}
x={xScale(f.x) - barWidth}
width={barWidth}
height={yScale.range()[0]}
/>
);
})}
</g>
{
selectedItem && <rect
mask='url(#mask-for-area-chart)'
className="area-chart selected"
x={xScale(selectedItem.x)}
height={yScale.range()[0]}
width={barWidth}
/>
}
</g>
)
};
export default AreaChart;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment