Change to blinking pin in javascript map? - javascript

My javascript map is reading from a json stream that looks like this:
[{"title":"Site1","latitude":18.3764,"longitude":-67.1819},
{"title":"Site2","latitude":18.2001,"longitude":-65.8081},
{"title":"Site3","latitude":18.3878,"longitude":-66.0998}]
The points are being drawn correctly, so that's great.
To this json I'll be adding an inService field. The inService field will be any of the following options: [Monday, Tuesday, Sunday, Thursday] and the json will look like this:
[{"title":"Site1","latitude":18.3764,"longitude":-67.1819,"inService":"Monday"},
{"title":"Site2","latitude":18.2001,"longitude":-65.8081,"inService":"Tuesday"},
{"title":"Site3","latitude":18.3878,"longitude":-66.0998,"inService":"Sunday"},
{"title":"Site4","latitude":18.1246,"longitude":-66.2607,"inService":"Thursday"}]
At the amcharts website, I saw these two new icons: One that blinks and another that's a dot with a circle around it.
So my question is: Using the json above, how can I assign a blinking pin to the different types of values in inService?
For example:
Monday: blinking blue pin
Tuesday: blinking black pin
Sunday: white dot with a circle around it (no blink)
Thursday red dot with a circle around it (no blink)
And finally, we will be adding other types of status. How can I change the shapes? For example, the pins at the top will be squared instead of round?
Thanks for any help.
I tried using SO code preview, but it's not rendering the map. So I've also included it in jsfiddle:
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>

Related

Reading a local geojson file with Mapbox

I am currently trying to make a simple visualization using Mapbox that is based on additional data provided by a local geojson file. I cannot upload this file to Mapbox and would like to keep it local.
I have used this base code from Mapbox that I have modified to include a local geojson file that is structured like this:
{"features": [{"geometry": null, "location": {"coordinates": [40.730610, -73.935242], "type": "Point"}, "properties": {"X": "1", "group": "1"}, "type": "Feature"},...}
I have modified the example code from Mapbox so that it is now:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Style circles with a data-driven property</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.js'></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoibG9ubmliZXNhbmNvbiIsImEiOiJjamxjaWNpOHQwMHV0M3FwaHhneGhvY2l2In0.7GxI8W_dnTKITNF4hEvZeQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
zoom: 12,
center: [-73.935242, 40.730610],
pitch: 20,
});
var url = "GeoObs.json.json"
map.on('load', function () {
var layers = map.getStyle().layers;
var labelLayerId;
for (var i = 0; i < layers.length; i++) {
if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
labelLayerId = layers[i].id;
break;
}
}
map.addSource("my_data", {
type: "geojson",
data: url //"./GeoObs.json",
/*cluster: true,
clusterMaxZoom: 15, // Max zoom to cluster points on
clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)*/
});
map.addLayer({
'id': 'population',
'type': 'circle',
source: 'my_data',
'source-layer': 'my_data',
'paint': {
// make circles larger as the user zooms from z12 to z22
'circle-radius': {
'base': 1.75,
'stops': [[12, 2], [22, 180]]
},
// color circles by ethnicity, using a match expression
// https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-match
'circle-color': [
'match',
['get', 'group'],
'1', '#fbb03b',
'2', '#223b53',
'3', '#e55e5e',
'4', '#3bb2d0',
/* other */ '#ccc'
]
}
});
map.addLayer({
'id': '3d-buildings',
'source': 'composite',
'source-layer': 'building',
'filter': ['==', 'extrude', 'true'],
'type': 'fill-extrusion',
'minzoom': 15,
'paint': {
'fill-extrusion-color': '#aaa',
// use an 'interpolate' expression to add a smooth transition effect to the
// buildings as the user zooms in
'fill-extrusion-height': [
"interpolate", ["linear"], ["zoom"],
15, 0,
15.05, ["get", "height"]
],
'fill-extrusion-base': [
"interpolate", ["linear"], ["zoom"],
10, 0,
15.05, ["get", "min_height"]
],
'fill-extrusion-opacity': .6
}
}, labelLayerId);
});
</script>
</body>
</html>
I get the following error:
Error: Source layer "my_data" does not exist on source "my_data" as specified by style layer "population"
at i._validateLayer (style.js:274)
at i.addLayer (style.js:576)
at o.addLayer (map.js:1175)
at o.<anonymous> (index3.html:52)
at o.L.fire (evented.js:115)
at o._render (map.js:1619)
at map.js:1683
Can anyone point me in the direction of a possible mistake here and hopefully how to fix it. You can use the example geojson I gave you to try out this example. Just copy paste it into a file called: GeoObs.json if you want the code to right away give the same error.
As the error states, your GeoJSON source does not have a source layer. So you can remove the 'source-layer' property from the map.addLayer call.
Your GeoJSON also needs to be modified to a proper FeatureCollection:
{
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "Point",
"coordinates": [
-73.935242,
40.730610
]
},
"properties": {
"X": "1",
"group": "1"
},
"type": "Feature"
}
]
}
For the population layer, comment out the line, because you do not have such a layer:
'source-layer': 'my_data',
And maybe you have an extra ".json" in the URL:
GeoObs.json.json
[ https://jsfiddle.net/c5nauwgx/ ]
This example from MapLibre helped me and also works with Mapbox GL JS. It adds a little interactivity to your map by giving you the option to select a local geojson file within the map.
https://maplibre.org/maplibre-gl-js-docs/example/local-geojson/

How to use a slider to animate an amcharts pie chart?

So I'm currently animating a pie chart using js and amcharts and was wondering if it was possible to use a slider to do so, instead of a time delay. So instead of having it change the current day every 1.5s you'd select the day you want to see the data for using a slider. Is that even possible using js ?
Thanks in advance ! :)
Ok, let's start.
First, you should know that sliders (<input> with type="range") have event onchange.
Second, is that you can pass a value of a slider to a function, which could be associated with your chart data.
Something like that:
const daysInMonth = 30 // just as an example
var chart = AmCharts.makeChart( "chartdiv", {
"type": "pie",
"theme": "light",
"dataProvider": [ {
"day": 1
},
{
"day": daysInMonth - 1
}],
"valueField": "day",
"titleField": "day",
"balloon": {
"fixedPosition":true
},
"export": {
"enabled": true
}
} );
function changeDay(value) {
chart.dataProvider[0].day = value;
chart.dataProvider[1].day = daysInMonth - value;
chart.validateData();
}
#chartdiv {
width: 100%;
height: 200px;
}
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/pie.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>
<h4>Day of a month</h4><input type="range" min="1" max="30" step="1" value="1" onchange="changeDay(this.value)">
<div id="chartdiv"></div>
This is just a quick example of how can you use your slider's value. Have a good day!

