{
const width = 500
const height = 300
const margin = {
left: 0,
top: 0,
right: 0,
bottom: 0
}
const stock = vx.appleStock.slice(800);
const formatDate = d3.timeFormat("%b %d, '%y");
const xStock = d => new Date(d.date);
const yStock = d => d.close;
const bisectDate = d3.bisector(d => new Date(d.date)).left;
class Area extends React.Component {
constructor(props) {
super(props);
this.handleTooltip = this.handleTooltip.bind(this);
}
handleTooltip({ event, data, xStock, xScale, yScale }) {
const { showTooltip } = this.props;
const { x } = vx.localPoint(event);
const x0 = xScale.invert(x);
const index = bisectDate(data, x0, 1);
const d0 = data[index - 1];
const d1 = data[index];
let d = d0;
if (d1 && d1.date) {
d = x0 - xStock(d0.date) > xStock(d1.date) - x0 ? d1 : d0;
}
showTooltip({
tooltipData: d,
tooltipLeft: x,
tooltipTop: yScale(d.close)
});
}
render() {
const {
width,
height,
margin,
showTooltip,
hideTooltip,
tooltipData,
tooltipTop,
tooltipLeft,
events
} = this.props;
if (width < 10) return null;
// bounds
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;
// scales
const xScale = vx.scaleTime({
range: [0, xMax],
domain: d3.extent(stock, xStock)
});
const yScale = vx.scaleLinear({
range: [yMax, 0],
domain: [0, d3.max(stock, yStock) + yMax / 3],
nice: true
});
return React.createElement(
"div",
null,
React.createElement(
"svg",
{ ref: s => this.svg = s, width: width, height: height },
React.createElement("rect", {
x: 0,
y: 0,
width: width,
height: height,
fill: "#32deaa",
rx: 14
}),
React.createElement(
"defs",
null,
React.createElement(
"linearGradient",
{
id: "gradient",
x1: "0%",
y1: "0%",
x2: "0%",
y2: "100%"
},
React.createElement("stop", {
offset: "0%",
stopColor: "#FFFFFF",
stopOpacity: 1
}),
React.createElement("stop", {
offset: "100%",
stopColor: "#FFFFFF",
stopOpacity: 0.2
})
)
),
React.createElement(vx.Group, {
transform: `translate(${margin.left}, ${margin.top})`},
React.createElement(vx.GridRows, {
lineStyle: { pointerEvents: 'none' },
scale: yScale,
width: xMax,
strokeDasharray: "2,2",
stroke: "rgba(255,255,255,0.3)"
}),
React.createElement(vx.GridColumns, {
lineStyle: { pointerEvents: 'none' },
scale: xScale,
height: yMax,
strokeDasharray: "2,2",
stroke: "rgba(255,255,255,0.3)"
}),
React.createElement(vx.AreaClosed, {
data: stock,
xScale: xScale,
yScale: yScale,
x: xStock,
y: yStock,
strokeWidth: 1,
stroke: 'url(#gradient)',
fill: 'url(#gradient)',
curve: vx.curveMonotoneX
}),
React.createElement(vx.Bar, {
x: 0,
y: 0,
width: width,
height: height,
fill: "transparent",
rx: 14,
data: stock,
onTouchStart: data => event => this.handleTooltip({
event,
data,
xStock,
xScale,
yScale
}),
onTouchMove: data => event => this.handleTooltip({
event,
data,
xStock,
xScale,
yScale
}),
onMouseMove: data => event => this.handleTooltip({
event,
data,
xStock,
xScale,
yScale
}),
onMouseLeave: data => event => hideTooltip()
})
),
tooltipData && React.createElement(
"g",
null,
React.createElement(vx.Line, {
from: { x: tooltipLeft, y: 0 },
to: { x: tooltipLeft, y: yMax },
stroke: "rgba(92, 119, 235, 1.000)",
strokeWidth: 2,
style: { pointerEvents: 'none' },
strokeDasharray: "2,2"
}),
React.createElement("circle", {
cx: tooltipLeft,
cy: tooltipTop + 1,
r: 4,
fill: "black",
fillOpacity: 0.1,
stroke: "black",
strokeOpacity: 0.1,
strokeWidth: 2,
style: { pointerEvents: 'none' }
}),
React.createElement("circle", {
cx: tooltipLeft,
cy: tooltipTop,
r: 4,
fill: "rgba(92, 119, 235, 1.000)",
stroke: "white",
strokeWidth: 2,
style: { pointerEvents: 'none' }
})
)
),
tooltipData && React.createElement(
"div",
null,
React.createElement(
vx.Tooltip,
{
top: tooltipTop - 12,
left: tooltipLeft + 12,
style: {
backgroundColor: 'rgba(92, 119, 235, 1.000)',
color: 'white'
}
},
`$${yStock(tooltipData)}`
),
React.createElement(
vx.Tooltip,
{
top: yMax - 14,
left: tooltipLeft,
style: {
transform: 'translateX(-50%)'
}
},
formatDate(xStock(tooltipData))
)
)
);
}
}
ReactDOM.render(
React.createElement(vx.withTooltip(Area), {width: width, height: height, margin: margin}),
document.getElementById("chart")
)
}