Added options for coloring

This commit is contained in:
Nikolay Rozhkov
2023-06-25 00:22:36 +03:00
parent 1674f12b62
commit b23e86aea3
6 changed files with 72 additions and 28 deletions

View File

@@ -98,6 +98,12 @@
flowchart: { curve: 'basis' }, flowchart: { curve: 'basis' },
gantt: { axisFormat: '%m/%d/%Y' }, gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorMargin: 50 }, sequence: { actorMargin: 50 },
sankey: {
title: 'Hey, this is Sankey-Beta',
width: 1200,
height: 600,
linkColor: 'gradient',
},
}); });
</script> </script>
</body> </body>

View File

@@ -412,7 +412,17 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig {
wrappingWidth?: number; wrappingWidth?: number;
} }
export type SankeyDiagramConfig = BaseDiagramConfig; export enum SankeyLinkColor {
source = 'source',
target = 'target',
gradient = 'gradient',
}
export interface SankeyDiagramConfig extends BaseDiagramConfig {
width?: number;
height?: number;
linkColor?: SankeyLinkColor | string;
}
export interface FontConfig { export interface FontConfig {
fontSize?: string | number; fontSize?: string | number;

View File

@@ -2270,6 +2270,11 @@ const config: Partial<MermaidConfig> = {
padding: 10, padding: 10,
maxNodeWidth: 200, maxNodeWidth: 200,
}, },
sankey: {
width: 800,
height: 400,
linkColor: 'gradient',
},
fontSize: 16, fontSize: 16,
}; };

View File

@@ -20,7 +20,7 @@ let nodesMap: Record<string, SankeyNode> = {};
let nodeAlign = 'justify'; let nodeAlign = 'justify';
const setNodeAlign = (alignment: string): void => { const setNodeAlign = (alignment: string): void => {
const nodeAlignments: Set<string>= new Set(['left', 'right', 'center', 'justify']); const nodeAlignments: Set<string> = new Set(['left', 'right', 'center', 'justify']);
if (nodeAlignments.has(alignment)) { if (nodeAlignments.has(alignment)) {
nodeAlign = alignment; nodeAlign = alignment;
} }

View File

@@ -20,9 +20,10 @@ import {
} from 'd3-sankey'; } from 'd3-sankey';
import { configureSvgSize } from '../../setupGraphViewbox.js'; import { configureSvgSize } from '../../setupGraphViewbox.js';
import { Uid } from './sankeyUtils.js'; import { Uid } from './sankeyUtils.js';
import { SankeyLinkColor } from '../../config.type.js';
/** /**
* Draws a sequenceDiagram in the tag with id: id based on the graph definition in text. * Draws Sankey diagram.
* *
* @param text - The text of the diagram * @param text - The text of the diagram
* @param id - The id of the diagram which will be used as a DOM element id¨ * @param id - The id of the diagram which will be used as a DOM element id¨
@@ -30,10 +31,14 @@ import { Uid } from './sankeyUtils.js';
* @param diagObj - A standard diagram containing the db and the text and type etc of the diagram * @param diagObj - A standard diagram containing the db and the text and type etc of the diagram
*/ */
export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void { export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
// TODO: Figure out what is happening there // Get Sankey config
const { securityLevel, sankey: conf } = configApi.getConfig();
// TODO:
// This code repeats for every diagram
// Figure out what is happening there, probably it should be separated
// The main thing is svg object that is a d3 wrapper for svg operations // The main thing is svg object that is a d3 wrapper for svg operations
// //
const { securityLevel, sequence: conf } = configApi.getConfig();
let sandboxElement: any; let sandboxElement: any;
if (securityLevel === 'sandbox') { if (securityLevel === 'sandbox') {
sandboxElement = d3select('#i' + id); sandboxElement = d3select('#i' + id);
@@ -43,18 +48,17 @@ export const draw = function (text: string, id: string, _version: string, diagOb
if (securityLevel === 'sandbox' && sandboxElement) { if (securityLevel === 'sandbox' && sandboxElement) {
root = d3select(sandboxElement.nodes()[0].contentDocument.body); root = d3select(sandboxElement.nodes()[0].contentDocument.body);
} }
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`); const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`);
// Establish svg dimensions and get width and height // Establish svg dimensions and get width and height
// //
const elem = doc.getElementById(id); const width = conf?.width || 800;
const width = elem.parentElement.offsetWidth; const height = conf?.height || 400;
const height = 600; const useMaxWidth = conf?.useMaxWidth || false;
// FIX: using max width prevents height from being set // FIX: using max width prevents height from being set, is it intended?
configureSvgSize(svg, height, width, false); // to add height directly one can use `svg.attr('height', height)`
// svg.attr('height', height); // that's why we need this line configureSvgSize(svg, height, width, useMaxWidth);
// Prepare data for construction based on diagObj.db // Prepare data for construction based on diagObj.db
// This must be a mutable object with `nodes` and `links` properties: // This must be a mutable object with `nodes` and `links` properties:
@@ -142,27 +146,46 @@ export const draw = function (text: string, id: string, _version: string, diagOb
.attr('class', 'link') .attr('class', 'link')
.style('mix-blend-mode', 'multiply'); .style('mix-blend-mode', 'multiply');
const gradient = link const linkColor = conf?.linkColor || SankeyLinkColor.gradient;
.append('linearGradient')
.attr('id', (d) => (d.uid = Uid.next('linearGradient-')).id)
.attr('gradientUnits', 'userSpaceOnUse')
.attr('x1', (d) => d.source.x1)
.attr('x2', (d) => d.target.x0);
gradient if (linkColor === SankeyLinkColor.gradient) {
.append('stop') const gradient = link
.attr('offset', '0%') .append('linearGradient')
.attr('stop-color', (d) => colorScheme(d.source.id)); .attr('id', (d) => (d.uid = Uid.next('linearGradient-')).id)
.attr('gradientUnits', 'userSpaceOnUse')
.attr('x1', (d) => d.source.x1)
.attr('x2', (d) => d.target.x0);
gradient gradient
.append('stop') .append('stop')
.attr('offset', '100%') .attr('offset', '0%')
.attr('stop-color', (d) => colorScheme(d.target.id)); .attr('stop-color', (d) => colorScheme(d.source.id));
gradient
.append('stop')
.attr('offset', '100%')
.attr('stop-color', (d) => colorScheme(d.target.id));
}
let coloring: any;
switch (linkColor) {
case SankeyLinkColor.gradient:
coloring = (d) => d.uid;
break;
case SankeyLinkColor.source:
coloring = (d) => d.source.id;
break;
case SankeyLinkColor.target:
coloring = (d) => d.target.id;
break;
default:
coloring = linkColor;
}
link link
.append('path') .append('path')
.attr('d', d3SankeyLinkHorizontal()) .attr('d', d3SankeyLinkHorizontal())
.attr('stroke', (d: any) => d.uid) .attr('stroke', coloring)
.attr('stroke-width', (d: any) => Math.max(1, d.width)); .attr('stroke-width', (d: any) => Math.max(1, d.width));
}; };

View File

@@ -24,4 +24,4 @@ export class Uid {
toString(): string { toString(): string {
return 'url(' + this.href + ')'; return 'url(' + this.href + ')';
} }
} }