Dashed line transforms the null values into zeros on the chart

I created a chart with Billboard.js (a chart library based on d3 v4+).
My aim was to make the lines look dashed so I used this documentation for it.
Basically, I added this code:
const regions = {}
for(const item of baselineTitle) {
regions[item]=[];
regions[item].push({"style" : "dashed"});
}
inside bb.generate:
var chart = bb.generate({
"data": {
"type": "spline",
"x": "x",
"columns": columns,
"regions": regions
},
...
When the lines are not dashed everything it's fine. I have no line on the chart for null values.
When it is dashed, it has a line on zero for all null values.
This is how my chart looks like, I put yellow color where it shouldn't be a line because the values are null for that part.
The array containing the values for that line is this one:
0:"char id"
1:null
2:null
3:null
4:2230.181884765625
5:2230.181884765625
6:2230.181884765625
7:2230.181884765625
8:2230.181884765625
9:2230.181884765625
10:2230.181884765625
11:2230.181884765625
12:2230.181884765625
13:2230.181884765625
14:2230.181884765625
15:2230.181884765625
16:4568.82470703125
17:4870.001953125
18:4671.97607421875
19:4767.93603515625
20:4729.97607421875
21:4721.1591796875
22:4799.16357421875
23:4864.5068359375
24:3512.424072265625
25:2924.76513671875
26:3047.808837890625
27:3052.245361328125
28:3045.63427734375
29:2930.223388671875
30:2410.9541015625
31:2116.904052734375
32:2064.01806640625
33:2159.795654296875
34:2232.72412109375
35:2669.738037109375
36:3420.1669921875
37:4515.5537109375
38:4703.1435546875
39:4993.89501953125
40:5207.1259765625
41:5056.1904296875
42:5222.80517578125
43:5509.8447265625
44:5453.8798828125
45:5206.78466796875
46:5155.16748046875
47:5082.36083984375
48:4002.560302734375
49:3587.09716796875
50:3569.875732421875
51:3328.478515625
52:3167.501953125
53:2847.85009765625
54:2208.728759765625
55:2152.306396484375
56:2085.06640625
57:2145.009521484375
58:2170.032958984375
59:2666.60107421875
60:3379.564208984375
61:4388.9384765625
62:4549.611328125
63:5117.0029296875
64:5279.7353515625
65:5314.0751953125
66:5404.16552734375
67:5757.20068359375
68:5631.9619140625
69:5716.732421875
70:5763.24560546875
71:5598.005859375
72:null
73:null
74:null
75:null
76:null
77:null
78:null
79:null
80:null
81:null
82:null
83:null
84:null
85:null
86:null
87:null
88:null
89:null
90:null
91:null
92:null
93:null
94:null
95:null
96:null
97:null
98:null
99:null
Do you know what's the problem here?
If you don't need to set a specific region of the line to be dashed, with the css stroke-dasharrayattribute will be more easier to implement that.
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
Check out the below snippet.
bb.generate({
data: {
columns: [
["data1", 100, 200, 1000, 900, 500],
["data2", 20, 40, null, 300, 200]
],
type: "spline"
},
point: {
show: false
}
});
.bb-lines-data2 {
stroke-dasharray: 2 4;
stroke-width: 2px;
}
<!doctype html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/billboard.js/dist/billboard.pkgd.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/billboard.js/dist/billboard.min.css">
</head>
<body>
<div id="chart"></div>
</body>
</html>

Change color of selected area in amMap with different color from adjacent area,

In amcharts amMap, when one selects a region then it changes its color. But every time, it is the same color, when select multi areas. How to make it a different color with every selection and the color of an area should be different from the adjacent areas.
JsFiddle
var map = AmCharts.makeChart("chartdiv", {
"type": "map",
"theme": "black",
"panEventsEnabled": true,
"backgroundColor": "#00aeff",
"backgroundAlpha": 1,
"dataProvider": {
"map": "indiaLow",
"getAreasFromMap": true,
"images": [{
"id": "backButton",
"label": "Back to continents map",
"rollOverColor": "#ffffff",
"labelRollOverColor": "#ffffff",
"useTargetsZoomValues": true,
"right": 100,
"top": 30,
"labelFontSize": 10,
"selectable": true,
"imageURL": "http://simplemaps.com/static/svg/in/in.svg",
"width": 32,
"height": 32,
"label": "District Level Map"
}]
},
"areasSettings": {
"autoZoom": false,
"color": "#CDCDCD",
"colorSolid": "#5EB7DE",
"selectedColor": "#5EB7DE",
"selectedColor": getRandomColor(),
"outlineColor": "#666666",
"rollOverColor": "#ffffff",
"rollOverOutlineColor": "#FFFFFF",
"selectable": true
},
"listeners": [{
"event": "clickMapObject",
"method": function(event) {
//I tried this but not working. I think map is not taking the new areasettinng values.
map.areasSettings = {selectedColor : ""};
map.areasSettings = {selectedColor : getRandomColor()};
map.selectedObject = map.dataProvider;
event.mapObject.showAsSelected = !event.mapObject.showAsSelected;
map.returnInitialColor(event.mapObject);
var states = [];
for (var i in map.dataProvider.areas) {
var area = map.dataProvider.areas[i];
if (area.showAsSelected) {
states.push(area.title);
}
}
}
}],
"export": {
"enabled": false
}
});
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
#chartdiv {
width: 100%;
height: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.amcharts.com/lib/3/ammap.js"></script>
<script src="https://www.amcharts.com/lib/3/maps/js/indiaLow.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/black.js"></script>
<div id="chartdiv"></div>
The selection of an area give some color to that area and then another area selected then it should be given another color. How to achieve this thing?
You have to assign the new individual color to the area itself and then call validateNow or validateData afterward to redraw the map with the changes. Setting it in areasSettings will potentially change all of the areas' colors (though, in your case, it won't do anything since you didn't call validateNow/Data). Here's your updated clickMapObject event:
"listeners": [{
"event": "clickMapObject",
"method": function(event) {
map.selectedObject = map.dataProvider;
event.mapObject.showAsSelected = !event.mapObject.showAsSelected;
map.returnInitialColor(event.mapObject);
var states = [];
for (var i in map.dataProvider.areas) {
var area = map.dataProvider.areas[i];
if (area.showAsSelected) {
//set a new color only if it wasn't assigned before
area.selectedColor = area.selectedColor || getRandomColor();
states.push(area.title);
}
}
// set same zoom levels to retain map position/zoom in case a selection was made after a zoom
map.dataProvider.zoomLevel = map.zoomLevel();
map.dataProvider.zoomLatitude = map.dataProvider.zoomLatitude = map.zoomLatitude();
map.dataProvider.zoomLongitude = map.dataProvider.zoomLongitude = map.zoomLongitude();
map.validateNow(); //redraw the map with the new selection/colors.
}
}],
Demo below:
var map = AmCharts.makeChart("chartdiv", {
"type": "map",
"theme": "black",
"panEventsEnabled": true,
"backgroundColor": "#00aeff",
"backgroundAlpha": 1,
"dataProvider": {
"map": "indiaLow",
"getAreasFromMap": true,
"images": [{
"id": "backButton",
"label": "Back to continents map",
"rollOverColor": "#ffffff",
"labelRollOverColor": "#ffffff",
"useTargetsZoomValues": true,
"right": 100,
"top": 30,
"labelFontSize": 10,
"selectable": true,
"imageURL": "http://simplemaps.com/static/svg/in/in.svg",
"width": 32,
"height": 32,
"label": "District Level Map"
}]
},
"areasSettings": {
"autoZoom": false,
"color": "#CDCDCD",
"colorSolid": "#5EB7DE",
"selectedColor": "#5EB7DE",
"selectedColor": getRandomColor(),
"outlineColor": "#666666",
"rollOverColor": "#ffffff",
"rollOverOutlineColor": "#FFFFFF",
"selectable": true
},
"listeners": [{
"event": "clickMapObject",
"method": function(event) {
map.selectedObject = map.dataProvider;
event.mapObject.showAsSelected = !event.mapObject.showAsSelected;
map.returnInitialColor(event.mapObject);
var states = [];
for (var i in map.dataProvider.areas) {
var area = map.dataProvider.areas[i];
if (area.showAsSelected) {
//set a new color only if it wasn't assigned before
area.selectedColor = area.selectedColor || getRandomColor();
states.push(area.title);
}
}
// set same zoom levels to retain map position/zoom in case a selection was made after a zoom
map.dataProvider.zoomLevel = map.zoomLevel();
map.dataProvider.zoomLatitude = map.dataProvider.zoomLatitude = map.zoomLatitude();
map.dataProvider.zoomLongitude = map.dataProvider.zoomLongitude = map.zoomLongitude();
map.validateNow(); //redraw the map with the new selection/colors.
}
}],
"export": {
"enabled": false
}
});
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
#chartdiv {
width: 100%;
height: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.amcharts.com/lib/3/ammap.js"></script>
<script src="https://www.amcharts.com/lib/3/maps/js/indiaLow.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/black.js"></script>
<div id="chartdiv"></div>

Color Bar Graph in xcharts

Has anyone changed the colors of the bar graph in xcharts? Any idea how to do so?
The plain navy blue is so boring:
http://tenxer.github.io/xcharts/examples/
Thanks,
Philip
Based on the documentation it does not appear the library has built in methods for styling the chart, but rather:
The best way to style charts is to start with the included stylesheet,
or use your browser's element inspector to see each elements CSS class
selectors that are available to use.
Each series has a class: .color0 through .colorN, so you could use the css to set the properties of each rectangle:
var data = {
"xScale": "ordinal",
"yScale": "linear",
"main": [
{
"className": ".pizza",
"data": [
{
"x": "Pepperoni",
"y": 4
},
{
"x": "Cheese",
"y": 8
}
]
}
]
};
var myChart = new xChart('bar', data, '#chart');
.color0 rect {
fill: orange !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xcharts/0.3.0/xcharts.js"> </script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/xcharts/0.3.0/xcharts.css">
<figure style="width: 400px; height: 300px;" id="chart"></figure>
Alternatively, you could use a d3 selection to alter the colors:
d3.selectAll(".color0").selectAll("rect").style("fill","orange");
var data = {
"xScale": "ordinal",
"yScale": "linear",
"main": [
{
"className": ".pizza",
"data": [
{
"x": "Pepperoni",
"y": 4
},
{
"x": "Cheese",
"y": 8
}
]
}
]
};
var myChart = new xChart('bar', data, '#chart');
d3.selectAll(".color0").selectAll("rect").style("fill","orange");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xcharts/0.3.0/xcharts.js"> </script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/xcharts/0.3.0/xcharts.css">
<figure style="width: 400px; height: 300px;" id="chart"></figure>
If you just want all rectangles to be a certain color, then d3.selectAll("rect").style("fill","color") will work.
In Xchart we can add color of the bar using seriesColors method.
CategoryChart chart = new CategoryChartBuilder()
.yAxisTitle("ABC Title")
.theme(Styler.ChartTheme.GGPlot2).build();
chart.getStyler().setSeriesColors(new Color[]{Color.blue, Color.cyan, Color.LIGHT_GRAY, new Color(224,43,54), new Color(24,43,124)});

Categories