Lines in React
Using ApexCharts with React
This Lines example wires ApexCharts into React through the react-apexcharts component.
Install it with npm install react-apexcharts apexcharts, then mount the chart with <Chart type="..." options={options} series={series} />.
import React from 'react'
import ReactApexChart from 'react-apexcharts'
import ApexCharts from 'apexcharts'
import './styles.css'
import 'apexcharts/features/highlight-filter'
// Shared by the vanilla-js, React and Vue builds.
//
// Orders per month by store (the wholes), and the orders that came from one
// kind of customer (the parts). Picking a customer keeps both stores on the
// chart: each line is drawn dashed at its full value, with that customer's
// orders solid in the same colour, on the same axis.
var MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug']
var STORES = ['Online store', 'Retail']
var ORDERS = [
[420, 460, 510, 480, 560, 610, 590, 650],
[300, 320, 310, 340, 360, 330, 380, 400],
]
var CUSTOMERS = {
returning: [
[250, 270, 300, 290, 340, 370, 360, 400],
[210, 220, 215, 240, 250, 230, 260, 280],
],
first: [
[170, 190, 210, 190, 220, 240, 230, 250],
[90, 100, 95, 100, 110, 100, 120, 120],
],
}
function seriesFor(customer) {
return STORES.map(function (name, i) {
var s = { name: name, data: ORDERS[i] }
if (customer) s.highlightData = CUSTOMERS[customer][i]
return s
})
}
// One call per pick: the parts go in, the chart animates from what is on
// screen. Clearing is the same call without them.
function pickCustomer(chart, customer) {
document.querySelectorAll('[data-customer]').forEach(function (b) {
b.classList.toggle('active', b.getAttribute('data-customer') === customer)
})
return chart.updateSeries(seriesFor(customer))
}
function wireCustomers(chart) {
document.querySelectorAll('[data-customer]').forEach(function (b) {
b.addEventListener('click', function () {
pickCustomer(chart, b.getAttribute('data-customer'))
})
})
}
const ApexChart = () => {
const [state, setState] = React.useState({
series: seriesFor('returning'),
options: {
chart: {
id: 'orders',
type: 'line',
height: 380,
toolbar: { show: false },
},
colors: ['#0f766e', '#ea580c'],
stroke: { curve: 'smooth', width: 3 },
markers: { size: 4, strokeWidth: 0, hover: { size: 6 } },
dataLabels: {
enabled: true,
style: { fontSize: '11px' },
background: { enabled: true, borderWidth: 0, opacity: 0.85 },
},
xaxis: { categories: MONTHS },
yaxis: { min: 0, title: { text: 'Orders' } },
highlightFilter: { line: { dashArray: 5 } },
legend: { position: 'bottom' },
tooltip: { shared: true, intersect: false },
},
})
React.useEffect(() => {
// The react-apexcharts wrapper owns the render, so reach the live instance
// by its chart.id. (seriesFor / pickCustomer live in the shared head script.)
const timer = window.setInterval(() => {
const chart = ApexCharts.getChartByID('orders')
if (!chart) return
window.clearInterval(timer)
wireCustomers(chart)
}, 50)
return () => window.clearInterval(timer)
}, [])
return (
<div>
<div className="wrap">
<h1>Highlight a part of every line</h1>
<p>
Pick a kind of customer. Each store's orders stay on the chart as a
dashed line at their full value, and the orders that customer placed
are drawn solid in the same colour. Labels and tooltips state the
part; the markers stay on the full line.
</p>
<div className="actions">
<span>Customer</span>
<button data-customer="returning" className="active">
Returning
</button>
<button data-customer="first">First order</button>
<button data-customer="">All (clear)</button>
</div>
<div className="chart-wrap">
<div id="chart">
<ReactApexChart
options={state.options}
series={state.series}
type="line"
height={380}
/>
</div>
</div>
</div>
</div>
)
}
export default ApexChart