AMChars, Zoom to certain countries with external buttons - javascript

OK, so I have this map in AMCharts where I have external buttons that contain IDs, LAT and Long of certain countries, and when I hover over them I want the map to zoom and center itself to that country, here's the code example ...
http://codepen.io/sheko_elanteko/pen/rjYvgE
var map = AmCharts.makeChart("chartdiv", {
"type": "map",
"dataProvider": {
"map": "worldLow",
"getAreasFromMap": true,
"areas": [ {
"id": "EG",
"color": "#67b7dc",
"rollOverOutlineColor": "#000",
"autoZoom": true,
"balloonText": "Egypt"
}, {
"id": "KZ",
"color": "#67b7dc",
"rollOverOutlineColor": "#000",
"autoZoom": true,
"balloonText": "Kazakistan"
}, {
"id": "US",
"color": "#67b7dc",
"rollOverOutlineColor": "#000",
"autoZoom": true,
"balloonText": "United States"
}]
},
"areasSettings": {
"color": "#999",
"autoZoom": false,
// "selectedColor": "#CC0000",
"balloonText": "",
"outlineColor": "#fff",
"rollOverOutlineColor": "#fff"
},
"listeners": [{
"event": "rendered",
"method": function(e) {
// Let's log initial zoom settings (for home button)
var map = e.chart;
map.initialZoomLevel = map.zoomLevel();
map.initialZoomLatitude = map.zoomLatitude();
map.initialZoomLongitude = map.zoomLongitude();
}
}]
});
function centerMap() {
map.zoomToLongLat(map.initialZoomLevel, map.initialZoomLongitude, map.initialZoomLatitude);
}
$("button.country").mouseenter(function(event) {
event.stopPropagation();
var countryID = $(this).data("id");
var country = map.getObjectById(countryID);
var lat = $(this).data("lat");
var long = $(this).data("long");
country.color = '#000';
// map.zoomToSelectedObject(country);
map.zoomToLongLat(3, lat, long);
country.validate();
}).mouseleave(function(event){
event.stopPropagation();
var countryID = $(this).data("id");
var country = map.getObjectById(countryID);
country.color = '#CC0000';
country.validate();
centerMap();
});
As you can see I have the coordinates of each country hard coded, as well as the zoom level, but the zooming doesn't work properly, especially for US!!
I also wonder if there's a way to get the LAT and Long of each country so that I don't hard-code them.
There's a function in AMCharts called "zoomToSelectedObject", but I tried that and gave it the object with no luck.

You could try amCharts' selectObject method. Its default function is to zoom to the map object provided (the one that you already get by using getObjectById. Example:
$("button.country").mouseenter(function(event) {
event.stopPropagation();
var countryID = $(this).data("id");
var country = map.getObjectById(countryID);
map.selectObject(country);
}).mouseleave( ... );
Just make sure that you add "selectable": true to your areasSettings. Without it, the selectObject method won't work.
amCharts maps have excellent docs that you'll find here: https://docs.amcharts.com/3/javascriptmaps/AmMap#selectObject.

Related

How to color GeoJson polygons using another api?

