import * as am5 from "@amcharts/amcharts5"; import * as am5flow from "@amcharts/amcharts5/flow"; import am5themes_Animated from "@amcharts/amcharts5/themes/Animated"; // 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 series // https://www.amcharts.com/docs/v5/charts/flow-charts/ // ChordNonRibbon draws each link as a thin curve, not a ribbon, and gives every node the same arc const series = root.container.children.push(am5flow.ChordNonRibbon.new(root, { sourceIdField: "source", targetIdField: "target", valueField: "value" })); // every second color of the color set, so neighboring nodes differ more series.nodes.get("colors")!.set("step", 2); // Draw each node as a circle with its name inside // https://www.amcharts.com/docs/v5/concepts/common-elements/bullets/ series.nodes.bullets.push((_root, _nodes, dataItem) => { const circle = am5.Circle.new(root, { radius: 24, // big enough to hold the node's name fill: dataItem.get("fill") // the node's own color }); // A node that is clicked off keeps its circle, in gray // https://www.amcharts.com/docs/v5/charts/flow-charts/#Node_toggling circle.states.create("hidden", { fill: root.interfaceColors.get("disabled") }); return am5.Bullet.new(root, { sprite: circle }); }); series.nodes.labels.template.setAll({ textType: "regular", // straight text, not bent along the circle fill: root.interfaceColors.get("alternativeText"), // light text that reads on the colored circle radius: -5 // 5 px in from the outer edge: the node's middle, where the circle is }); // a clicked-off node's label stays light, so it still reads on the gray circle series.nodes.labels.template.states.create("disabled", { fill: root.interfaceColors.get("alternativeText") }); // Add a circle that travels along each link and back // https://www.amcharts.com/docs/v5/concepts/animations/ series.bullets.push((_root, _series, dataItem) => { return am5.Bullet.new(root, { // from the source end (0) to the target end (1) and back, forever, slowing at each end animations: [ { key: "locationY", from: 0, to: 1, duration: 2000, loops: 0, yoyo: true, easing: "cubic", ease: "inOut" } ], sprite: am5.Circle.new(root, { radius: 5, fill: dataItem.get("source").get("fill") // the color of the link's source node }) }); }); // Keep the travelling circles under the nodes series.children.moveValue(series.bulletsContainer, 0); // Set data // https://www.amcharts.com/docs/v5/charts/flow-charts/#Setting_data series.data.setAll([ { source: "LHR", target: "JFK", value: 24 }, { source: "LHR", target: "DXB", value: 18 }, { source: "LHR", target: "CDG", value: 14 }, { source: "CDG", target: "JFK", value: 12 }, { source: "CDG", target: "FRA", value: 10 }, { source: "FRA", target: "DXB", value: 9 }, { source: "FRA", target: "SIN", value: 6 }, { source: "DXB", target: "SIN", value: 11 }, { source: "JFK", target: "LAX", value: 30 }, { source: "LAX", target: "SIN", value: 4 } ]); // Make stuff animate on load // https://www.amcharts.com/docs/v5/concepts/animations/#Forcing_appearance_animation series.appear(1000, 100);