#5237 Theme support

This commit is contained in:
Knut Sveidqvist 2024-05-10 13:21:39 +02:00
parent 7ecb772c6c
commit ce6f2739b5
11 changed files with 85 additions and 55 deletions

View File

@ -32,7 +32,7 @@
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
/* background: #333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
@ -45,12 +45,14 @@
.mermaid svg {
/* font-size: 18px !important; */
background-color: #efefef;
/* background-color: #efefef;
background-image: radial-gradient(#fff 51%, transparent 91%),
radial-gradient(#fff 51%, transparent 91%);
background-size: 20px 20px;
background-position: 0 0, 10px 10px;
background-repeat: repeat;
background-position:
0 0,
10px 10px;
background-repeat: repeat; */
}
.malware {
position: fixed;
@ -107,6 +109,22 @@ stateDiagram-v2
</pre
>
<pre id="diagram" class="mermaid">
%%{init: {"handdrawn": "true"} }%%
stateDiagram-v2
state ProActive {
state Active {
Chimp --> A:One
Chimp --> B:Two
Chimp --> C:Three
state InActive {
D
}
}
}
</pre
>
<pre id="diagram" class="mermaid">
%%{init: {"handdrawn": false} }%%
stateDiagram-v2
state ProActive {
state Active {
@ -511,6 +529,7 @@ mindmap
// useMaxWidth: false,
// });
mermaid.initialize({
theme: 'base',
handdrawn: true,
// layout: 'dagre',
layout: 'elk',

View File

@ -1,17 +1,8 @@
import insertMarkers from '../../rendering-elements/markers.js';
import { findCommonAncestor } from './find-common-ancestor.js';
import { getConfig } from '$root/diagram-api/diagramAPI.js';
import {
insertNode,
positionNode,
clear as clearNodes,
setNodeElem,
} from '../../rendering-elements/nodes.js';
import {
insertCluster,
clear as clearClusters,
positionCluster,
} from '../../rendering-elements/clusters.js';
import { insertNode, clear as clearNodes } from '../../rendering-elements/nodes.js';
import { insertCluster, clear as clearClusters } from '../../rendering-elements/clusters.js';
import {
insertEdgeLabel,
positionEdgeLabel,
@ -116,14 +107,12 @@ const drawNodes = (relX, relY, nodeArray, svg, subgraphsEl, depth) => {
if (node.type === 'group') {
log.debug('Id abc88 subgraph = ', node.id, node.x, node.y, node.labelData);
const subgraphEl = subgraphsEl.insert('g').attr('class', 'subgraph');
// TODO use faster way of cloning
const clusterNode = JSON.parse(JSON.stringify(node));
clusterNode.x = node.offset.posX + node.width / 2;
clusterNode.y = node.offset.posY + node.height / 2;
// clusterNode.y = node.y + node.height / 2;
const cluster = insertCluster(subgraphEl, clusterNode);
// const bbox = cluster.node().getBBox();
// node.x -= bbox.width / 2 - 2; // Magic number 2... why??? WHY???
// node.y -= bbox.height / 2;
log.info('Id (UGH)= ', node.shape, node.labels);
} else {
log.info(
@ -524,6 +513,7 @@ export const render = async (data4Layout, svg, element) => {
height: node?.labelData?.height || 100,
},
];
node['elk.direction'] = 'RIGHT';
delete node.x;
delete node.y;
delete node.width;
@ -533,7 +523,7 @@ export const render = async (data4Layout, svg, element) => {
log.info('before layout', JSON.stringify(elkGraph, null, 2));
const g = await elk.layout(elkGraph);
log.info('after layout DAGA', g);
log.info('after layout DAGA', JSON.stringify(g));
// debugger;
drawNodes(0, 0, g.children, svg, subGraphsEl, 0);

View File

@ -134,6 +134,12 @@ const noteGroup = (parent, node) => {
const roundedWithTitle = (parent, node) => {
const siteConfig = getConfig();
console.log('DAGO node in roundedWithTitle', siteConfig.themeVariables);
const { themeVariables } = siteConfig;
const { altBackground, compositeBackground, compositeTitleBackground, nodeBorder } =
themeVariables;
// Add outer g element
const shapeSvg = parent.insert('g').attr('class', node.classes).attr('id', node.id);
@ -178,28 +184,26 @@ const roundedWithTitle = (parent, node) => {
// add the rect
let rect;
if (node.useRough) {
const isAlt = node.classes.indexOf('statediagram-cluster-alt') >= 0;
console.log(
'DAGA node in roundedWithTitle',
node.classes,
node.classes.indexOf('statediagram-cluster-alt'),
isAlt
);
const isAlt = node.classes.includes('statediagram-cluster-alt');
const rc = rough.svg(shapeSvg);
const roughOuterNode =
node.rx || node.ry
? rc.path(createRoundedRectPathD(x, y, width, height, 10), {
roughness: 0.7,
fill: compositeTitleBackground,
fillStyle: 'solid',
stroke: nodeBorder,
})
: rc.rectangle(x, y, width, height);
rect = shapeSvg.insert(() => roughOuterNode);
rect = shapeSvg.insert(() => roughOuterNode, ':first-child');
const roughInnerNode = rc.rectangle(x, innerY, width, innerHeight, {
fill: isAlt ? 'lightgrey' : 'white',
fill: isAlt ? altBackground : compositeBackground,
fillStyle: isAlt ? 'hachure' : 'solid',
stroke: nodeBorder,
});
rect = shapeSvg.insert(() => roughOuterNode);
rect = shapeSvg.insert(() => roughOuterNode, ':first-child');
innerRect = shapeSvg.insert(() => roughInnerNode);
} else {
rect = outerRectG.insert('rect', ':first-child');

View File

@ -2,7 +2,7 @@ import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js';
import rough from 'roughjs';
import solidFillOptions from './solidFillOptions.js';
import { solidStateFill } from './handdrawnStyles.js';
export const choice = (parent: SVG, node: Node) => {
const shapeSvg = parent
.insert('g')
@ -23,7 +23,7 @@ export const choice = (parent: SVG, node: Node) => {
const pointArr = points.map(function (d) {
return [d.x, d.y];
});
const roughNode = rc.polygon(pointArr, solidFillOptions);
const roughNode = rc.polygon(pointArr, solidStateFill('black'));
choice = shapeSvg.insert(() => roughNode);
} else {
choice = shapeSvg.insert('polygon', ':first-child').attr(

View File

@ -4,7 +4,7 @@ import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js';
import rough from 'roughjs';
import solidFillOptions from './solidFillOptions.js';
import { solidStateFill } from './handdrawnStyles.js';
export const forkJoin = (parent: SVG, node: Node, dir: string) => {
const shapeSvg = parent
@ -25,7 +25,7 @@ export const forkJoin = (parent: SVG, node: Node, dir: string) => {
let shape;
if (node.useRough) {
const rc = rough.svg(shapeSvg);
const roughNode = rc.rectangle(x, y, width, height, solidFillOptions);
const roughNode = rc.rectangle(x, y, width, height, solidStateFill('black'));
shape = shapeSvg.insert(() => roughNode);
} else {
shape = shapeSvg

View File

@ -0,0 +1,11 @@
// Striped fill like start or fork nodes in state diagrams
export const solidStateFill = (color: string) => {
return {
fill: color,
// fillStyle: 'solid',
hachureAngle: 120, // angle of hachure,
hachureGap: 4,
fillWeight: 2,
roughness: 0.7,
};
};

View File

@ -3,6 +3,7 @@ import { labelHelper, updateNodeBounds } from './util.js';
import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import { createRoundedRectPathD } from './roundedRectPath.js';
import { getConfig } from '$root/diagram-api/diagramAPI.js';
import rough from 'roughjs';
/**
@ -57,6 +58,21 @@ function applyNodePropertyBorders(
}
export const rect = async (parent: SVGAElement, node: Node) => {
const { themeVariables } = getConfig();
const {
textColor,
clusterTextColor,
altBackground,
compositeBackground,
compositeTitleBackground,
compositeBorder,
noteBorderColor,
noteBkgColor,
nodeBorder,
mainBkg,
stateBorder,
} = themeVariables;
const { shapeSvg, bbox, halfPadding } = await labelHelper(
parent,
node,
@ -77,15 +93,14 @@ export const rect = async (parent: SVGAElement, node: Node) => {
rx || ry
? rc.path(createRoundedRectPathD(x, y, totalWidth, totalHeight, rx || 0), {
roughness: 0.7,
fill:'white',
fillStyle: 'solid' // solid fill'
fill: mainBkg,
fillStyle: 'solid', // solid fill'
stroke: nodeBorder,
})
: rc.rectangle(x, y, totalWidth, totalHeight);
rect = shapeSvg.insert(() => roughNode, ':first-child');
rect
.attr('class', 'basic label-container')
.attr('style', style)
rect.attr('class', 'basic label-container').attr('style', style);
} else {
rect = shapeSvg.insert('rect', ':first-child');

View File

@ -1,10 +0,0 @@
const options = {
fill: 'black',
// fillStyle: 'solid',
hachureAngle: 120, // angle of hachure,
hachureGap: 4,
fillWeight: 2,
roughness: 0.7,
};
export default options;

View File

@ -4,7 +4,7 @@ import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js';
import rough from 'roughjs';
import solidFillOptions from './solidFillOptions.js';
import { solidStateFill } from './handdrawnStyles.js';
export const stateEnd = (parent: SVG, node: Node) => {
const shapeSvg = parent
@ -26,7 +26,7 @@ export const stateEnd = (parent: SVG, node: Node) => {
if (node.useRough) {
const rc = rough.svg(shapeSvg);
const roughNode = rc.circle(0, 0, 14, { roughness: 0.5 });
const roughInnerNode = rc.circle(0, 0, 5, { ...solidFillOptions, fillStyle: 'solid' });
const roughInnerNode = rc.circle(0, 0, 5, { ...solidStateFill('black'), fillStyle: 'solid' });
circle = shapeSvg.insert(() => roughNode);
innerCircle = shapeSvg.insert(() => roughInnerNode);
} else {

View File

@ -4,7 +4,7 @@ import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js';
import rough from 'roughjs';
import solidFillOptions from './solidFillOptions.js';
import { solidStateFill } from './handdrawnStyles.js';
export const stateStart = (parent: SVG, node: Node) => {
const shapeSvg = parent
@ -15,7 +15,7 @@ export const stateStart = (parent: SVG, node: Node) => {
let circle;
if (node.useRough) {
const rc = rough.svg(shapeSvg);
const roughNode = rc.circle(0, 0, 14, solidFillOptions);
const roughNode = rc.circle(0, 0, 14, solidStateFill('black'));
circle = shapeSvg.insert(() => roughNode);
} else {
circle = shapeSvg.insert('circle', ':first-child');

View File

@ -6,7 +6,6 @@ class Theme {
this.background = '#333';
this.primaryColor = '#1f2020';
this.secondaryColor = lighten(this.primaryColor, 16);
this.tertiaryColor = adjust(this.primaryColor, { h: -160 });
this.primaryBorderColor = invert(this.background);
this.secondaryBorderColor = mkBorder(this.secondaryColor, this.darkMode);
@ -22,7 +21,7 @@ class Theme {
this.mainContrastColor = 'lightgrey';
this.darkTextColor = lighten(invert('#323D47'), 10);
this.lineColor = 'calculated';
this.border1 = '#81B1DB';
this.border1 = '#ccc';
this.border2 = rgba(255, 255, 255, 0.25);
this.arrowheadColor = 'calculated';
this.fontFamily = '"trebuchet ms", verdana, arial, sans-serif';
@ -333,6 +332,8 @@ class Theme {
this.attributeBackgroundColorEven =
this.attributeBackgroundColorEven || lighten(this.background, 2);
/* -------------------------------------------------- */
this.nodeBorder = this.nodeBorder || '#999';
}
calculate(overrides) {
if (typeof overrides !== 'object') {