Join regions highmaps - javascript

What I want to accomplish is to join/merge two or more regions in Highmaps. E.g. say you want to show the population for Europe + Asia, then when you hoover Asia or Europe they appear as one connected region with the acumulated population
I tried the following, but with no success:
var data = [
[['eu', 'as'], 0],
['af', 2],
['na', 4],
['sa', 5]];
With the fiddle: https://jsfiddle.net/2ek3mp1s/3/
Any ideas?

Of course, one option is to change the underlying geo data. But if you don't want to do that, you can tweak the mouseOver event so that it highlights at the same time the countries with the same value.
Here's a demo:
// Prepare demo data
// Data is joined to map using value of 'hc-key' property by default.
// See API docs for 'joinBy' for more info on linking data and map.
var data = [
['eu', 0],
['as', 0],
['af', 2],
['na', 4],
['sa', 5]
];
// Create the chart
Highcharts.mapChart('container', {
chart: {
map: 'custom/world-continents'
},
title: {
text: 'Highmaps basic demo'
},
plotOptions: {
map: {
point: {
events: {
mouseOver: function() {
var v = this.value
Highcharts.each(this.series.points, function(p) {
if (v == p.value) {
p.setState('hover')
}
});
},
mouseOut: function() {
Highcharts.each(this.series.points, function(p) {
p.setState('')
});
}
}
},
allAreas: false,
}
},
subtitle: {
text: 'Source map: World continents'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
colorAxis: {
min: 0
},
series: [{
data: data,
name: 'Random data',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
format: '{point.name}'
}
}]
})
<script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/mapdata/custom/world-continents.js"></script>
<div id="container"></div>
Jsfiddle: https://jsfiddle.net/user2314737/uhp2wgkn/
See also Highcharts "Categorized areas" demo

Not solving my exact issue, but found a way to achieve similar for Europe. In this case I connect Sweden and Finland("name": "path7025"):
http://jsfiddle.net/huqfkc2y/
by adding their respective region. Case dismissed.

Related

Highmaps country map not showing when using type: "mappoint"

I was working on India map demo in Highcharts, that have the following code:
// Create the chart
Highcharts.mapChart('container', {
chart: {
//type:'mappoint',
map: 'countries/in/custom/in-all-disputed'
},
title: {
text: 'Highmaps basic demo'
},
subtitle: {
text: 'Source map: India with disputed territories'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
colorAxis: {
min: 0
},
series: [{
data: data,
name: 'Random data',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
format: '{point.name}'
}
}]
});
It was working fine until I used type: "mappoint" .
I want to use mappoint type to dislplay points on the states of the country.
but using this mappoint type. my chart gets vanished and random points are showing on the screen.
You can see the example below in my fiddle:
https://jsfiddle.net/abnitchauhan/5naocyqw/
In order to use the mappoint series, you have to specify the position of each point.
You can do this by specifying the latitude and longitude.
Remember to import the proj4js library in order to work with lat and lon.
{
type: 'mappoint',
data: [{
name: 'New Delhi',
lat: 28.644800,
lon: 77.216721
}]
}
Demo: https://jsfiddle.net/BlackLabel/g49xcm7n/

Highcharts Maps Drilldown Map From geojson

