Oil exports from six terminals in the Gulf states to ports in Asia and Europe, drawn as Sankey bands on a globe: the wider the band, the more oil. The bands follow sea lanes through waypoints, with drops of oil traveling along them.
A map Sankey series draws each flow as a band as wide as its value, and stacks the bands that leave or reach the same place, so the busiest routes stand out. Waypoints bend a band through set points, here to keep the tankers at sea through Hormuz, Malacca and Suez. The volumes are approximate, in thousands of barrels a day.
Built with amCharts 5, a JavaScript library. The JavaScript includes your theme and renderer (canvas or SVG); the JSON also follows the changes you make with the controls.
npm install @amcharts/amcharts5 and @amcharts/amcharts5-geodata. See Getting started.
The same chart as a JSON config. Chart Maker reads and writes this format, the library's JSON parser turns it into a chart, and the <am5-chart> element puts it on a page with no code."type" is the class to create and "settings" what you would pass to its new() in code; "properties" fill in its parts, lists such as series and axes or templates such as columns.template; "refs" holds objects used in more than one place ("#series-0" stands for the one named series-0); a string starting with "@" takes a value from another object, such as "@series.get('fill')".
A complete page. Save it as an .html file and open it in a browser.
Paste this into an AI coding assistant to build the chart from scratch. More in amCharts & AI.
var root = am5.Root.new("chartdiv");
var oilTheme = am5.Theme.new(root); // a custom theme: the oil colors for buttons and text
oilTheme.rule("InterfaceColors").setAll({
primaryButton: am5.color(0x1e2824), // buttons, such as the zoom control...
primaryButtonHover: am5.color(0x3a5040), // ...under the pointer...
primaryButtonDown: am5.color(0x0a0e12), // ...while pressed...
primaryButtonActive: am5.color(0xc8890a), // ...and when switched on
primaryButtonText: am5.color(0xf5d090), // button icons and labels
secondaryButton: am5.color(0x1e2824),
secondaryButtonHover: am5.color(0x3a5040),
secondaryButtonDown: am5.color(0x141a1a),
secondaryButtonText: am5.color(0xf5d090),
background: am5.color(0x0a0e12),
text: am5.color(0xf5d090) // default text color
});
root.setThemes([am5themes_Animated.new(root), oilTheme, am5themes_Responsive.new(root)]);
// Crude & Tar palette
var deepCrude = am5.color(0x141a1a); // ocean — very dark teal-black
var slick = am5.color(0x1e2824); // land dark — oil slick green-black
var pipeline = am5.color(0x3a5040); // accents — industrial dark green
var amber = am5.color(0xc8890a); // primary — dark amber / crude oil
var sulfur = am5.color(0xa89050); // secondary — sulfurous yellow-brown
var flare = am5.color(0xf5d090); // text/highlights — gas flare warm
// ---- Chart (start zoomed out at home) ----
var chart = root.container.children.push(am5map.MapChart.new(root, {
panX: "rotateX", // a sideways drag spins the globe
panY: "rotateY", // an up or down drag tilts it
projection: am5map.geoOrthographic(), // a globe, seen from space
homeGeoPoint: { longitude: 0, latitude: 0 }, // home view: centered on longitude 0, latitude 0...
homeRotationX: 0, // ...not spun...
homeRotationY: 0, // ...not tilted...
homeZoomLevel: 1, // ...and at the fitted size
minZoomLevel: 0.8, // zoom out to 80% of the fitted size at most
zoomLevel: 1, // start at the fitted size
background: am5.Rectangle.new(root, {
fill: am5.color(0x0a0e12), // near-black space around the globe
fillOpacity: 1,
stroke:am5.color(0x0a0e12),
strokeOpacity: 1
})
}));
// ---- Ocean background ----
var bgSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {}));
bgSeries.mapPolygons.template.setAll({
fill: deepCrude, // dark ocean
fillOpacity: 1, // solid; the flat map views turn it off
strokeOpacity: 0 // no outline
});
// one polygon that covers the whole Earth: the ocean
bgSeries.data.push({ geometry: am5map.getGeoRectangle(90, 180, -90, -180) });
// ---- Graticule ----
var graticuleSeries = chart.series.push(am5map.GraticuleSeries.new(root, {}));
graticuleSeries.mapLines.template.setAll({
stroke: pipeline, // grid lines in dark green...
strokeOpacity: 0.25, // ...faint...
strokeWidth: 0.5 // ...and thin
});
// ---- Countries ----
var polygonSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {
geoJSON: am5geodata_worldLow // country shapes from the low-detail world map
}));
polygonSeries.mapPolygons.template.setAll({
fill: slick, // dark land
stroke: pipeline, // dark green borders...
strokeWidth: 0.5, // ...thin...
strokeOpacity: 0.6 // ...and a little see-through
});
// Highlight producer & importer countries
var producerIds = ["SA", "IQ", "AE", "KW", "IR", "QA"];
var importerIds = ["CN", "JP", "KR", "IN", "SG", "IT", "GR", "NL"];
// once the countries are drawn, color the producers and importers and give them a tooltip
polygonSeries.events.on("datavalidated", function () {
am5.array.each(polygonSeries.dataItems, function (di) {
var id = di.get("id");
if (producerIds.includes(id)) {
di.get("mapPolygon").setAll({ fill: am5.color(0x6b5a10), tooltipText: "{name}" });
} else if (importerIds.includes(id)) {
di.get("mapPolygon").setAll({ fill: am5.color(0x2a4030), tooltipText: "{name}" });
}
});
});
// ---- MapSankeySeries — Oil flows through Hormuz ----
// the main trick: bands as wide as their values, from terminal to port, routed through waypoints
var sankeySeries = chart.series.push(am5map.MapSankeySeries.new(root, {
polygonSeries: polygonSeries,
// the widest band, for the largest value, is 0.8 degrees across
maxWidth: 0.8,
controlPointDistance: 0.4, // a little shorter straight run at each end than the default 0.5
resolution: 60, // 60 points per curve segment, for smooth bends
nodePadding: 0.1 // end nodes 0.1 degrees bigger than their bands, so no gap shows
}));
sankeySeries.mapPolygons.template.setAll({
fill: amber, // amber bands...
fillOpacity: 0.4, // ...see-through, so overlapping routes show
strokeOpacity: 0, // no outline
tooltipText: "{source} > {target}\n{value}k bbl/day" // hover a band for its route and volume
});
// the nodes: the shapes at each terminal and port where the bands start and end
sankeySeries.nodes.mapPolygons.template.setAll({
fill: amber,
stroke: flare, // a light outline...
strokeWidth: 1.5, // ...1.5px wide
fillOpacity: 0.95, // almost solid
strokeOpacity: 1,
tooltipText: "{name}" // hover a node for its name
});
// ---- Animated oil drop bullets ----
sankeySeries.bullets.push(function () {
return am5.Bullet.new(root, {
locationX: 0, // start at the band's source end
autoRotate: true, // turn the drop with the band's direction
// turn the drop along the band so its pointed end trails behind
autoRotateAngle: -90,
sprite: am5.Graphics.new(root, {
// Oil drop shape
svgPath: "M0,-7 C2,-4 5,0 5,3 C5,6 3,8 0,8 C-3,8 -5,6 -5,3 C-5,0 -2,-4 0,-7 Z",
fill: amber, // amber...
stroke: am5.color(0x8b6914), // ...with a darker outline
strokeWidth: 0.5,
centerX: am5.p50, // centered on its point...
centerY: am5.p50, // ...both ways
scale: 0.45, // the shape drawn at 45% of its size
visible: false // hidden until its animation starts
})
});
});
// once the bands are drawn, send drops along each, timed by the band's length
sankeySeries.events.on("datavalidated", function () {
// Find the longest path to scale durations proportionally
var maxLength = 0;
am5.array.each(sankeySeries.dataItems, function (dataItem) {
var len = sankeySeries.getPathLength(dataItem);
if (len > maxLength) maxLength = len;
});
var baseDuration = 8000; // longest path duration
var minDuration = 2000; // even the shortest band takes at least 2 seconds
am5.array.each(sankeySeries.dataItems, function (dataItem) {
var pathLength = sankeySeries.getPathLength(dataItem) || maxLength;
// longer bands take longer, so all the drops move at about the same speed
var dur = maxLength > 0 ? Math.max(minDuration, (pathLength / maxLength) * baseDuration) : baseDuration;
var bullets = dataItem.bullets;
if (bullets) {
am5.array.each(bullets, function (bullet) {
// vary the speed by up to 20% and start at a random time, so the drops don't move in step
var randomDur = dur * (0.8 + Math.random() * 0.4);
var delay = Math.random() * randomDur;
setTimeout(function () {
var sprite = bullet.get("sprite");
if (sprite) sprite.set("visible", true); // show the drop once it starts moving
bullet.animate({
key: "locationX", // move the drop along the band...
from: 0, // ...from the source...
to: 1, // ...to the target...
duration: randomDur,
easing: am5.ease.linear, // ...at a steady speed...
loops: Infinity // ...over and over
});
}, delay);
});
}
});
});
// ---- Oil Export Data — through Strait of Hormuz ----
// Coordinates: actual oil port / terminal locations
// Values in thousands of barrels per day (approximate)
// Gulf export terminals
var rasTanura = { lon: 50.17, lat: 26.64 }; // Saudi Arabia — Ras Tanura
var basra = { lon: 48.80, lat: 29.69 }; // Iraq — Basra Oil Terminal
var fujairah = { lon: 56.33, lat: 25.12 }; // UAE — Port of Fujairah
var minaAhmadi = { lon: 48.17, lat: 29.08 }; // Kuwait — Mina Al Ahmadi
var khargIsland = { lon: 50.32, lat: 29.23 }; // Iran — Kharg Island
var rasLaffan = { lon: 51.56, lat: 25.93 }; // Qatar — Ras Laffan
// Asian import terminals
var ningbo = { lon: 121.97, lat: 29.87 }; // China — Ningbo-Zhoushan
var qingdao = { lon: 120.38, lat: 36.07 }; // China — Qingdao
var yokohama = { lon: 139.64, lat: 35.44 }; // Japan — Yokohama
var chiba = { lon: 140.10, lat: 35.60 }; // Japan — Chiba
var ulsan = { lon: 129.38, lat: 35.50 }; // South Korea — Ulsan
var jamnagar = { lon: 69.66, lat: 22.42 }; // India — Jamnagar / Vadinar
var mumbai = { lon: 72.88, lat: 19.08 }; // India — Mumbai (JNPT)
var singapore = { lon: 103.84, lat: 1.26 }; // Singapore — Jurong Island
// European import terminals
var trieste = { lon: 13.78, lat: 45.65 }; // Italy — Trieste (SIOT)
var piraeus = { lon: 23.63, lat: 37.94 }; // Greece — Piraeus / Agioi Theodoroi
var rotterdam = { lon: 4.12, lat: 51.95 }; // Netherlands — Rotterdam
// builds one data item: a flow from a terminal to a port, with optional waypoints
function flow(src, srcName, tgt, tgtName, value, wp) {
var result = {
sourceLongitude: src.lon, sourceLatitude: src.lat,
targetLongitude: tgt.lon, targetLatitude: tgt.lat,
source: srcName, target: tgtName, value: value
};
if (wp) result.waypoints = wp; // the band passes through these points in order
return result;
}
// Maritime waypoints — keep ships on water
var wpHormuz = { longitude: 58, latitude: 24 }; // Strait of Hormuz exit
var wpArabianSea = { longitude: 64, latitude: 18 }; // Mid Arabian Sea
var wpSouthIndia = { longitude: 78, latitude: 6 }; // South of Sri Lanka
var wpMalacca = { longitude: 101, latitude: 3 }; // Malacca Strait
var wpAden = { longitude: 47, latitude: 12 }; // Gulf of Aden
var wpSuez = { longitude: 34, latitude: 29 }; // Suez Canal
// Route templates — fan out East Asia routes so they don't merge
var viaJapan = [{ longitude: 58, latitude: 26 }, { longitude: 80, latitude: 9 }, { longitude: 104, latitude: 7 }];
var viaKorea = [wpHormuz, wpSouthIndia, wpMalacca];
var viaChina = [{ longitude: 58, latitude: 22 }, { longitude: 76, latitude: 3 }, { longitude: 99, latitude: 1 }];
var viaChinaNorth = [{ longitude: 58, latitude: 22 }, { longitude: 76, latitude: 3 }, { longitude: 99, latitude: 1 }, { longitude: 124, latitude: 32 }];
var viaIndiaNear = [wpHormuz]; // > Jamnagar (close)
var viaIndiaFar = [wpHormuz, wpArabianSea]; // > Mumbai
var viaSingapore = [wpHormuz, wpSouthIndia]; // > Singapore
var viaSuez = [wpHormuz, wpAden, wpSuez]; // > Mediterranean / Europe
var wpSouthGreece = { longitude: 22, latitude: 35 }; // South of Peloponnese
var wpOtranto = { longitude: 18.5, latitude: 40 }; // Strait of Otranto (Adriatic entry)
var viaSuezItaly = [wpHormuz, wpAden, wpSuez, wpSouthGreece, wpOtranto]; // > Italy via south of Greece
var wpSicily = { longitude: 13, latitude: 37 }; // Near Sicily
var wpPortugal = { longitude: -10, latitude: 39 }; // Off Portugal coast
var viaAtlantic = [wpHormuz, wpAden, wpSuez, wpSicily, wpPortugal]; // > Atlantic Europe
// each flow: from, its name, to, its name, thousands of barrels a day, waypoints
sankeySeries.data.setAll([
// === Ras Tanura (Saudi Arabia) ===
flow(rasTanura, "Ras Tanura", ningbo, "Ningbo", 1100, viaChina),
flow(rasTanura, "Ras Tanura", qingdao, "Qingdao", 600, viaChinaNorth),
flow(rasTanura, "Ras Tanura", yokohama, "Yokohama", 700, viaJapan),
flow(rasTanura, "Ras Tanura", chiba, "Chiba", 300, viaJapan),
flow(rasTanura, "Ras Tanura", ulsan, "Ulsan", 800, viaKorea),
flow(rasTanura, "Ras Tanura", jamnagar, "Jamnagar", 500, viaIndiaNear),
flow(rasTanura, "Ras Tanura", mumbai, "Mumbai", 300, viaIndiaFar),
flow(rasTanura, "Ras Tanura", rotterdam, "Rotterdam", 350, viaAtlantic),
// === Basra Oil Terminal (Iraq) ===
flow(basra, "Basra", ningbo, "Ningbo", 700, viaChina),
flow(basra, "Basra", qingdao, "Qingdao", 400, viaChinaNorth),
flow(basra, "Basra", jamnagar, "Jamnagar", 600, viaIndiaNear),
flow(basra, "Basra", mumbai, "Mumbai", 400, viaIndiaFar),
flow(basra, "Basra", ulsan, "Ulsan", 400, viaKorea),
flow(basra, "Basra", trieste, "Trieste", 350, viaSuezItaly),
flow(basra, "Basra", piraeus, "Piraeus", 250, viaSuez),
// === Fujairah (UAE) — already outside Hormuz ===
flow(fujairah, "Fujairah", yokohama, "Yokohama", 400, viaJapan.slice(1)),
flow(fujairah, "Fujairah", chiba, "Chiba", 200, viaJapan.slice(1)),
flow(fujairah, "Fujairah", jamnagar, "Jamnagar", 300),
flow(fujairah, "Fujairah", mumbai, "Mumbai", 200, [wpArabianSea]),
flow(fujairah, "Fujairah", ningbo, "Ningbo", 250, viaChina.slice(1)),
flow(fujairah, "Fujairah", ulsan, "Ulsan", 350, viaKorea.slice(1)),
flow(fujairah, "Fujairah", singapore, "Singapore", 250, [wpSouthIndia]),
// === Mina Al Ahmadi (Kuwait) ===
flow(minaAhmadi, "Mina Al Ahmadi", ulsan, "Ulsan", 400, viaKorea),
flow(minaAhmadi, "Mina Al Ahmadi", yokohama, "Yokohama", 300, viaJapan),
flow(minaAhmadi, "Mina Al Ahmadi", ningbo, "Ningbo", 300, viaChina),
flow(minaAhmadi, "Mina Al Ahmadi", jamnagar, "Jamnagar", 200, viaIndiaNear),
// === Kharg Island (Iran) ===
flow(khargIsland, "Kharg Island", ningbo, "Ningbo", 400, viaChina),
flow(khargIsland, "Kharg Island", qingdao, "Qingdao", 200, viaChinaNorth),
flow(khargIsland, "Kharg Island", jamnagar, "Jamnagar", 200, viaIndiaNear),
flow(khargIsland, "Kharg Island", piraeus, "Piraeus", 100, viaSuez),
// === Ras Laffan (Qatar) ===
flow(rasLaffan, "Ras Laffan", yokohama, "Yokohama", 300, viaJapan),
flow(rasLaffan, "Ras Laffan", ulsan, "Ulsan", 200, viaKorea),
flow(rasLaffan, "Ras Laffan", jamnagar, "Jamnagar", 150, viaIndiaNear),
flow(rasLaffan, "Ras Laffan", singapore, "Singapore", 120, viaSingapore)
]);
// ---- Title + Subtitle (top center) ----
var titleCont = chart.children.push(am5.Container.new(root, {
layout: root.verticalLayout, // the title above the subtitle
x: am5.p50, // in the middle of the chart...
centerX: am5.p50, // ...centered on its own middle
y: 0, // at the top
position: "absolute", // floats over the map instead of taking room in the chart's layout
paddingTop: 16 // 16px below the top edge
}));
titleCont.children.push(am5.Label.new(root, {
text: "Strait of Hormuz — Oil Export Flows",
fontSize: 18,
fontWeight: "600", // semi-bold
fill: amber,
x: am5.p50,
centerX: am5.p50
}));
titleCont.children.push(am5.Label.new(root, {
text: "Gulf Producers > Major Importers (thousands of barrels/day)",
fontSize: 11,
fill: sulfur,
x: am5.p50,
centerX: am5.p50
}));
var easing = am5.ease.inOut(am5.ease.cubic); // a slow start and end for the moves below
var duration = 1500; // each move takes 1.5 seconds
// switches to the globe and turns it to face the Gulf, zoomed in
function zoomToGlobe() {
chart.set("projection", am5map.geoOrthographic());
chart.set("panX", "rotateX");
chart.set("panY", "rotateY");
chart.animate({ key: "rotationX", to: -74, duration, easing }); // bring longitude 74 east to the front...
chart.animate({ key: "rotationY", to: -30, duration, easing }); // ...and latitude 30 north to the middle...
chart.animate({ key: "zoomLevel", to: 1.6, duration, easing }); // ...and zoom in 1.6 times
bgSeries.mapPolygons.template.set("fillOpacity", 1); // the ocean shows on the globe
}
// switches to a flat map (Mercator or Equal Earth) and zooms in on the Gulf
function zoomToMap(name) {
chart.set("projection", name === "mercator" ? am5map.geoMercator() : am5map.geoEqualEarth());
chart.set("panX", "translateX"); // a drag moves the flat map...
chart.set("panY", "translateY"); // ...in both directions
chart.animate({ key: "rotationY", to: 0, duration, easing }); // a flat map has no tilt
setTimeout(function () {
// zoom in 3.5 times around the Gulf and the Arabian Sea
chart.zoomToGeoPoint({ longitude: 67, latitude: 32 }, 3.5, true, duration);
}, 100);
bgSeries.mapPolygons.template.set("fillOpacity", 0); // no ocean rectangle on the flat map
}
var fadeDuration = 300;
// ---- Zoom controls with home button ----
var zoomControl = chart.set("zoomControl", am5map.ZoomControl.new(root, {}));
zoomControl.homeButton.set("visible", true); // the home button is hidden by default
chart.appear(1000, 100);
// Initial animation: rotate to globe position, then zoom in
setTimeout(function () {
zoomToGlobe();
}, 1000);
{
"type": "MapChart",
"settings": {
"panX": "rotateX",
"panY": "rotateY",
"homeGeoPoint": {
"longitude": 0,
"latitude": 0
},
"homeRotationX": 0,
"homeRotationY": 0,
"homeZoomLevel": 1,
"minZoomLevel": 0.8,
"zoomLevel": 1.6,
"background": {
"type": "Rectangle",
"settings": {
"fill": {
"type": "Color",
"value": "#0a0e12"
},
"fillOpacity": 1,
"stroke": {
"type": "Color",
"value": "#0a0e12"
},
"strokeOpacity": 1
}
},
"zoomControl": {
"type": "ZoomControl",
"properties": {
"homeButton": {
"settings": {
"visible": true
}
}
}
},
"projectionName": "geoOrthographic"
},
"properties": {
"series": [
"#series-0",
"#series-1",
"#series-2",
"#series-3"
]
},
"children": [
{
"type": "Container",
"settings": {
"layout": {
"type": "VerticalLayout"
},
"x": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
},
"y": 0,
"position": "absolute",
"paddingTop": 16
},
"children": [
{
"type": "Label",
"settings": {
"text": "Strait of Hormuz — Oil Export Flows",
"fontSize": 18,
"fontWeight": "600",
"fill": {
"type": "Color",
"value": "#c8890a"
},
"x": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
}
}
},
{
"type": "Label",
"settings": {
"text": "Gulf Producers > Major Importers (thousands of barrels/day)",
"fontSize": 11,
"fill": {
"type": "Color",
"value": "#a89050"
},
"x": {
"type": "Percent",
"value": 50
},
"centerX": {
"type": "Percent",
"value": 50
}
}
}
],
"index": 2
}
],
"refs": [
{
"data-0": [
{
"geometry": {
"type": "GeoRectangle",
"north": 90,
"east": 180,
"south": -90,
"west": -180
},
"__parse": true
}
]
},
{
"data-1": []
},
{
"data-2": []
},
{
"data-3": [
{
"sourceLongitude": 50.17,
"sourceLatitude": 26.64,
"targetLongitude": 121.97,
"targetLatitude": 29.87,
"source": "Ras Tanura",
"target": "Ningbo",
"value": 1100,
"waypoints": [
{
"longitude": 58,
"latitude": 22
},
{
"longitude": 76,
"latitude": 3
},
{
"longitude": 99,
"latitude": 1
}
],
"__parse": true
},
{
"sourceLongitude": 50.17,
"sourceLatitude": 26.64,
"targetLongitude": 120.38,
"targetLatitude": 36.07,
"source": "Ras Tanura",
"target": "Qingdao",
"value": 600,
"waypoints": [
{
"longitude": 58,
"latitude": 22
},
{
"longitude": 76,
"latitude": 3
},
{
"longitude": 99,
"latitude": 1
},
{
"longitude": 124,
"latitude": 32
}
],
"__parse": true
},
{
"sourceLongitude": 50.17,
"sourceLatitude": 26.64,
"targetLongitude": 139.64,
"targetLatitude": 35.44,
"source": "Ras Tanura",
"target": "Yokohama",
"value": 700,
"waypoints": [
{
"longitude": 58,
"latitude": 26
},
{
"longitude": 80,
"latitude": 9
},
{
"longitude": 104,
"latitude": 7
}
],
"__parse": true
},
{
"sourceLongitude": 50.17,
"sourceLatitude": 26.64,
"targetLongitude": 140.1,
"targetLatitude": 35.6,
"source": "Ras Tanura",
"target": "Chiba",
"value": 300,
"waypoints": [
{
"longitude": 58,
"latitude": 26
},
{
"longitude": 80,
"latitude": 9
},
{
"longitude": 104,
"latitude": 7
}
],
"__parse": true
},
{
"sourceLongitude": 50.17,
"sourceLatitude": 26.64,
"targetLongitude": 129.38,
"targetLatitude": 35.5,
"source": "Ras Tanura",
"target": "Ulsan",
"value": 800,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 78,
"latitude": 6
},
{
"longitude": 101,
"latitude": 3
}
],
"__parse": true
},
{
"sourceLongitude": 50.17,
"sourceLatitude": 26.64,
"targetLongitude": 69.66,
"targetLatitude": 22.42,
"source": "Ras Tanura",
"target": "Jamnagar",
"value": 500,
"waypoints": [
{
"longitude": 58,
"latitude": 24
}
],
"__parse": true
},
{
"sourceLongitude": 50.17,
"sourceLatitude": 26.64,
"targetLongitude": 72.88,
"targetLatitude": 19.08,
"source": "Ras Tanura",
"target": "Mumbai",
"value": 300,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 64,
"latitude": 18
}
],
"__parse": true
},
{
"sourceLongitude": 50.17,
"sourceLatitude": 26.64,
"targetLongitude": 4.12,
"targetLatitude": 51.95,
"source": "Ras Tanura",
"target": "Rotterdam",
"value": 350,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 47,
"latitude": 12
},
{
"longitude": 34,
"latitude": 29
},
{
"longitude": 13,
"latitude": 37
},
{
"longitude": -10,
"latitude": 39
}
],
"__parse": true
},
{
"sourceLongitude": 48.8,
"sourceLatitude": 29.69,
"targetLongitude": 121.97,
"targetLatitude": 29.87,
"source": "Basra",
"target": "Ningbo",
"value": 700,
"waypoints": [
{
"longitude": 58,
"latitude": 22
},
{
"longitude": 76,
"latitude": 3
},
{
"longitude": 99,
"latitude": 1
}
],
"__parse": true
},
{
"sourceLongitude": 48.8,
"sourceLatitude": 29.69,
"targetLongitude": 120.38,
"targetLatitude": 36.07,
"source": "Basra",
"target": "Qingdao",
"value": 400,
"waypoints": [
{
"longitude": 58,
"latitude": 22
},
{
"longitude": 76,
"latitude": 3
},
{
"longitude": 99,
"latitude": 1
},
{
"longitude": 124,
"latitude": 32
}
],
"__parse": true
},
{
"sourceLongitude": 48.8,
"sourceLatitude": 29.69,
"targetLongitude": 69.66,
"targetLatitude": 22.42,
"source": "Basra",
"target": "Jamnagar",
"value": 600,
"waypoints": [
{
"longitude": 58,
"latitude": 24
}
],
"__parse": true
},
{
"sourceLongitude": 48.8,
"sourceLatitude": 29.69,
"targetLongitude": 72.88,
"targetLatitude": 19.08,
"source": "Basra",
"target": "Mumbai",
"value": 400,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 64,
"latitude": 18
}
],
"__parse": true
},
{
"sourceLongitude": 48.8,
"sourceLatitude": 29.69,
"targetLongitude": 129.38,
"targetLatitude": 35.5,
"source": "Basra",
"target": "Ulsan",
"value": 400,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 78,
"latitude": 6
},
{
"longitude": 101,
"latitude": 3
}
],
"__parse": true
},
{
"sourceLongitude": 48.8,
"sourceLatitude": 29.69,
"targetLongitude": 13.78,
"targetLatitude": 45.65,
"source": "Basra",
"target": "Trieste",
"value": 350,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 47,
"latitude": 12
},
{
"longitude": 34,
"latitude": 29
},
{
"longitude": 22,
"latitude": 35
},
{
"longitude": 18.5,
"latitude": 40
}
],
"__parse": true
},
{
"sourceLongitude": 48.8,
"sourceLatitude": 29.69,
"targetLongitude": 23.63,
"targetLatitude": 37.94,
"source": "Basra",
"target": "Piraeus",
"value": 250,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 47,
"latitude": 12
},
{
"longitude": 34,
"latitude": 29
}
],
"__parse": true
},
{
"sourceLongitude": 56.33,
"sourceLatitude": 25.12,
"targetLongitude": 139.64,
"targetLatitude": 35.44,
"source": "Fujairah",
"target": "Yokohama",
"value": 400,
"waypoints": [
{
"longitude": 80,
"latitude": 9
},
{
"longitude": 104,
"latitude": 7
}
],
"__parse": true
},
{
"sourceLongitude": 56.33,
"sourceLatitude": 25.12,
"targetLongitude": 140.1,
"targetLatitude": 35.6,
"source": "Fujairah",
"target": "Chiba",
"value": 200,
"waypoints": [
{
"longitude": 80,
"latitude": 9
},
{
"longitude": 104,
"latitude": 7
}
],
"__parse": true
},
{
"sourceLongitude": 56.33,
"sourceLatitude": 25.12,
"targetLongitude": 69.66,
"targetLatitude": 22.42,
"source": "Fujairah",
"target": "Jamnagar",
"value": 300
},
{
"sourceLongitude": 56.33,
"sourceLatitude": 25.12,
"targetLongitude": 72.88,
"targetLatitude": 19.08,
"source": "Fujairah",
"target": "Mumbai",
"value": 200,
"waypoints": [
{
"longitude": 64,
"latitude": 18
}
],
"__parse": true
},
{
"sourceLongitude": 56.33,
"sourceLatitude": 25.12,
"targetLongitude": 121.97,
"targetLatitude": 29.87,
"source": "Fujairah",
"target": "Ningbo",
"value": 250,
"waypoints": [
{
"longitude": 76,
"latitude": 3
},
{
"longitude": 99,
"latitude": 1
}
],
"__parse": true
},
{
"sourceLongitude": 56.33,
"sourceLatitude": 25.12,
"targetLongitude": 129.38,
"targetLatitude": 35.5,
"source": "Fujairah",
"target": "Ulsan",
"value": 350,
"waypoints": [
{
"longitude": 78,
"latitude": 6
},
{
"longitude": 101,
"latitude": 3
}
],
"__parse": true
},
{
"sourceLongitude": 56.33,
"sourceLatitude": 25.12,
"targetLongitude": 103.84,
"targetLatitude": 1.26,
"source": "Fujairah",
"target": "Singapore",
"value": 250,
"waypoints": [
{
"longitude": 78,
"latitude": 6
}
],
"__parse": true
},
{
"sourceLongitude": 48.17,
"sourceLatitude": 29.08,
"targetLongitude": 129.38,
"targetLatitude": 35.5,
"source": "Mina Al Ahmadi",
"target": "Ulsan",
"value": 400,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 78,
"latitude": 6
},
{
"longitude": 101,
"latitude": 3
}
],
"__parse": true
},
{
"sourceLongitude": 48.17,
"sourceLatitude": 29.08,
"targetLongitude": 139.64,
"targetLatitude": 35.44,
"source": "Mina Al Ahmadi",
"target": "Yokohama",
"value": 300,
"waypoints": [
{
"longitude": 58,
"latitude": 26
},
{
"longitude": 80,
"latitude": 9
},
{
"longitude": 104,
"latitude": 7
}
],
"__parse": true
},
{
"sourceLongitude": 48.17,
"sourceLatitude": 29.08,
"targetLongitude": 121.97,
"targetLatitude": 29.87,
"source": "Mina Al Ahmadi",
"target": "Ningbo",
"value": 300,
"waypoints": [
{
"longitude": 58,
"latitude": 22
},
{
"longitude": 76,
"latitude": 3
},
{
"longitude": 99,
"latitude": 1
}
],
"__parse": true
},
{
"sourceLongitude": 48.17,
"sourceLatitude": 29.08,
"targetLongitude": 69.66,
"targetLatitude": 22.42,
"source": "Mina Al Ahmadi",
"target": "Jamnagar",
"value": 200,
"waypoints": [
{
"longitude": 58,
"latitude": 24
}
],
"__parse": true
},
{
"sourceLongitude": 50.32,
"sourceLatitude": 29.23,
"targetLongitude": 121.97,
"targetLatitude": 29.87,
"source": "Kharg Island",
"target": "Ningbo",
"value": 400,
"waypoints": [
{
"longitude": 58,
"latitude": 22
},
{
"longitude": 76,
"latitude": 3
},
{
"longitude": 99,
"latitude": 1
}
],
"__parse": true
},
{
"sourceLongitude": 50.32,
"sourceLatitude": 29.23,
"targetLongitude": 120.38,
"targetLatitude": 36.07,
"source": "Kharg Island",
"target": "Qingdao",
"value": 200,
"waypoints": [
{
"longitude": 58,
"latitude": 22
},
{
"longitude": 76,
"latitude": 3
},
{
"longitude": 99,
"latitude": 1
},
{
"longitude": 124,
"latitude": 32
}
],
"__parse": true
},
{
"sourceLongitude": 50.32,
"sourceLatitude": 29.23,
"targetLongitude": 69.66,
"targetLatitude": 22.42,
"source": "Kharg Island",
"target": "Jamnagar",
"value": 200,
"waypoints": [
{
"longitude": 58,
"latitude": 24
}
],
"__parse": true
},
{
"sourceLongitude": 50.32,
"sourceLatitude": 29.23,
"targetLongitude": 23.63,
"targetLatitude": 37.94,
"source": "Kharg Island",
"target": "Piraeus",
"value": 100,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 47,
"latitude": 12
},
{
"longitude": 34,
"latitude": 29
}
],
"__parse": true
},
{
"sourceLongitude": 51.56,
"sourceLatitude": 25.93,
"targetLongitude": 139.64,
"targetLatitude": 35.44,
"source": "Ras Laffan",
"target": "Yokohama",
"value": 300,
"waypoints": [
{
"longitude": 58,
"latitude": 26
},
{
"longitude": 80,
"latitude": 9
},
{
"longitude": 104,
"latitude": 7
}
],
"__parse": true
},
{
"sourceLongitude": 51.56,
"sourceLatitude": 25.93,
"targetLongitude": 129.38,
"targetLatitude": 35.5,
"source": "Ras Laffan",
"target": "Ulsan",
"value": 200,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 78,
"latitude": 6
},
{
"longitude": 101,
"latitude": 3
}
],
"__parse": true
},
{
"sourceLongitude": 51.56,
"sourceLatitude": 25.93,
"targetLongitude": 69.66,
"targetLatitude": 22.42,
"source": "Ras Laffan",
"target": "Jamnagar",
"value": 150,
"waypoints": [
{
"longitude": 58,
"latitude": 24
}
],
"__parse": true
},
{
"sourceLongitude": 51.56,
"sourceLatitude": 25.93,
"targetLongitude": 103.84,
"targetLatitude": 1.26,
"source": "Ras Laffan",
"target": "Singapore",
"value": 120,
"waypoints": [
{
"longitude": 58,
"latitude": 24
},
{
"longitude": 78,
"latitude": 6
}
],
"__parse": true
}
]
},
{
"series-0": {
"type": "MapPolygonSeries",
"properties": {
"data": "#data-0",
"mapPolygons": {
"properties": {
"template": {
"settings": {
"fill": {
"type": "Color",
"value": "#141a1a"
},
"fillOpacity": 1,
"strokeOpacity": 0
}
}
}
}
}
}
},
{
"series-1": {
"type": "GraticuleSeries",
"properties": {
"mapLines": {
"properties": {
"template": {
"settings": {
"stroke": {
"type": "Color",
"value": "#3a5040"
},
"strokeOpacity": 0.25,
"strokeWidth": 0.5
}
}
}
}
}
}
},
{
"series-2": {
"type": "MapPolygonSeries",
"settings": {
"geoJSON": "am5geodata_worldLow"
},
"properties": {
"mapPolygons": {
"properties": {
"template": {
"settings": {
"fill": {
"type": "Color",
"value": "#1e2824"
},
"stroke": {
"type": "Color",
"value": "#3a5040"
},
"strokeWidth": 0.5,
"strokeOpacity": 0.6
}
}
}
}
}
}
},
{
"series-3": {
"type": "MapSankeySeries",
"settings": {
"polygonSeries": "#series-2",
"maxWidth": 0.8,
"controlPointDistance": 0.4,
"resolution": 60,
"nodePadding": 0.1
},
"properties": {
"data": "#data-3",
"mapPolygons": {
"properties": {
"template": {
"settings": {
"fill": {
"type": "Color",
"value": "#c8890a"
},
"fillOpacity": 0.4,
"strokeOpacity": 0,
"tooltipText": "{source} > {target}\n{value}k bbl/day"
}
}
}
},
"nodes": {
"properties": {
"mapPolygons": {
"properties": {
"template": {
"settings": {
"fill": {
"type": "Color",
"value": "#c8890a"
},
"stroke": {
"type": "Color",
"value": "#f5d090"
},
"strokeWidth": 1.5,
"fillOpacity": 0.95,
"strokeOpacity": 1,
"tooltipText": "{name}"
}
}
}
}
}
},
"bullets": [
{
"type": "Bullet",
"settings": {
"locationX": 0,
"autoRotate": true,
"autoRotateAngle": -90,
"sprite": {
"type": "Graphics",
"settings": {
"svgPath": "M0,-7 C2,-4 5,0 5,3 C5,6 3,8 0,8 C-3,8 -5,6 -5,3 C-5,0 -2,-4 0,-7 Z",
"fill": {
"type": "Color",
"value": "#c8890a"
},
"stroke": {
"type": "Color",
"value": "#8b6914"
},
"strokeWidth": 0.5,
"centerX": {
"type": "Percent",
"value": 50
},
"centerY": {
"type": "Percent",
"value": 50
},
"scale": 0.45,
"visible": false
}
}
}
}
]
}
}
}
],
"root": {
"properties": {
"interfaceColors": {
"settings": {
"background": {
"type": "Color",
"value": "#0a0e12"
}
}
}
}
}
}
