I am looking to create a highmap with overlaid piecharts based on this JSfiddle. I have used the events = list(load = JS()
construct to call the JS code, copied from the demo above. The problem I have, as shown below, is that the output contains only a single piechart, whereas it should include a piechart for each non-missing point in the series.
Additionally, I note that the pie chart renders in the centre of the map, but the tooltip and data is for the last point of the data series - here SE (Sweden, I think!). It is also significant that the pie chart always renders in the same spot, regardless of the id
of the last country of data
. What am I doing wrong here? I attach an image of the output below, as well as the code to replicate the map.
Update Thanks to Felix Jassler's comment I realised that each individual pie chart is in fact being plotted, but the problem is then that they all plotted in the same place. Enabling labels on the pie chart makes this clear to see, as shown in the updated image output below. Additionally, I have also since found this post, where a user on highcharts in vue.JS encountered the exact same problem. The solution here was the user to update to the latest version of highcharts v10.2. I have the latest version of highcharter (v9.4), and so I think that that solution would probably require some input from the developers of highcharter. I have opened an issue here on the highcharter git.
Final update
The answer given below by jedrzerjuta has been accepted with much gratitude and the result can be seen below.
# Required
library(tidyverse)
library(highcharter)
# Create data
data <- tibble(
id = c(
"PL",
"NO",
"DE",
"BY",
"FR",
"CZ",
"SE"
),
successes = c(
15,
20,
10,
10,
1,
20,
20
),
failures = c(
3,
2,
10,
15,
2,
20,
8
)
)
data$value <- data$successes-data$failures
# Plot
hcmap("custom/world-highres",
data = data,
joinBy = c("iso-a2", "id"),
keys =c('id', 'successes', 'failures', 'value')
)%>%
hc_colorAxis(
dataClasses=list(
list(
from = -15,
to = -1,
color = '#faa',
name = 'Successes'
),
list(
from = 0,
to = 0,
color = '#ddd',
name = 'Neutral'
),
list(
from = 1,
to = 18,
color = '#adf',
name = 'Neutral'
)
)
)%>%
hc_chart(events = list(load = JS("function() {
var chart = this;
chart.series[0].points.forEach(country => {
if (!country.isNull) {
chart.addSeries({
type: 'pie',
name: country.id,
zIndex: 4,
size: 40,
dataLabels: {
enabled: false
},
onPoint: {
id: country.id
},
states: {
inactive: {
enabled: true
}
},
data: [{
name: 'Successes',
y: country.successes,
color: '#adf'
}, {
name: 'Failures',
y: country.failures,
color: '#faa'
}]
}, false);
}
}
);
chart.redraw();
}
"
)
)
)
The problem with the pie charts not being laid on countries coordinates is strictly linked to Highcharts v9.3.1 being used in the latest Highcharter version available on CRAN. Above code uses onPoint
object property, which requires series-on-point module, that is available from Highcharts > v10 version.
As a workaround, you can install the development version from Highcharter GitHub repository: https://github.com/jbkunst/highcharter?tab=readme-ov-file#installation and add the series-on-point module using highcharter::hc_add_dependency
method. This version uses Highcharts v10.2.0, so it should work correctly.
Below you will find updated R code:
# Required
library(tidyverse)
remotes::install_github("jbkunst/highcharter")
# Create data
data <- tibble(
idd = c(
"PL",
"NO",
"DE",
"BY",
"FR",
"CZ",
"SE"
),
successes = c(
15,
20,
10,
10,
1,
20,
20
),
failures = c(
3,
2,
10,
15,
2,
20,
8
)
)
data$value <- data$successes-data$failures
# Plot
highcharter::hcmap("custom/world-highres",
data = data,
joinBy = c("iso-a2", "idd"),
keys =c('idd', 'successes', 'failures', 'value')#,
#dataLabels = list(enabled = TRUE, format = "{point.idd}",
#style=list(fontSize='10'))
)%>%
highcharter::hc_add_dependency("modules/series-on-point.js")%>%
highcharter::hc_colorAxis(
dataClasses=list(
list(
from = -15,
to = -1,
color = '#faa',
name = 'Successes'
),
list(
from = 0,
to = 0,
color = '#ddd',
name = 'Neutral'
),
list(
from = 1,
to = 18,
color = '#adf',
name = 'Neutral'
)
)
)%>%
highcharter::hc_chart(events = list(load = highcharter::JS("function() {
var chart = this;
chart.series[0].points.forEach(country => {
if (!country.isNull) {
chart.addSeries({
type: 'pie',
name: country.idd,
zIndex: 6,
size: 40,
dataLabels: {
enabled: true
},
onPoint: {
id: country.id
},
states: {
inactive: {
enabled: true
}
},
data: [{
name: 'Successes',
y: country.successes,
color: '#adf'
}, {
name: 'Failures',
y: country.failures,
color: '#faa'
}]
}, false);
}
}
);
chart.redraw();
}
"
)
)
)