I need to be able to render a map of the US as a chorpleth of states, then click on a state to just show that state's county divisions as a choropleth. I am using the base demo found here. I expanded that and am running into an issue where the data is not rendering the choropleth (ie, all areas have null value). Our source of the geojson is an internal ESRI service that uses full fips codes for the area identifier and the data contains a property of "Maparea" that I then use in the joinBy clause:
joinBy: ['fips', 'Maparea']
The data is pulled back dynamically from our data source (REST call) but it does not appear that is the cause of this issue as it occurs even with hardcoded data.
This works if I just show the states or just the counties. If I add in the drilldown ability I lose info on the drilldown series and then drilling back up produces and interesting artifact that the national map now has counties as shown for the state I clicked on instead of the state "shape". So, I have two problems:
Drill down does not produce choropleth
Drill up produces corrupt map
I have created a simple demo using CT as the state. Click on it and it should render the counties in CT and a choropleth. Drilling up should just go back to state map. Demo here. Code (minus test data):
// Set drilldown pointers
$.each(statedata.data, function(i) {
this.drilldown = this.Maparea.substring(0, 2);
});
// Instantiate the map
Highcharts.mapChart('container', {
chart: {
map: stateMap,
events: {
drilldown: function(e) {
if (!e.seriesOptions) {
var chart = this;
//Neded this bit to just show the county shapes
chart.update({
chart: {
map: countyMap
}
});
chart.addSeriesAsDrilldown(e.point, [{
mapData: countyMap
}, countyData]);
}
this.setTitle(null, {
text: e.point.areaname
});
},
drillup: function() {
this.setTitle(null, {
text: ''
});
}
}
},
title: {
text: 'Highcharts Map Drilldown'
},
subtitle: {
text: '',
floating: true,
align: 'right',
y: 50,
style: {
fontSize: '16px'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
colorAxis: {
min: 0,
minColor: '#E6E7E8',
maxColor: '#005645'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
plotOptions: {
map: {
states: {
hover: {
color: '#EEDD66'
}
}
}
},
series: [{
map: stateMap
}, statedata],
drilldown: {
activeDataLabelStyle: {
color: '#FFFFFF',
textDecoration: 'none',
textOutline: '1px #000000'
},
drillUpButton: {
relativeTo: 'spacingBox',
position: {
x: 0,
y: 60
}
}
}
});
Notice that in the official demo the chart.map update doesn't exist - this behaviour changes the working of the drillup functionality.
Try to assign the map to the drilldown data series as:
mapData: Highcharts.geojson(countyMap),
Demo: https://jsfiddle.net/BlackLabel/4hcxeku7/
Is this an output which you want to achieve?

Highmaps chart is empty in Angular 5

I have a component where I have to show high maps. No errors but the maps is always empty
My chart options object :
let chartData = [{ code3: "ABW", z: 105 }, { code3: "AFG", z: 35530 }];
this.chartConfigObject = new MapChart(<any>{
chart: {
borderWidth: 1,
map: 'custom/world'
},
title: {
text: 'World population 2013 by country'
},
subtitle: {
text: 'Demo of Highcharts map with bubbles'
},
legend: {
enabled: false
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
series: [{
name: 'Countries',
color: '#E0E0E0',
enableMouseTracking: false
}, {
type: 'mapbubble',
name: 'Population 2016',
joinBy: ['iso-a3', 'code3'],
data: chartData,
map: mapData,
minSize: 4,
maxSize: '12%',
tooltip: {
pointFormat: '{point.properties.hc-a2}: {point.z} thousands'
}
}]
});
When I console the created MapChart object i am getting the series as null always.
What am i missing and why the maps series is always null?
I am using angular-highcharts component as explained here :
https://github.com/cebor/angular-highcharts
reproduced in stackblitz: https://stackblitz.com/edit/angular-highcharts-stock-nbvnuw?file=app%2Fapp.module.ts
You are not providing the map data to your chart , so it doesn't know which map to show. Try showing the map data like mapData: Highcharts.maps['custom/world'] under Series.
If you cannot access the maps in your Highcharts reference , try importing all the maps (JS files) from the HighMaps library into your project and reference them in your typescript component file like this:
const Highcharts = {maps: {}};
require('../../../assets/maps')(Highcharts); //your custom project path
and use mapData: Highcharts['maps']['custom/world'] or whatever is the map you wanted to use like 'countries/us/us-all'
Below is working map code using angular-highcharts to plot the map and points on it:
getMap(data) {
return new MapChart({
chart: {
events: {
load: function (point) {
//do something here on page load
}
},
spacingBottom: 20
backgroundColor: '#FFF',
style: {fontFamily: 'inherit'}
},
title: {
text: ''
},
mapNavigation: {
enabled: true
},
tooltip: {
headerFormat: '',
formatter: function () {
var toolTipTxt = '<b>' + this.point.options.name + '</b>';
return toolTipTxt;
}
},
plotOptions: {
series: {
color: '#00A778',
marker: {
radius: 6,
symbol: 'circle',
lineColor: '#00A778',
lineWidth: 1,
states: {
select: {
fillColor: '#00A778',
lineWidth: 1,
lineColor: '#00A778'
}
}
},
point: {
events: {
click: function () {
this.select(null, true);
}
}
}
}
},
series: [
{
//mapData: Highcharts['maps']['custom/world']
mapData: Highcharts.maps['custom/world'],
name: 'Basemap',
borderColor: '#A0A0A0',
nullColor: 'rgba(200, 200, 200, 0.3)',
showInLegend: false,
data: []
},
{
// Specify points using lat/lon
type: 'mappoint',
name: 'MySites',
data: data
}
]
});
}
Also you need proj4js library to plot points on the map, in case if that's your requirement as well.
Hope this helps !
Might, it can be useful.
Here is the solution for angular-highcharts:
1) Download the map from collection:
https://code.highcharts.com/mapdata/
2) Create a variable that equals to the content of this file and export it:
instead of
Highcharts.maps["custom/world"] = { ... content of the file ... }
use
const worldMap = { ... content of the file ... }
export default worldMap;
2) Import this map to your component (for world-map.ts):
import worldMap from './world-map';
3) use
chart: {
...
map: worldMap,
...
},
And, of course, don't forget to add a couple of lines to your module:
import { ChartModule, HIGHCHARTS_MODULES } from 'angular-highcharts';
import * as highmaps from 'highcharts/modules/map.src';
#NgModule({
...
providers: [
{ provide: HIGHCHARTS_MODULES, useFactory: () => [highmaps] }
],
...
})
About modules: https://www.npmjs.com/package/angular-highcharts#highmaps
Here is the working example:
https://stackblitz.com/edit/angular-highcharts-stock-byjo6a
Solution was found here:
https://forum.highcharts.com/highmaps-usage-f14/highmaps-bubble-chart-is-empty-t40432/