I have a GeoJson map file with province ids and coordinates , also I am using another api which tells the color of each province id . I want to set fillColor of each polygon accordingly
my GeoJson file (just the first polygon as an example):
[
{
"type" : "FeatureCollection",
"features" : [
{
"type" : "Feature",
"id" : 0,
"regionColor": "orangeColor",
"geometry" : {
"type" : "Polygon",
"coordinates" : [...]
},
"properties" : {
"FID" : 0,
"FID_1" : 0
}
}
]
my API (imported as mockData):
{
"colors": [
{
"id": "0",
"countryColor": "red"
},
{
"id": "1",
"countryColor": "orange"
},
{
"id": "2",
"countryColor": "yellow"
}
]
}
my code :
<template>
<div class="container">
<div id="mapContainer">
</div>
</div>
</template>
<script>
import "leaflet/dist/leaflet.css";
import L from "leaflet";
import geojson from "../components/provinces.json"
import mockData from "./test.json"
export default{
name: "locationMap",
data() {
return{
center: [32.87255939010237, 53.781741816799745],
}
},
methods: {
setupLeafletMap: function () {
const mapDiv = L.map("mapContainer").setView(this.center, 5);
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
attribution: '© <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
// maxZoom: 18,
}
).addTo(mapDiv);
var myStyle = {
"fillColor": "#818181",
"color": "black",
"weight": 2,
"opacity": 0.65,
"fillOpacity": 0.6
};
L.geoJSON(geojson,{
style: myStyle,
}
}
}
mounted() {
this.setupLeafletMap()
console.log(mockData.colors[1].id)
},
}
</script>
L.geoJSON accepts a style function to dynamically apply styles based on each feature. You can write a style function that maps the feature ID to the color in your dataset. For example:
L.geoJSON(geoJSONData, {
// The style function receives each feature from your GeoJSON dataset.
// You can access the feature's properties to lookup the color.
style: function (feature) {
const fid = feature.properties.FID,
color = mockData.colors.find((color) => parseInt(color.id) === fid);
console.debug(`Feature with id ${fid} has now color ${color.countryColor}`);
return {
fillColor: color.countryColor,
color: "black",
weight: 2,
opacity: 0.65,
fillOpacity: 0.6
};
}
}).addTo(map);
I created an example with your code and some sample data as a reference, check it out here: https://codepen.io/strfx/pen/XWYNrBM
Hope this helps!

Drilldown Map using JSON file Highcharts

I would like to do map drilldown using Highcharts by following this US Map Drilldown example : US Map Drilldown Highcharts
This is the sample of my drilldown javascript file
var data = Highcharts.geojson(Highcharts.maps['countries/my/my-all']),
separators = Highcharts.geojson(Highcharts.maps['countries/my/my-all'], 'mapline'),
// Some responsiveness
small = $('#container').width() < 400;
// Set drilldown pointers
$.each(data, function (i) {
this.drilldown = this.properties['hc-key'];
this.value = i; // Non-random bogus data
});
// Instantiate the map
Highcharts.mapChart('container', {
chart: {
events: {
drilldown: function (e) {
if (!e.seriesOptions) {
var chart = this,
mapKey = 'countries/my/' + e.point.drilldown + '-all',
// Handle error, the timeout is cleared on success
fail = setTimeout(function () {
if (!Highcharts.maps[mapKey]) {
chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
fail = setTimeout(function () {
chart.hideLoading();
}, 1000);
}
}, 3000);
// Show the spinner
chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner
// Load the drilldown map
$.getScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', function () {
data = Highcharts.geojson(Highcharts.maps[mapKey]);
// Set a non-random bogus value
$.each(data, function (i) {
this.value = i;
});
// Hide loading and add series
chart.hideLoading();
clearTimeout(fail);
chart.addSeriesAsDrilldown(e.point, {
name: e.point.name,
data: data,
dataLabels: {
enabled: true,
format: '{point.name}'
}
});
});
}
this.setTitle(null, { text: e.point.name });
},
drillup: function () {
this.setTitle(null, { text: '' });
}
}
This is sample code for states.json
"features": [
{
"type": "Feature",
"id": "MY.SA",
"properties": {
"hc-group": "admin1",
"hc-middle-x": 0.32,
"hc-middle-y": 0.6,
"hc-key": "my-sa",
"hc-a2": "SA",
"labelrank": "6",
"hasc": "MY.SA",
"alt-name": "North Borneo",
"woe-id": "2346310",
"subregion": null,
"fips": "MY16",
"postal-code": "SA",
"name": "Sabah",
"country": "Malaysia",
"type-en": "State",
"region": null,
"longitude": "117.095",
"woe-name": "Sabah",
"latitude": "5.31115",
"woe-label": "Sabah, MY, Malaysia",
"type": "State"
},
This is sample code for district in district.json
{
"type": "Feature",
"properties": {
"GID_0": "MYS",
"NAME_0": "Malaysia",
"GID_1": "MYS.13_1",
"NAME_1": "Sabah",
"NL_NAME_1": null,
"GID_2": "MYS.13.1_1",
"NAME_2": "Beaufort",
"VARNAME_2": null,
"NL_NAME_2": null,
"TYPE_2": "Daerah",
"ENGTYPE_2": "District",
"CC_2": null,
"HASC_2": "MY.SA.BF",
"ISO": "MY-12",
"ISO_district": "MY-12.1"
},
I need to use getJSON function right? Can someone help me how to do the declaration in the javascript file?

Amchart Clicklabel event not working

I m fairly new to Amchart library and facing a problem with clickLabel event of legend.
here is the Javascript code I have tried:
var chart = AmCharts.makeChart("chartdiv", {
"type": "serial",
"theme": "light",
"legend": {
"horizontalGap": 10,
"maxColumns": 1,
"position": "right",
"useGraphSettings": true,
"markerSize": 10,
"listeners": [{
"event": "clickMarker",
"method": function(e) {
document.getElementById('clicked').textContent =
e.dataItem.title + ' - marker status before toggle: ' + e.dataItem.hidden;
}
}]
},
chart.legend.addListener('clickLabel', function(event) {
document.getElementById('clicked').textContent =
e.dataItem.title + ' - marker status before toggle: ' + e.dataItem.hidden;
});
here is Jsfiddle: http://jsfiddle.net/Shivin15/15k53omf/2/
Thank you for your help!
You'll need to set textClickEnabled to true.
Check the updated example here: http://jsfiddle.net/15k53omf/3/

Change pin color in javascript map?

We're using an amcharts map, and so far, it all looks pretty good.
What I'm trying to do is change the color of the pins based on some value coming from our json stream.
javascript:
AmCharts.makeChart("mapdiv", {
"type": "map",
"theme": "light",
"imagesSettings": {
"rollOverColor": "#089282",
"rollOverScale": 1,
"selectedScale": 0.5,
"selectedColor": "#089282",
"color": "#13564e",
"selectable": false,
"bringForwardOnHover": false
},
"areasSettings": {
"color": "#D3D3D3",
"autoZoom": true
},
"data": {
"map": "puertoRicoHigh",
"getAreasFromMap": true
},
"dataLoader": {
"url": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/716619/30189.json",
"format": "json",
"showErrors": true,
"postProcess": function(data, config, map) {
// create a new dataProvider
var mapData = map.data;
// init images array
if (mapData.images === undefined)
mapData.images = [];
// create images out of loaded data
for(var i = 0; i < data.length; i++) {
var image = data[i];
image.type = "circle";
mapData.images.push(image);
}
return mapData;
}
}
});
That works well, but I would like to change the pins being displayed in the map. Ideally, I would like to use images (jpg, png, etc) that I've downloaded from the web.
So let's say that my json looks like this:
[{"title":"Site1","longitude":18.4262,"latitude":-67.1483,"inservice":true},
{"title":"Site2","longitude":18.3663,"latitude":-66.1887,"inservice":false}]
How can I change the pin color/size/font (or even image) so that if "inservice" is true, then use one pin. If it's false, then use another pin.
I tried using the SO snippet tool, but it's not rendering the map. So here it is, in jsfiddle: https://jsfiddle.net/wn61bfqb/
AmCharts.makeChart("mapdiv", {
"type": "map",
"theme": "light",
"imagesSettings": {
"rollOverColor": "#089282",
"rollOverScale": 1,
"selectedScale": 0.5,
"selectedColor": "#089282",
"color": "#13564e",
"selectable": false,
"bringForwardOnHover": false
},
"areasSettings": {
"color": "#D3D3D3",
"autoZoom": true
},
"data": {
"map": "puertoRicoHigh",
"getAreasFromMap": true
},
"dataLoader": {
"url": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/716619/30189.json",
"format": "json",
"showErrors": true,
"postProcess": function(data, config, map) {
// create a new dataProvider
var mapData = map.data;
// init images array
if (mapData.images === undefined)
mapData.images = [];
// create images out of loaded data
for(var i = 0; i < data.length; i++) {
var image = data[i];
image.type = "circle";
mapData.images.push(image);
}
return mapData;
}
}
});
#mapdiv {
width: 100%;
height: 300px;
<script src="https://www.amcharts.com/lib/3/ammap.js"></script>
<script src="https://www.amcharts.com/lib/3/maps/js/puertoRicoHigh.js"></script>
<script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script>
<link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" />
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<script src="https://www.amcharts.com/lib/3/plugins/dataloader/dataloader.js"></script>
<div id="mapdiv"></div>
Thanks.
inside the dataLoader function where your are looping through the datasets add a check if inservice is true. Based on this check add a color.
for (var i = 0; i < data.length; i++) {
var image = data[i];
image.type = "circle";
if(data[i].inservice){
image.color = 'green'; // if inservice is true
} else {
image.color = 'red'; // if inservice is false or undefined
}
mapData.images.push(image);
}
I noticed that the end point you are calling to create this map is not returning inservice field yet. So till then we end up showing red pin all the time.
jsFiddle link

Google charts: identify a specific control

Is there a way to identify which control in a set of bound controls is changed by the user?
In this instance I want to know that in a set of 5 bound controls, the user just changed control 3.
I want to resize the div that the control is within, based on the number of distinct values the user has chosen. I can get these, but I cannot identify which control has been changed.
So, something like:
var controlPicker1 = new google.visualization.ControlWrapper({
"controlType": "CategoryFilter",
"containerId": "control1",
"options": {
"filterColumnLabel": "Media source",
"ui": {
"labelStacking": "horizontal",
"allowTyping": true,
"allowMultiple": true
}
}
});
var view = new google.visualization.DataView(data);
barChart = new google.visualization.ChartWrapper({
"chartType": "BarChart",
"containerId": "chart_div",
"options": {
"width": "100%",
"height": "120%",
"vAxis": {title: "Media source (Branch - Dialled number)"},
"hAxis": {title: "Number of calls"},
"fontSize": 14,
"chartArea": {top: 0, right: 0, bottom: 0, height:"100%", width:"70%"}
},
"view": {"columns": [0,6,7,8,9,10,11]}
});
google.visualization.events.addListener(dashboard, "ready", function() {
barChart.draw();
resizeControl("control1", 50, barChart.getDataTable().getDistinctValues(1), 500);
}
});
dashboard.bind(controlPicker1, controlPicker2);
dashboard.bind(controlPicker2, controlPicker3);
dashboard.bind(controlPicker3, controlPicker4);
dashboard.bind(controlPicker4, controlPicker5);
dashboard.bind(controlPicker5, barChart);
dashboard.draw(view);
}
function resizeControl(name, total, div1, length) {
var control=div1.length;
if(total>control){
var div=document.getElementById(name);
var w=parseInt(div.style.width);
var revs=($(this).width()/length);
var newh = 35;
for (var i=0; i <(control / revs); i++) {
if(i>0)newh = newh+25;
}
newh + "px";
$(div).height(newh);
}
}
Thanks,
H.
There's not a lot of information in your post. So I'll show you how to responder to a sort event in a Table.
google.visualization.events.addListener(table, 'sort',
function(event) {
data.sort([{column: event.column, desc: !event.ascending}]);
chart.draw(view);
});
So depending on your chart type:
google.visualization.events.addListener(map, 'select',
function() {
table.setSelection(map.getSelection());
});
Find the event you want, add the listener to the chart.

Categories

Resources