1

I have a bubble map chart that shows the location of cities on the map. The map has the default label but I want to use a custom react component as the label on the map. This is my source code but it has error and doesn't work:

import React, { Component, Fragment } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import HighchartsMap from "highcharts/modules/map";
import mapData from "@highcharts/map-collection/countries/gb/gb-all.geo.json";
import proj4 from "proj4";
import CustomLabel from "./CustomLabel";

HighchartsMap(Highcharts);

class BubbleMapChart extends Component {
  render() {
    const options = {
      chart: {
        map: "countries/gb/gb-all",
        proj4
      },
      series: [
        {
          name: "countries",
          nullColor: "#fff",
          showInLegend: false,
          mapData: mapData
        },
        {
          // Specify points using lat/lon
          type: "mapbubble",
          // PAY ATTENTION TO THIS SECTION - USE A CUSTOM LABEL COMPONENT
          dataLabels: {
            enabled: true,
            format: <CustomLabel name={"point.name"} />
          },
          minSize: "5%",
          maxSize: "15%",
          showInLegend: true,
          data: [
            {
              name: "London",
              lat: 51.507222,
              lon: -0.1275
            },
            {
              name: "Birmingham",
              lat: 52.483056,
              lon: -1.893611
            }
          ]
        }
      ]
    };

    return (
        <HighchartsReact
          highcharts={Highcharts}
          options={options}
          constructorType={"mapChart"}
        />
    );
  }
}

and this is a customLabel component as an example:

 import React, { Component } from "react";
    class CustomLabel extends Component {
  render() {
    return (
      <div>
        {/* Doesn't show this Division (actually doesn't apply the style ...) */}
        <div
          style={{ BackgroundColor: "red", width: "10px", height: "10px" }}
        ></div>
        <span>{this.props.name}</span>

        <br />

        {/* Doesn't show the red bullet inside the text */}
        <Badge color="#f50" text={this.props.name} />
      </div>
    );
  }
}
    export default CustomLabel;

How can I customize the data label in highcharts? actually I want to use a custom component as the label.

Zahra Talebi
  • 675
  • 4
  • 11
  • 26
  • seems it isn't possible at this point based on this thread https://www.highcharts.com/forum/viewtopic.php?t=44512 – albert Mar 14 '21 at 00:14

1 Answers1

0

Use ReactDOMServer and renderToStaticMarkup or renderToString method in formatter function for data labels:

    dataLabels: {
      enabled: true,
      formatter: function () {
        return renderToStaticMarkup(<CustomLabel name={this.point.name} />);
      }
    }

Live demo: https://codesandbox.io/s/highcharts-react-demo-forked-40icn?file=/demo.jsx

Docs: https://reactjs.org/docs/react-dom-server.html

API Reference: https://api.highcharts.com/highmaps/series.mapbubble.dataLabels.formatter


Or if you need to use some reactive logic inside CustomLabel take advantage of Portals in React.


Docs: https://reactjs.org/docs/portals.html

Example: https://www.npmjs.com/package/highcharts-react-official#how-to-add-react-component-to-a-charts-element

ppotaczek
  • 36,341
  • 2
  • 14
  • 24
  • Thank you for your response, But unfortunately in your solution we can not use third components. for example if I put the `Badge` component from `antd` library in `customLabel`, it doesn't work. this is badge component : `` – Zahra Talebi Apr 04 '21 at 21:00
  • Hi @Zahra Talebi, Please reproduce the problem in codesandbox. – ppotaczek Apr 06 '21 at 08:15
  • I have reproduce the problem in codesandbox. In addition, I make some changes in question above. thank you https://codesandbox.io/s/highcharts-react-demo-forked-wkc5v?file=/CustomLabel.jsx – Zahra Talebi Apr 09 '21 at 15:45
  • Thanks for the example. The `Badge` component propaply relays on state and `renderToStaticMarkup` method doesn't fully convert it. You need to use portals I mentioned above. – ppotaczek Apr 12 '21 at 10:50