Improvements for sankey diagram after review

This commit is contained in:
Nikolay Rozhkov
2023-06-24 22:02:18 +03:00
parent 0a7d429192
commit 2f281ba228
4 changed files with 27 additions and 41 deletions

View File

@@ -53,7 +53,7 @@ record
const source = yy.findOrCreateNode($source.trim()); const source = yy.findOrCreateNode($source.trim());
const target = yy.findOrCreateNode($target.trim()); const target = yy.findOrCreateNode($target.trim());
const value = parseFloat($value.trim()); const value = parseFloat($value.trim());
$$ = yy.addLink(source,target,value); yy.addLink(source,target,value);
} // parse only 3 fields, this is not part of CSV standard } // parse only 3 fields, this is not part of CSV standard
; ;

View File

@@ -12,26 +12,26 @@ import {
// Variables where graph data is stored // Variables where graph data is stored
// Sankey diagram represented by nodes and links between those nodes // Sankey diagram represented by nodes and links between those nodes
// We have to track nodes uniqueness (by ID), thats why we need hash also // We have to track nodes uniqueness (by ID), thats why we need a mapping also
// //
let links: Array<SankeyLink> = []; let links: Array<SankeyLink> = [];
let nodes: Array<SankeyNode> = []; let nodes: Array<SankeyNode> = [];
let nodesHash: Record<string, SankeyNode> = {}; let nodesMap: Record<string, SankeyNode> = {};
let nodeAlign = 'justify'; let nodeAlign = 'justify';
const setNodeAlign = function (alignment: string): void { const setNodeAlign = (alignment: string): void => {
const nodeAlignments: string[] = ['left', 'right', 'center', 'justify']; const nodeAlignments: Set<string>= new Set(['left', 'right', 'center', 'justify']);
if (nodeAlignments.includes(alignment)) { if (nodeAlignments.has(alignment)) {
nodeAlign = alignment; nodeAlign = alignment;
} }
}; };
const getNodeAlign = () => nodeAlign; const getNodeAlign = (): string => nodeAlign;
const clear = function () { const clear = (): void => {
links = []; links = [];
nodes = []; nodes = [];
nodesHash = {}; nodesMap = {};
nodeAlign = 'justify'; nodeAlign = 'justify';
commonClear(); commonClear();
}; };
@@ -45,30 +45,26 @@ class SankeyLink {
* @param target - Node where the link ends * @param target - Node where the link ends
* @param value - number, float or integer, describes the amount to be passed * @param value - number, float or integer, describes the amount to be passed
*/ */
const addLink = function (source: SankeyNode, target: SankeyNode, value: number): SankeyLink { const addLink = (source: SankeyNode, target: SankeyNode, value: number): void => {
const link: SankeyLink = new SankeyLink(source, target, value); links.push(new SankeyLink(source, target, value));
links.push(link);
return link;
}; };
class SankeyNode { class SankeyNode {
constructor(public ID: string, public label: string = ID) {} constructor(public ID: string) {}
} }
/** /**
* @param ID - The id of the node * @param ID - The id of the node
*/ */
const findOrCreateNode = function (ID: string): SankeyNode { const findOrCreateNode = (ID: string): SankeyNode => {
ID = common.sanitizeText(ID, configApi.getConfig()); ID = common.sanitizeText(ID, configApi.getConfig());
let node: SankeyNode; let node: SankeyNode;
if (nodesHash[ID] === undefined) { if (nodesMap[ID] === undefined) {
node = new SankeyNode(ID); node = new SankeyNode(ID);
nodesHash[ID] = node; nodesMap[ID] = node;
nodes.push(node); nodes.push(node);
} else { } else {
node = nodesHash[ID]; node = nodesMap[ID];
} }
return node; return node;
}; };
@@ -77,7 +73,7 @@ const getNodes = () => nodes;
const getLinks = () => links; const getLinks = () => links;
const getGraph = () => ({ const getGraph = () => ({
nodes: nodes.map((node) => ({ id: node.ID, label: node.label })), nodes: nodes.map((node) => ({ id: node.ID })),
links: links.map((link) => ({ links: links.map((link) => ({
source: link.source.ID, source: link.source.ID,
target: link.target.ID, target: link.target.ID,
@@ -86,7 +82,7 @@ const getGraph = () => ({
}); });
export default { export default {
nodesHash, nodesMap,
getConfig: () => configApi.getConfig().sankey, getConfig: () => configApi.getConfig().sankey,
getNodes, getNodes,
getLinks, getLinks,

View File

@@ -57,20 +57,12 @@ export const draw = function (text: string, id: string, _version: string, diagOb
// svg.attr('height', height); // that's why we need this line // svg.attr('height', height); // that's why we need this line
// Prepare data for construction based on diagObj.db // Prepare data for construction based on diagObj.db
// This must be a mutable object with 2 properties: // This must be a mutable object with `nodes` and `links` properties:
// `nodes` and `links`
// //
// let graph = { // {
// "nodes": [ // "nodes": [ { "id": "Alice" }, { "id": "Bob" }, { "id": "Carol" } ],
// { "id": "Alice" }, // "links": [ { "source": "Alice", "target": "Bob", "value": 23 }, { "source": "Bob", "target": "Carol", "value": 43 } ]
// { "id": "Bob" }, // }
// { "id": "Carol" }
// ],
// "links": [
// { "source": "Alice", "target": "Bob", "value": 23 },
// { "source": "Bob", "target": "Carol", "value": 43 }
// ]
// };
// //
const graph = diagObj.db.getGraph(); const graph = diagObj.db.getGraph();
const nodeAligns = { const nodeAligns = {
@@ -136,7 +128,7 @@ export const draw = function (text: string, id: string, _version: string, diagOb
.attr('y', (d: any) => (d.y1 + d.y0) / 2) .attr('y', (d: any) => (d.y1 + d.y0) / 2)
.attr('dy', '0.35em') .attr('dy', '0.35em')
.attr('text-anchor', (d: any) => (d.x0 < width / 2 ? 'start' : 'end')) .attr('text-anchor', (d: any) => (d.x0 < width / 2 ? 'start' : 'end'))
.text((d: any) => d.label); .text((d: any) => d.id);
// Creates the paths that represent the links. // Creates the paths that represent the links.
const link = svg const link = svg

View File

@@ -1,4 +1,4 @@
const prepareTextForParsing = (text: string): string => { export const prepareTextForParsing = (text: string): string => {
const textToParse = text const textToParse = text
.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g, '') // remove all trailing spaces for each row .replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g, '') // remove all trailing spaces for each row
.replaceAll(/([\n\r])+/g, '\n') // remove empty lines duplicated .replaceAll(/([\n\r])+/g, '\n') // remove empty lines duplicated
@@ -7,7 +7,7 @@ const prepareTextForParsing = (text: string): string => {
return textToParse; return textToParse;
}; };
class Uid { export class Uid {
private static count = 0; private static count = 0;
id: string; id: string;
href: string; href: string;
@@ -25,5 +25,3 @@ class Uid {
return 'url(' + this.href + ')'; return 'url(' + this.href + ')';
} }
} }
export { Uid, prepareTextForParsing };