Public
Edited
Jan 16, 2024
Insert cell
Insert cell
Insert cell
Insert cell
visualise = async container => {
const visualiser = await new AMCharts4.Visualiser(container, options).build();
container.replaceChildren(visualiser.element);
return visualiser;
}
Insert cell
Insert cell
Insert cell
Insert cell
options = ({
setup: (am4core, am4charts, element) => {
var chart = am4core.create(element, am4charts.ChordDiagram);

chart.colors.saturation = 0.45;
chart.colors.step = 3;

chart.data = data;

chart.dataFields.fromName = "from";
chart.dataFields.toName = "to";
chart.dataFields.value = "value";

chart.nodePadding = 0.5;
chart.minNodeSize = 0.01;
chart.startAngle = 80;
chart.endAngle = chart.startAngle + 360;
chart.sortBy = "value";
chart.fontSize = 10;

const nodeTemplate = chart.nodes.template;
nodeTemplate.readerTitle = "Click to show/hide or drag to rearrange";
nodeTemplate.showSystemTooltip = true;
nodeTemplate.propertyFields.fill = "color";
nodeTemplate.tooltipText = "{name}: {total}";

// when rolled over the node, make all the links rolled-over
nodeTemplate.events.on("over", function(event) {
const node = event.target;
node.outgoingDataItems.each(function(dataItem) {
if (dataItem.toNode) {
dataItem.link.isHover = true;
dataItem.toNode.label.isHover = true;
}
});
node.incomingDataItems.each(function(dataItem) {
if (dataItem.fromNode) {
dataItem.link.isHover = true;
dataItem.fromNode.label.isHover = true;
}
});
node.label.isHover = true;
});

// when rolled out from the node, make all the links rolled-out
nodeTemplate.events.on("out", function(event) {
const node = event.target;
node.outgoingDataItems.each(function(dataItem) {
if (dataItem.toNode) {
dataItem.link.isHover = false;
dataItem.toNode.label.isHover = false;
}
});
node.incomingDataItems.each(function(dataItem) {
if (dataItem.fromNode) {
dataItem.link.isHover = false;
dataItem.fromNode.label.isHover = false;
}
});

node.label.isHover = false;
});

const label = nodeTemplate.label;
label.relativeRotation = 90;

label.fillOpacity = 0.4;
const labelHS = label.states.create("hover");
labelHS.properties.fillOpacity = 1;

nodeTemplate.cursorOverStyle = am4core.MouseCursorStyle.pointer;

// this adapter makes non-main character nodes to be filled with color
nodeTemplate.adapter.add("fill", function(fill, target) {
const node = target;
const counters = {};
// let mainChar = false;
node.incomingDataItems.each(function(dataItem) {
// if (colors[dataItem.toName]) {
// mainChar = true;
// }

if (isNaN(counters[dataItem.fromName])) {
counters[dataItem.fromName] = dataItem.value;
} else {
counters[dataItem.fromName] += dataItem.value;
}
});

let biggest = 0;
let biggestName;

for (var name in counters) {
if (counters[name] > biggest) {
biggestName = name;
biggest = counters[name];
}
}

return fill;
});

// link template
const linkTemplate = chart.links.template;
linkTemplate.strokeOpacity = 0;
linkTemplate.fillOpacity = 0.15;
linkTemplate.tooltipText = "{fromName} & {toName}:{value.value}";

const hoverState = linkTemplate.states.create("hover");
hoverState.properties.fillOpacity = 0.7;
hoverState.properties.strokeOpacity = 0.7;
}
})
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more