|
import React from 'react' |
|
import { render } from 'react-dom' |
|
import Highcharts from 'highcharts/highstock' |
|
import HighchartsReact from 'highcharts-react-official' |
|
import { BrowserRouter as Router, Route, Link } from 'react-router-dom' |
|
|
|
// Used in the helper function named formatter |
|
import { renderToString } from 'react-dom/server' |
|
|
|
// Axis formatter which renders labels with links. |
|
class AxisFormatter extends React.Component { |
|
renderLabel = (match, ctx) => { |
|
const msg = ( |
|
match.params.id === ctx.value.toString() ? |
|
'You clicked me' : |
|
'Click me!' |
|
) |
|
const text = `${ctx.value}: ${msg}` |
|
return <Link to={`/${ctx.value}`}>{text}</Link> |
|
} |
|
render() { |
|
const ctx = this.props.context |
|
const fn = ({ match }) => this.renderLabel(match, ctx) |
|
return <Router> |
|
<div> |
|
<Route path="/:id" render={fn} /> |
|
<Route exact path="/" render={fn} /> |
|
</div> |
|
</Router> |
|
} |
|
} |
|
|
|
|
|
// Helper to render components in a formatter function. |
|
const formatter = (Component) => { |
|
return function () { |
|
const args = arguments |
|
const ctx = this |
|
const uniqueId = () => Math.random().toString(36).substring(2, 9) |
|
const id = 'highcharts-formatter-' + uniqueId() |
|
const axis = ctx.axis; |
|
const chart = axis.chart; |
|
const addEvent = Highcharts.addEvent; |
|
|
|
// When issue with fireEvent is fixed, remove the following block. |
|
if (!chart.removeFormatterCleanUp) { |
|
chart.formatterCleanUp = []; |
|
chart.removeFormatterCleanUp = addEvent(chart, 'beforeRedraw', function () { |
|
this.formatterCleanUp.forEach(function (removeEvent) { |
|
removeEvent(); |
|
}); |
|
this.formatterCleanUp = []; |
|
}) |
|
} |
|
|
|
const removeEvent = addEvent(axis, 'afterRender', function () { |
|
const el = document.getElementById(id); |
|
if (el) { |
|
// Render the component as an element with events handlers and so on. |
|
render(<Component arguments={args} context={ctx} />, el); |
|
el.removeAttribute('id'); |
|
} |
|
// When issue with fireEvent is fixed, remove next line, and uncomment the second next line. |
|
chart.formatterCleanUp.push(removeEvent) |
|
//removeEvent() |
|
}); |
|
return '<span id="' + id + '">' + |
|
// Render content to have correct positioning |
|
renderToString(<Component arguments={args} context={ctx} />) + |
|
'</span>' |
|
} |
|
} |
|
|
|
const options = { |
|
title: { |
|
text: 'My stock chart' |
|
}, |
|
series: [{ |
|
data: [1, 2, 3] |
|
}], |
|
xAxis: { |
|
labels: { |
|
useHTML: true, |
|
// Passing the component into the helper function |
|
formatter: formatter(AxisFormatter) |
|
} |
|
} |
|
} |
|
|
|
const App = () => <div> |
|
<HighchartsReact |
|
highcharts={Highcharts} |
|
constructorType={'stockChart'} |
|
options={options} |
|
/> |
|
</div> |
|
|
|
render(<App />, document.getElementById('root')) |
@jon-a-nygaard nice solution, thanks for this π
However, this renders
<div data-reactroot=""><a href="/0">0: Click me!</a></div>
which clicking on generate a server page load...