Extending Highmaps Side Effect

I am trying to create a dot density map of the state of Florida. While I know that Highmaps doesn't support color axis with mappoints. I extended it and it works but it comes with a side affect. When I click on one of the categories in the legend no hiding occurs. For example if I click on '>10', all values greater than 10 don't hide. When I open up the Chrome debugger it states that: a.setVisible is not a function What can I do to solve this problem. This is a requirement, while it may seem minor. I would appreciate any sort of tips or maybe some sort of example would be perfect. I can't show more code than what is shown. If you need me to explain more about the problem I will be glad to do so.
(function (H) {
H.seriesTypes.mappoint.prototype.axisTypes = [ 'xAxis', 'yAxis', 'colorAxis'];
H.wrap(H.seriesTypes.mappoint.prototype, "translate", function (p) {
p.call(this);
H.seriesTypes.mappoint.prototype.translateColors.call(this);
});
H.seriesTypes.mappoint.prototype.translateColors = H.seriesTypes.heatmap.prototype.translateColors;
H.seriesTypes.mappoint.prototype.colorKey = 'value';
})(Highcharts);
// Initiate the chart
$('#container').highcharts('Map', {
title: {
text: title
},
mapNavigation: {
enabled: false,
},
colorAxis: {
dataClasses: [{
from: 0,
to: 3,
color: "#66FFFF"
}, {
from: 4,
to: 9,
color: "#0099FF"
}, {
from: 10,
color: "#0000FF"
}
]
},
tooltip:
{
enabled: true
}
,
series: [{
mapData: Highcharts.maps['countries/us/us-fl-all'],
name: 'Basemap',
borderColor: '#A0A0A0',
nullColor: 'rgba(200, 200, 200, 0.3)',
showInLegend: false,
},
{
// Specify points using lat/lon
type: 'mappoint',
name: 'A',
turboThreshold: 2000000,
data: p_data,
dataLabels: {
enabled: false
}
},
{
// Specify points using lat/lon
type: 'mappoint',
name: 'B',
turboThreshold: 2000000,
data: m_data,
dataLabels: {
enabled: false
}
},
{
// Specify points using lat/lon
type: 'mappoint',
name: 'C',
turboThreshold: 2000000,
data: h_data,
dataLabels: {
enabled: false
}
}
]});
A sample to play with: http://jsfiddle.net/dlope073/4mabw6zr/2/
Use setVisible method from default map series. Like this: http://jsfiddle.net/4mabw6zr/3
(function (H) {
H.seriesTypes.mappoint.prototype.axisTypes = ['xAxis', 'yAxis', 'colorAxis'];
H.seriesTypes.mappoint.prototype.pointClass.prototype.setVisible = H.seriesTypes.map.prototype.pointClass.prototype.setVisible; // use the same setVisible method as map type.
H.wrap(H.seriesTypes.mappoint.prototype, "translate", function (p) {
p.call(this);
H.seriesTypes.mappoint.prototype.translateColors.call(this);
});
H.seriesTypes.mappoint.prototype.translateColors = H.seriesTypes.heatmap.prototype.translateColors;
H.seriesTypes.mappoint.prototype.colorKey = 'value';
})(Highcharts);

How do I make a Tornado Chart using Highcharts

