diff --git a/src/datamap.jsx b/src/datamap.jsx index a71b2f3..18e112c 100644 --- a/src/datamap.jsx +++ b/src/datamap.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import Datamaps from 'datamaps'; +import ExtendedDatamaps from './extended_datamaps'; export default class Datamap extends React.Component { @@ -64,7 +64,7 @@ export default class Datamap extends React.Component { let map = this.map; if (!map) { - map = this.map = new Datamaps({ + map = this.map = new ExtendedDatamaps({ ...props, data, element: this.refs.container diff --git a/src/extended_datamaps.js b/src/extended_datamaps.js new file mode 100644 index 0000000..7da707c --- /dev/null +++ b/src/extended_datamaps.js @@ -0,0 +1,45 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import Datamaps from 'datamaps'; +import d3 from 'd3'; + +export default class ExtendedDatamaps extends Datamaps { + + updatePopup(element, d, options) { + const self = this, + data = JSON.parse(element.attr('data-info')), + reactObj = options.popupTemplate(d, data); + + if (!React.isValidElement(reactObj)) { + return super.updatePopup(element, d, options); + } + + const hoverObj = d3.select(self.svg[0][0].parentNode).select('.datamaps-hoverover'); + + element.on('mousemove', null); + element.on('mouseenter', null); + element.on('mouseleave', null); + + element.on('mouseenter', function() { + hoverObj.style('display', 'block'); + ReactDOM.render(reactObj, hoverObj[0][0]); + }); + + element.on('mousemove', function() { + let position = d3.mouse(self.options.element); + + hoverObj + .style('top', (position[1] + 30) + "px") + .style('left', position[0] + "px"); + }); + + element.on('mouseleave', function() { + ReactDOM.unmountComponentAtNode(hoverObj[0][0]) + + hoverObj + .style('display', 'none') + .html(''); + }); + } + +}