
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 { Flow } from "./Flow";
import { chord, ribbon } from "d3-chord";
import { ascending, descending } from "d3";
import { Template } from "../../core/util/Template";
import { ListTemplate } from "../../core/util/List";
import { ChordNodes } from "./ChordNodes";
import { ChordLink } from "./ChordLink";
import { p100, p50 } from "../../core/util/Percent";
import * as $array from "../../core/util/Array";
import * as $utils from "../../core/util/Utils";
import * as $math from "../../core/util/Math";
/**
* Regular chord series.
*
* @see {@link https://www.amcharts.com/docs/v5/charts/flow-charts/} for more information
* @important
*/
export class Chord extends Flow {
constructor() {
super(...arguments);
/**
* List of link elements.
*
* @default new ListTemplate<ChordLink>
*/
Object.defineProperty(this, "links", {
enumerable: true,
configurable: true,
writable: true,
value: new ListTemplate(Template.new({}), () => ChordLink._new(this._root, { themeTags: ["link", "shape"] }, [this.links.template]))
});
/**
* A series for all chord nodes.
*
* @default ChordNodes.new()
*/
Object.defineProperty(this, "nodes", {
enumerable: true,
configurable: true,
writable: true,
value: this.children.push(ChordNodes.new(this._root, {}))
});
Object.defineProperty(this, "_d3chord", {
enumerable: true,
configurable: true,
writable: true,
value: chord()
});
Object.defineProperty(this, "_chordLayout", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "_ribbon", {
enumerable: true,
configurable: true,
writable: true,
value: ribbon()
});
}
_afterNew() {
this._settings.themeTags = $utils.mergeTags(this._settings.themeTags, ["chord"]);
this.linksContainer.setAll({ x: p50, y: p50 });
this.bulletsContainer.setAll({ x: p50, y: p50 });
super._afterNew();
}
_fixRibbon(ribbon) {
ribbon.startAngle((d) => {
return d.startAngle + this.get("startAngle", 0) * $math.RADIANS + Math.PI / 2;
});
ribbon.endAngle((d) => {
return d.endAngle + this.get("startAngle", 0) * $math.RADIANS + Math.PI / 2;
});
}
/**
* @ignore
*/
makeLink(dataItem) {
const link = this.linksContainer.children.push(this.links.make());
this.links.push(link);
link._setDataItem(dataItem);
link.set("source", dataItem.get("source"));
link.set("target", dataItem.get("target"));
link.series = this;
return link;
}
_makeMatrix() {
const matrix = [];
$array.each(this.nodes.dataItems, (sourceDataItem) => {
const group = [];
matrix.push(group);
let outgoing = sourceDataItem.get("outgoingLinks");
$array.each(this.nodes.dataItems, (targetDataItem) => {
let value = 0;
if (outgoing) {
$array.each(outgoing, (outgoingLink) => {
if (outgoingLink.get("target") === targetDataItem) {
value = outgoingLink.get("valueWorking");
}
let valueSum = this.getPrivate("valueSum", 0);
let minSize = this.get("minSize", 0);
if (value > 0 && minSize > 0) {
if (value < valueSum * minSize) {
value = valueSum * minSize;
}
}
});
}
group.push(value);
});
});
return matrix;
}
_prepareChildren() {
super._prepareChildren();
this._fixRibbon(this._ribbon);
let chordChanged = false;
if (this._valuesDirty || this._sizeDirty || this.isDirty("padAngle") || this.isDirty("startAngle")) {
const matrix = this._makeMatrix();
this._d3chord.padAngle(this.get("padAngle", 0) * $math.RADIANS);
const sort = this.get("sort");
if (sort === "ascending") {
this._d3chord.sortGroups(ascending);
}
else if (sort === "descending") {
this._d3chord.sortGroups(descending);
}
/*
this._d3chord.sortSubgroups((a, b)=>{
if (a != Math.round(a)) return false
if (b != Math.round(b)) return true
return b < a ? -1 : b > a ? 1 : 0;
})
*/
this._chordLayout = this._d3chord(matrix);
chordChanged = true;
}
if (chordChanged || this.isDirty("radius") || this.isDirty("nodeWidth")) {
let radius = $utils.relativeToValue(this.get("radius", 0), Math.min(this.innerWidth(), this.innerHeight())) / 2;
let i = 0;
const chordStartAngle = this.get("startAngle", 0);
const nodeWidth = this.get("nodeWidth", 0);
$array.each(this.nodes.dataItems, (dataItem) => {
const slice = dataItem.get("slice");
const chordGroup = this._chordLayout.groups[i];
const startAngle = chordGroup.startAngle * $math.DEGREES + chordStartAngle;
const endAngle = chordGroup.endAngle * $math.DEGREES + chordStartAngle;
slice.setAll({ radius: radius, innerRadius: radius - nodeWidth, startAngle: startAngle, arc: endAngle - startAngle });
const label = dataItem.get("label");
label.setAll({ labelAngle: startAngle + (endAngle - startAngle) / 2 });
label.setPrivate("radius", radius);
label.setPrivate("innerRadius", 0.1);
i++;
});
const linkRadius = radius - this.get("nodeWidth", 0);
$array.each(this._chordLayout, (chord) => {
let dataItem = this._linksByIndex[chord.source.index + "_" + chord.target.index];
if (!dataItem) {
dataItem = this._linksByIndex[chord.target.index + "_" + chord.source.index];
}
if (dataItem) {
const link = dataItem.get("link");
this._getLinkPoints(link, linkRadius, chord);
this._updateLink(this._ribbon, link, linkRadius, chord);
}
});
}
}
_getLinkPoints(link, linkRadius, chordLayoutItem) {
const source = chordLayoutItem.source;
const target = chordLayoutItem.target;
const chordStartAngle = this.get("startAngle", 0) * $math.RADIANS;
if (source && target) {
const startAngle0 = source.startAngle;
const endAngle0 = source.endAngle;
const angle0 = startAngle0 + (endAngle0 - startAngle0) / 2 + chordStartAngle;
const startAngle1 = target.startAngle;
const endAngle1 = target.endAngle;
const angle1 = startAngle1 + (endAngle1 - startAngle1) / 2 + chordStartAngle;
link._p0 = { x: linkRadius * Math.cos(angle0), y: linkRadius * Math.sin(angle0) };
link._p1 = { x: linkRadius * Math.cos(angle1), y: linkRadius * Math.sin(angle1) };
}
}
_updateLink(ribbon, link, linkRadius, chordLayoutItem) {
if (chordLayoutItem) {
ribbon.sourceRadius($utils.relativeToValue(link.get("sourceRadius", p100), linkRadius));
ribbon.targetRadius($utils.relativeToValue(link.get("targetRadius", p100), linkRadius));
link.set("draw", (display) => {
ribbon.context(display);
ribbon(chordLayoutItem);
});
}
}
}
Object.defineProperty(Chord, "className", {
enumerable: true,
configurable: true,
writable: true,
value: "Chord"
});
Object.defineProperty(Chord, "classNames", {
enumerable: true,
configurable: true,
writable: true,
value: Flow.classNames.concat([Chord.className])
});
//# sourceMappingURL=Chord.js.map