import React from 'react'
import ReactApexChart from 'react-apexcharts'
import ApexCharts from 'apexcharts'
import './styles.css'
function signal() {
var out = []
for (var i = 0; i < 40; i++) {
var v = 50 + 22 * Math.sin(i / 4.0) + 9 * Math.sin(i / 1.4) + i * 0.4
out.push([i, Math.round(v)])
}
return out
}
const ApexChart = () => {
const [state, setState] = React.useState({
series: [{ name: 'Signal', data: signal() }],
options: {
chart: {
id: 'signal',
type: 'line',
height: 380,
fontFamily: 'Helvetica, Arial, sans-serif',
animations: { enabled: false },
ink: { enabled: true, palette: true },
history: { enabled: true },
toolbar: { show: false },
zoom: { enabled: false },
},
stroke: { width: 2, curve: 'smooth' },
colors: ['#0EA5E9'],
title: { text: 'Signal (drag the callouts)', align: 'left' },
xaxis: { type: 'numeric', title: { text: 'Sample' } },
yaxis: { title: { text: 'Value' } },
annotations: {
points: [
{
x: 6,
y: 74,
id: 'peak',
marker: {
size: 7,
fillColor: '#fff',
strokeColor: '#0EA5E9',
strokeWidth: 3,
},
label: {
text: 'Peak',
borderColor: '#0EA5E9',
style: { color: '#fff', background: '#0EA5E9' },
},
},
{
x: 20,
y: 52,
id: 'dip',
marker: {
size: 7,
fillColor: '#fff',
strokeColor: '#ef4444',
strokeWidth: 3,
},
label: {
text: 'Watch',
borderColor: '#ef4444',
style: { color: '#fff', background: '#ef4444' },
},
},
],
xaxis: [
{
x: 10,
x2: 16,
id: 'window',
fillColor: '#7DD3FC',
opacity: 0.28,
label: {
text: 'Window',
style: { color: '#fff', background: '#0EA5E9' },
},
},
],
yaxis: [
{
y: 62,
id: 'target',
borderColor: '#f59e0b',
strokeDashArray: 4,
label: {
text: 'Target',
style: { color: '#fff', background: '#f59e0b' },
},
},
],
},
},
})
React.useEffect(() => {
// The react-apexcharts wrapper owns the render, so reach the live instance by
// its chart.id. Poll until it exists, then wire the same readout the vanilla
// build does. The ink feature drives the chart instance directly (drag / edit
// annotations), so no React state changes and the chart is not re-rendered.
let chart
const timer = window.setInterval(() => {
chart = ApexCharts.getChartByID('signal')
if (!chart) return
window.clearInterval(timer)
const readout = document.getElementById('ink-readout')
chart.addEventListener('annotationDragged', (c, o) => {
readout.textContent =
"Moved '" +
o.id +
"' to x=" +
Number(o.x).toFixed(2) +
', y=' +
Number(o.y).toFixed(2)
})
chart.addEventListener('annotationStyled', (c, o) => {
readout.textContent = "Restyled '" + o.id + "'"
})
chart.addEventListener('annotationDeleted', (c, o) => {
readout.textContent = "Deleted '" + o.id + "' (Ctrl/Cmd+Z restores it)"
})
}, 50)
return () => {
window.clearInterval(timer)
}
}, [])
return (
<div>
<div className="ink-wrap">
<div className="ink-bar">
<span className="readout" id="ink-readout">
Drag a labelled point to reposition it
</span>
</div>
<div id="chart">
<ReactApexChart
options={state.options}
series={state.series}
type="line"
height={380}
/>
</div>
<div className="ink-note">
The chart sets <code>chart.ink.enabled</code>, so its point
annotations are
<b>draggable</b>: grab a labelled marker and move it.{' '}
<b>Click a note</b> to open its floating editor card: rename it
inline, pick an accent color, toggle bold, step the text size,
grow/shrink or reshape the <b>marker</b>, or <b>delete</b> the note
(Enter commits, Escape closes; the swatches come from{' '}
<code>chart.ink.noteColors</code>). On release of a drag the new
position is converted back to data coordinates and written to
<code>annotations.points[].x/y</code>, so the annotation stays glued
to that data location on later zoom or resize. Use <b>+ Note</b> (the
palette, from
<code>chart.ink.palette</code>) then click the plot to drop a new
labelled note. The x-axis <b>Window</b> band moves (drag its middle)
or resizes (drag an edge), and the y-axis <b>Target</b> line drags
vertically. Fires
<code>annotationDragged</code> / <code>annotationEdited</code> /
<code>annotationStyled</code> / <code>annotationCreated</code> /
<code>annotationDeleted</code>. With the history (Rewind) feature
enabled,
<b>Ctrl/Cmd+Z</b> undoes any edit and Shift+Ctrl/Cmd+Z redoes it.
Needs the
<code>ink</code> feature. (Set <code>draggable:false</code> on a
single annotation to pin it.)
</div>
</div>
</div>
)
}
export default ApexChart