
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import * as am5 from "@amcharts/amcharts5";
import * as am5map from "@amcharts/amcharts5/map";
import am5geodata_worldLow from "@amcharts/amcharts5/geodata/worldLow";
import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
/**
* ---------------------------------------
* This demo was created using amCharts 5.
*
* For more information visit:
* https://www.amcharts.com/
*
* Documentation is available at:
* https://www.amcharts.com/docs/v5/
* ---------------------------------------
*/
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
const root = am5.Root.new("chartdiv");
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([am5themes_Animated.new(root)]);
// Create the map chart
// https://www.amcharts.com/docs/v5/charts/map-chart/
const chart = root.container.children.push(
am5map.MapChart.new(root, {
panX: "rotateX",
panY: "rotateY",
projection: am5map.geoMercator()
})
);
// Create series for background fill
// https://www.amcharts.com/docs/v5/charts/map-chart/map-polygon-series/#Background_polygon
const backgroundSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {}));
backgroundSeries.mapPolygons.template.setAll({
fill: root.interfaceColors.get("alternativeBackground"),
fillOpacity: 0,
strokeOpacity: 0
});
// Add background polygo
// https://www.amcharts.com/docs/v5/charts/map-chart/map-polygon-series/#Background_polygon
backgroundSeries.data.push({
geometry: am5map.getGeoRectangle(90, 180, -90, -180)
});
// Create main polygon series for countries
// https://www.amcharts.com/docs/v5/charts/map-chart/map-polygon-series/
const polygonSeries = chart.series.push(
am5map.MapPolygonSeries.new(root, {
geoJSON: am5geodata_worldLow
})
);
// Create point series for Sun icon
// https://www.amcharts.com/docs/v5/charts/map-chart/map-point-series/
const sunSeries = chart.series.push(am5map.MapPointSeries.new(root, {}));
sunSeries.bullets.push(function () {
const circle = am5.Circle.new(root, {
radius: 18,
fill: am5.color(0xffba00),
filter: "blur(5px)"
});
circle.animate({
key: "radius",
duration: 2000,
to: 23,
loops: Infinity,
easing: am5.ease.yoyo(am5.ease.linear)
});
return am5.Bullet.new(root, {
sprite: circle
});
});
sunSeries.bullets.push(function () {
return am5.Bullet.new(root, {
sprite: am5.Circle.new(root, {
radius: 14,
fill: am5.color(0xffba00)
})
});
});
const sunDataItem = sunSeries.pushDataItem({});
// Create polygon series for night-time polygons
// https://www.amcharts.com/docs/v5/charts/map-chart/map-polygon-series/
const nightSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {}));
nightSeries.mapPolygons.template.setAll({
fill: am5.color(0x000000),
fillOpacity: 0.25,
strokeOpacity: 0
});
const nightDataItem0 = nightSeries.pushDataItem({});
const nightDataItem1 = nightSeries.pushDataItem({});
const nightDataItem2 = nightSeries.pushDataItem({});
// Create controls
const container = chart.children.push(
am5.Container.new(root, {
y: am5.percent(95),
centerX: am5.p50,
x: am5.p50,
width: am5.percent(80),
layout: root.horizontalLayout
})
);
const playButton = container.children.push(
am5.Button.new(root, {
themeTags: ["play"],
centerY: am5.p50,
marginRight: 15,
icon: am5.Graphics.new(root, {
themeTags: ["icon"]
})
})
);
playButton.events.on("click", function () {
if (playButton.get("active")) {
slider.set("start", slider.get("start") + 0.0001);
} else {
slider.animate({
key: "start",
to: 1,
duration: 15000 * (1 - slider.get("start"))
});
}
});
const slider = container.children.push(
am5.Slider.new(root, {
orientation: "horizontal",
start: 0.5,
centerY: am5.p50
})
);
slider.on("start", function (start) {
if (start === 1) {
playButton.set("active", false);
}
});
slider.events.on("rangechanged", function () {
updateDateNight(
(slider.get("start", 0) - 0.5) * am5.time.getDuration("day", 2) +
new Date().getTime()
);
});
const cont = chart.children.push(
am5.Container.new(root, {
layout: root.horizontalLayout,
x: 20,
y: 40
})
);
cont.children.push(
am5.Label.new(root, {
centerY: am5.p50,
text: "Map"
})
);
const switchButton = cont.children.push(
am5.Button.new(root, {
themeTags: ["switch"],
centerY: am5.p50,
icon: am5.Circle.new(root, {
themeTags: ["icon"]
})
})
);
switchButton.on("active", function () {
if (!switchButton.get("active")) {
chart.set("projection", am5map.geoMercator());
chart.set("panY", "translateY");
chart.set("panX", "translateX");
backgroundSeries.mapPolygons.template.set("fillOpacity", 0);
} else {
chart.set("projection", am5map.geoOrthographic());
chart.set("panY", "rotateY");
chart.set("panX", "rotateX");
backgroundSeries.mapPolygons.template.set("fillOpacity", 0.1);
}
});
cont.children.push(
am5.Label.new(root, {
centerY: am5.p50,
text: "Globe"
})
);
chart.appear(1000, 100);
function updateDateNight(time) {
const sunPosition = solarPosition(time);
sunDataItem.set("longitude", sunPosition.longitude);
sunDataItem.set("latitude", sunPosition.latitude);
const nightPosition = {
longitude: sunPosition.longitude + 180,
latitude: -sunPosition.latitude
};
nightDataItem0.set("geometry", am5map.getGeoCircle(nightPosition, 92));
nightDataItem1.set("geometry", am5map.getGeoCircle(nightPosition, 90));
nightDataItem2.set("geometry", am5map.getGeoCircle(nightPosition, 88));
}
const offset = new Date().getTimezoneOffset() * 60 * 1000;
//updateDateNight(new Date().getTime());
// all sun position calculation is taken from: http://bl.ocks.org/mbostock/4597134
function solarPosition(time) {
const centuries = (time - Date.UTC(2000, 0, 1, 12)) / 864e5 / 36525; // since J2000
const longitude =
((am5.time.round(new Date(time), "day", 1).getTime() - time - offset) /
864e5) *
360 -
180;
return am5map.normalizeGeoPoint({
longitude: longitude - equationOfTime(centuries) * am5.math.DEGREES,
latitude: solarDeclination(centuries) * am5.math.DEGREES
});
}
// Equations based on NOAA’s Solar Calculator; all angles in RADIANS.
// http://www.esrl.noaa.gov/gmd/grad/solcalc/
function equationOfTime(centuries) {
const e = eccentricityEarthOrbit(centuries),
m = solarGeometricMeanAnomaly(centuries),
l = solarGeometricMeanLongitude(centuries),
y = Math.tan(obliquityCorrection(centuries) / 2);
y *= y;
return (
y * Math.sin(2 * l) -
2 * e * Math.sin(m) +
4 * e * y * Math.sin(m) * Math.cos(2 * l) -
0.5 * y * y * Math.sin(4 * l) -
1.25 * e * e * Math.sin(2 * m)
);
}
function solarDeclination(centuries) {
return Math.asin(
Math.sin(obliquityCorrection(centuries)) *
Math.sin(solarApparentLongitude(centuries))
);
}
function solarApparentLongitude(centuries) {
return (
solarTrueLongitude(centuries) -
(0.00569 +
0.00478 * Math.sin((125.04 - 1934.136 * centuries) * am5.math.RADIANS)) *
am5.math.RADIANS
);
}
function solarTrueLongitude(centuries) {
return (
solarGeometricMeanLongitude(centuries) + solarEquationOfCenter(centuries)
);
}
function solarGeometricMeanAnomaly(centuries) {
return (
(357.52911 + centuries * (35999.05029 - 0.0001537 * centuries)) *
am5.math.RADIANS
);
}
function solarGeometricMeanLongitude(centuries) {
const l = (280.46646 + centuries * (36000.76983 + centuries * 0.0003032)) % 360;
return ((l < 0 ? l + 360 : l) / 180) * Math.PI;
}
function solarEquationOfCenter(centuries) {
const m = solarGeometricMeanAnomaly(centuries);
return (
(Math.sin(m) * (1.914602 - centuries * (0.004817 + 0.000014 * centuries)) +
Math.sin(m + m) * (0.019993 - 0.000101 * centuries) +
Math.sin(m + m + m) * 0.000289) *
am5.math.RADIANS
);
}
function obliquityCorrection(centuries) {
return (
meanObliquityOfEcliptic(centuries) +
0.00256 *
Math.cos((125.04 - 1934.136 * centuries) * am5.math.RADIANS) *
am5.math.RADIANS
);
}
function meanObliquityOfEcliptic(centuries) {
return (
(23 +
(26 +
(21.448 -
centuries * (46.815 + centuries * (0.00059 - centuries * 0.001813))) /
60) /
60) *
am5.math.RADIANS
);
}
function eccentricityEarthOrbit(centuries) {
return 0.016708634 - centuries * (0.000042037 + 0.0000001267 * centuries);
}