I am trying to prepare a Tornado Chart using the column chart in Highcharts. Here is my fiddle.
My current code is:
$('#container').highcharts({
chart: {
type: 'columnrange',
inverted: true
},
title: {
text: 'Net Sales'
},
subtitle: {
text: 'MM $'
},
xAxis: {
categories: ['Annual Revenue', 'Number of Years', 'Annual Costs']
},
yAxis: {
title: {
text: 'MM $'
}
},
plotOptions: {
columnrange: {
dataLabels: {
enabled: true,
formatter: function () {
return this.y;
}
}
},
scatter:{
marker:{
symbol:'line',
lineWidth:11,
radius:8,
lineColor:'#f00'
}
}
},
legend: {
enabled: false
},
series: [{
name: 'Temperatures',
data: [
[12.15, 46.86],
[15.45, 42.28],
[27.77, 31.24]
]
},
{
name:'Base',type: 'scatter',data:[120],
}]
});
The problem is that the last series (Annual Costs) does not show, as it is in reversed order. Also, I'd like the Tornado Chart to look more like this:
Note that the labels in this chart are different from the actual values plotted. Also note that the bar in the center - in the example code, there would be a vertical line at 29.5. I would also like to support a combined uncertainty bar like the one at the bottom. Any suggestions would be greatly appreciated.
Your last bat is not showing, because first number is lower than second, see: http://jsfiddle.net/kErPt/1/
If you want to display another values at labels, then add that info first. Example:
data: [{
low: 12,
high: 15,
lowLabel: 35,
highLabel: 46
}, {
low: 2,
high: 35,
lowLabel: 15,
highLabel: 26
} ... ]
And then use dataLabels.formatter for series.
To add vertical line use plotLines.
I'm not sure what is the last bar called 'combined uncertainty'.
I've used Highcharts with separate series (thanks jlbriggs) to create a Tornado Chart: http://jsfiddle.net/uRjBp/
var baseValue = 29.5;
var outputTitle = "Net Sales";
var chart = new Highcharts.Chart({
chart: {
renderTo:'container',
//type:'column'
//type:'area'
//type:'scatter'
//type:'bubble'
},
credits: {},
exporting: {},
legend: {},
title: {
text: outputTitle
},
subtitle: {
text: "MM $"
},
tooltip: {
formatter: function() {
var msg = "";
var index = this.series.chart.xAxis[0].categories.indexOf(this.x);
var low = round(this.series.chart.series[0].data[index].y+baseValue);
var high = round(this.series.chart.series[1].data[index].y+baseValue);
if (this.x === "Combined Uncertainty") {
msg = "Combined Uncertainty in "+outputTitle+": "+low+" to "+high;
} else {
var lowLabel = this.series.chart.series[0].data[index].label;
var highLabel = this.series.chart.series[1].data[index].label;
msg = '<b>'+outputTitle+'</b> goes from '+ low +' to '+ high+'<br/> when '+this.x +
' goes from <br/> '+lowLabel+" to "+highLabel;
}
return msg;
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
formatter: function () {
var index = this.series.chart.xAxis[0].categories.indexOf(this.x);
if (this.series.userOptions.labels === undefined) {
return this.y+baseValue;
}
return this.key === "Combined Uncertainty" ? "":this.series.userOptions.labels[index];
}
}
}
},
xAxis: {
title: {
text: 'Factor'
},
allowDecimals:false,
categories: ['Annual Revenue', 'Number of Years', 'Annual Costs', 'Combined Uncertainty']
},
yAxis: {
title: {
text: 'MM $'
},
labels: {
formatter:function() {
return this.value+baseValue;
}
}
},
series:[{
name: 'Low',
grouping:false,
type:'bar',
data:[{y:12.15-baseValue, label:10},{y:15.45-baseValue, label:1},{y:31.25-baseValue, label:2},{y:12.15-baseValue, color:'#99CCFF', label: ""}],
labels:[10,1,2,]
},{
name: 'High',
grouping:false,
type:'bar',
data:[{y:46.86-baseValue, label:30},{y:42.28-baseValue, label:3},{y:27.77-baseValue, label:4},{y:46.86-baseValue, color:'#99CCFF', label:""}],
labels:[30,3,4,]
},
{
name: 'Median',
type: 'scatter',
data: [null,null, null,27-baseValue],
marker: {
lineWidth: 2,
lineColor: Highcharts.getOptions().colors[3],
fillColor: 'white'
}
}]
});
function round(num) {
return Math.round(num*100)/100;
}
usually, this kind of chart is done using a separate series for the left and right portions
One way to do this is by setting one set of data as negative numbers, and then using the formatters to make the axis labels, datalabels, and tooltips display the absolute values
example:
http://jsfiddle.net/jlbriggs/yPLVP/68/
UPDATE:
to show a line as in your original chart, you can extend the marker symbols to include a line type, and use a scatter series to draw that point:
http://jsfiddle.net/jlbriggs/yPLVP/69/
If you don't want to have the extra code for the line marker type, you could use any of the other existing marker symbols for the scatter series.

Categories

Resources