import React from 'react'
import ReactApexChart from 'react-apexcharts'
import ApexCharts from 'apexcharts'
import './styles.css'
// Marks (#11): register a reusable "dumbbell" series type once. Each datum is
// a { x, y: [start, end] } pair. dataType 'rangeXY' tells ApexCharts to fold
// BOTH y-bounds into the axis scale (so the axis fits the full range, not just
// the end value) and to render the tooltip as "start - end".
ApexCharts.registerSeriesType('dumbbell', {
dataType: 'rangeXY',
renderItem: function (ctx) {
var datum = ctx.datum
var x = ctx.x
var scales = ctx.scales
var api = ctx.api
var yStart = scales.y(datum.y[0])
var yEnd = scales.y(datum.y[1])
// connecting stem
api.line({
x1: x,
y1: yStart,
x2: x,
y2: yEnd,
stroke: '#d0d5dd',
width: 4,
lineCap: 'round',
})
// start marker (hollow ring) and end marker (filled)
api.circle({
cx: x,
cy: yStart,
r: 7,
fill: '#fff',
stroke: '#008FFB',
strokeWidth: 3,
})
api.circle({ cx: x, cy: yEnd, r: 7, fill: '#00B894' })
},
})
var dumbbellData = [
{ x: 'Austin', y: [312, 498] },
{ x: 'Denver', y: [398, 545] },
{ x: 'Miami', y: [285, 610] },
{ x: 'Seattle', y: [512, 720] },
{ x: 'Boise', y: [255, 415] },
{ x: 'Raleigh', y: [268, 402] },
{ x: 'Phoenix', y: [295, 468] },
]
const ApexChart = () => {
const [state, setState] = React.useState({
series: [{ name: 'Price range', data: dumbbellData }],
options: {
chart: {
height: 440,
type: 'dumbbell',
animations: { enabled: false },
toolbar: { show: false },
},
grid: {
padding: { left: 15, right: 15 },
xaxis: { lines: { show: true } },
},
title: {
text: 'Median home price by city: 2019 vs 2024',
align: 'left',
},
subtitle: {
text: 'A custom "dumbbell" series type built with Marks (registerSeriesType)',
align: 'left',
},
xaxis: {
type: 'category',
tooltip: { enabled: false },
},
yaxis: {
min: 200,
tickAmount: 6,
labels: {
formatter: function (val) {
return '$' + Math.round(val) + 'k'
},
},
},
tooltip: {
y: {
formatter: function (val) {
return '$' + val + 'k'
},
},
},
},
})
return (
<div>
<div className="panel">
<div className="legend">
<span className="item">
<span className="dot hollow"></span> 2019
</span>
<span className="item">
<span className="dot filled"></span> 2024
</span>
</div>
</div>
<div id="chart">
<ReactApexChart
options={state.options}
series={state.series}
type="dumbbell"
height={440}
/>
</div>
<div className="panel">
<div className="note">
There is no built-in dumbbell type here. It is a custom series
registered with
<code>
ApexCharts.registerSeriesType('dumbbell', { dataType:
'rangeXY', renderItem })
</code>
.<code>renderItem</code> draws one stem and two circles per datum
through the primitive <code>api</code>, and{' '}
<code>dataType: 'rangeXY'</code> routes the
<code>y: [start, end]</code> pair through the range path so the y-axis
fits both bounds and the tooltip reads "start - end". Hover a marker
to see it.
</div>
</div>
</div>
)
}
export default ApexChart