mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-12-05 03:54:35 +01:00
Merge remote-tracking branch 'upstream/develop' into sidv/fixE2E
* upstream/develop: (33 commits) Updated lockfile chore(deps-dev): update vite requirement from ^3.0.9 to ^3.1.4 chore(deps-dev): update typescript requirement from ^4.8.3 to ^4.8.4 chore(deps-dev): update @vitest/coverage-c8 requirement chore(deps-dev): update @typescript-eslint/eslint-plugin requirement chore(deps-dev): update esbuild requirement from ^0.15.8 to ^0.15.10 chore(deps-dev): update @commitlint/config-conventional requirement chore(deps-dev): update eslint-plugin-jest requirement chore(deps-dev): update @applitools/eyes-cypress requirement chore(deps-dev): update jsdom requirement from ^20.0.0 to ^20.0.1 chore(deps-dev): update vitest requirement from ^0.23.1 to ^0.23.4 chore(deps-dev): update lint-staged requirement from ^13.0.0 to ^13.0.3 chore(deps): update @types/node requirement from ^18.7.21 to ^18.8.1 chore(deps-dev): update @typescript-eslint/parser requirement Fix postbuild script #3561 Adding cScale0-11 etc and usage of the colors from the mindmap diagram Fix for broken test Mindmap cleanup Using cose-bilkent layout algorithm for mindmaps chore(deps-dev): update husky requirement from ^8.0.0 to ^8.0.1 ...
This commit is contained in:
@@ -7,8 +7,8 @@ describe('when parsing an info graph it', function () {
|
||||
ex.yy = db;
|
||||
});
|
||||
|
||||
it('should handle an info definition', function () {
|
||||
let str = `info
|
||||
it('should handle an example-diagram definition', function () {
|
||||
let str = `example-diagram
|
||||
showInfo`;
|
||||
|
||||
ex.parse(str);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** Created by knut on 14-12-11. */
|
||||
import { select } from 'd3';
|
||||
import { log, getConfig } from './mermaidUtils';
|
||||
import { log, getConfig, setupGraphViewbox } from './mermaidUtils';
|
||||
|
||||
/**
|
||||
* Draws a an info picture in the tag with id: id based on the graph definition in text.
|
||||
@@ -10,10 +10,11 @@ import { log, getConfig } from './mermaidUtils';
|
||||
* @param {any} version
|
||||
* @param diagObj
|
||||
*/
|
||||
export const draw = (text, id, version, diagObj) => {
|
||||
export const draw = (text, id, version) => {
|
||||
try {
|
||||
log.debug('Rendering info diagram\n' + text);
|
||||
|
||||
const conf = getConfig();
|
||||
log.debug('Rendering example diagram\n' + text, 'Conf: ');
|
||||
const THEME_COLOR_LIMIT = getConfig().themeVariables.THEME_COLOR_LIMIT;
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and Document for when rendering in sanbox mode
|
||||
let sandboxElement;
|
||||
@@ -25,14 +26,34 @@ export const draw = (text, id, version, diagObj) => {
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
|
||||
// Parse the graph definition
|
||||
// parser.parse(text);
|
||||
// log.debug('Parsed info diagram');
|
||||
// Fetch the default direction, use TD if none was found
|
||||
const svg = root.select('#' + id);
|
||||
|
||||
const g = svg.append('g');
|
||||
|
||||
let i;
|
||||
for (i = 0; i < THEME_COLOR_LIMIT; i++) {
|
||||
const section = g.append('g').attr('class', 'section-' + i);
|
||||
section
|
||||
.append('rect')
|
||||
.attr('x', (i % 5) * 110)
|
||||
.attr('y', Math.floor(i / 5) * 90 + 60)
|
||||
.attr('width', 100)
|
||||
.attr('height', 60);
|
||||
section
|
||||
.append('rect')
|
||||
.attr('x', (i % 5) * 110)
|
||||
.attr('y', Math.floor(i / 5) * 90 + 120)
|
||||
.attr('class', 'inverted')
|
||||
.attr('width', 100)
|
||||
.attr('height', 20);
|
||||
section
|
||||
.append('text', 'section-' + i)
|
||||
.text('Section ' + i)
|
||||
.attr('x', (i % 5) * 110 + 15)
|
||||
.attr('y', Math.floor(i / 5) * 90 + 95)
|
||||
.attr('class', 'section-text-' + i);
|
||||
}
|
||||
|
||||
g.append('text') // text label for the x axis
|
||||
.attr('x', 100)
|
||||
.attr('y', 40)
|
||||
@@ -41,9 +62,8 @@ export const draw = (text, id, version, diagObj) => {
|
||||
.style('text-anchor', 'middle')
|
||||
.text('v ' + version);
|
||||
|
||||
svg.attr('height', 100);
|
||||
svg.attr('width', 400);
|
||||
// svg.attr('viewBox', '0 0 300 150');
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
|
||||
} catch (e) {
|
||||
log.error('Error while rendering info diagram');
|
||||
log.error(e.message);
|
||||
|
||||
@@ -19,7 +19,6 @@ export const log: Record<keyof typeof LEVELS, typeof console.log> = {
|
||||
error: warning,
|
||||
fatal: warning,
|
||||
};
|
||||
|
||||
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
|
||||
export let getConfig: () => object;
|
||||
export let sanitizeText: (str: string) => string;
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
const getStyles = () => ``;
|
||||
import { darken, lighten, isDark } from 'khroma';
|
||||
|
||||
const genSections = (options) => {
|
||||
let sections = '';
|
||||
|
||||
for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {
|
||||
sections += `
|
||||
.section-${i} rect {
|
||||
fill: ${options['cScale' + i]};
|
||||
stroke: ${options['cScalePeer' + i]};
|
||||
stroke-width: 4;
|
||||
}
|
||||
.section-${i} rect.inverted {
|
||||
fill: ${options['cScaleInv' + i]};
|
||||
}
|
||||
.section-${i} text {
|
||||
fill: ${options['cScaleLabel' + i]};
|
||||
}
|
||||
|
||||
`;
|
||||
}
|
||||
return sections;
|
||||
};
|
||||
|
||||
const getStyles = (options) =>
|
||||
`
|
||||
${genSections(options)}
|
||||
`;
|
||||
export default getStyles;
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.0",
|
||||
"cytoscape": "^3.23.0",
|
||||
"cytoscape-cose-bilkent": "^4.1.0",
|
||||
"cytoscape-fcose": "^2.1.0",
|
||||
"d3": "^7.0.0",
|
||||
"non-layered-tidy-tree-layout": "^2.0.2"
|
||||
},
|
||||
|
||||
@@ -5,12 +5,6 @@ import mindmapRenderer from './mindmapRenderer';
|
||||
import mindmapStyles from './styles';
|
||||
import { injectUtils } from './mermaidUtils';
|
||||
|
||||
// const getBaseFolder = (path: string) => {
|
||||
// const parts = path.split('/');
|
||||
// parts.pop();
|
||||
// return parts.join('/');
|
||||
// };
|
||||
|
||||
window.mermaid.connectDiagram(
|
||||
'mindmap',
|
||||
{
|
||||
|
||||
@@ -132,11 +132,7 @@ export const type2Str = (type) => {
|
||||
}
|
||||
};
|
||||
|
||||
export let parseError; // = (str, hash)
|
||||
// => {
|
||||
// const error = { str, hash };
|
||||
// throw error;
|
||||
// };
|
||||
export let parseError;
|
||||
export const setErrorHandler = (handler) => {
|
||||
parseError = handler;
|
||||
};
|
||||
@@ -146,17 +142,3 @@ export const getLogger = () => log;
|
||||
|
||||
export const getNodeById = (id) => nodes[id];
|
||||
export const getElementById = (id) => elements[id];
|
||||
// export default {
|
||||
// // getMindmap,
|
||||
// // addNode,
|
||||
// // clear,
|
||||
// // nodeType,
|
||||
// // getType,
|
||||
// // decorateNode,
|
||||
// // setElementForId,
|
||||
// getElementById: (id) => elements[id],
|
||||
// // getNodeById: (id) => nodes.find((node) => node.id === id),
|
||||
// getNodeById: (id) => nodes[id],
|
||||
// // type2Str,
|
||||
// // parseError
|
||||
// };
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
const detector = function detect(txt) {
|
||||
if (txt.match(/^\s*mindmap/)) {
|
||||
return 'mindmap';
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export default detector;
|
||||
@@ -2,11 +2,13 @@
|
||||
import { select } from 'd3';
|
||||
import { log, getConfig, setupGraphViewbox } from './mermaidUtils';
|
||||
import svgDraw from './svgDraw';
|
||||
import { BoundingBox, Layout } from 'non-layered-tidy-tree-layout';
|
||||
import cytoscape from 'cytoscape';
|
||||
import clone from 'fast-clone';
|
||||
import coseBilkent from 'cytoscape-cose-bilkent';
|
||||
import * as db from './mindmapDb';
|
||||
|
||||
// Inject the layout algorithm into cytoscape
|
||||
cytoscape.use(coseBilkent);
|
||||
|
||||
/**
|
||||
* @param {any} svg The svg element to draw the diagram onto
|
||||
* @param {object} mindmap The maindmap data and hierarchy
|
||||
@@ -28,184 +30,138 @@ function drawNodes(svg, mindmap, section, conf) {
|
||||
* @param parent
|
||||
* @param depth
|
||||
* @param section
|
||||
* @param conf
|
||||
* @param edgesEl
|
||||
* @param cy
|
||||
*/
|
||||
function drawEdges(edgesElem, mindmap, parent, depth, section, conf) {
|
||||
if (parent) {
|
||||
svgDraw.drawEdge(edgesElem, mindmap, parent, depth, section, conf);
|
||||
}
|
||||
if (mindmap.children) {
|
||||
mindmap.children.forEach((child, index) => {
|
||||
drawEdges(edgesElem, child, mindmap, depth + 1, section < 0 ? index : section, conf);
|
||||
});
|
||||
}
|
||||
function drawEdges(edgesEl, cy) {
|
||||
cy.edges().map((edge, id) => {
|
||||
const data = edge.data();
|
||||
if (edge[0]._private.bodyBounds) {
|
||||
const bounds = edge[0]._private.rscratch;
|
||||
log.trace('Edge: ', id, data);
|
||||
edgesEl
|
||||
.insert('path')
|
||||
.attr(
|
||||
'd',
|
||||
`M ${bounds.startX},${bounds.startY} L ${bounds.midX},${bounds.midY} L${bounds.endX},${bounds.endY} `
|
||||
)
|
||||
.attr('class', 'edge section-edge-' + data.section + ' edge-depth-' + data.depth);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mindmap
|
||||
* @param callback
|
||||
* @param {any} svg The svg element to draw the diagram onto
|
||||
* @param {object} mindmap The maindmap data and hierarchy
|
||||
* @param section
|
||||
* @param cy
|
||||
* @param {object} conf The configuration object
|
||||
* @param level
|
||||
*/
|
||||
function eachNode(mindmap, callback) {
|
||||
callback(mindmap);
|
||||
function addNodes(mindmap, cy, conf, level) {
|
||||
cy.add({
|
||||
group: 'nodes',
|
||||
data: {
|
||||
id: mindmap.id,
|
||||
labelText: mindmap.descr,
|
||||
height: mindmap.height,
|
||||
width: mindmap.width,
|
||||
level: level,
|
||||
nodeId: mindmap.id,
|
||||
padding: mindmap.padding,
|
||||
type: mindmap.type,
|
||||
},
|
||||
position: {
|
||||
x: mindmap.x,
|
||||
y: mindmap.y,
|
||||
},
|
||||
});
|
||||
if (mindmap.children) {
|
||||
mindmap.children.forEach((child) => {
|
||||
eachNode(child, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
/** @param {object} mindmap */
|
||||
function transpose(mindmap) {
|
||||
eachNode(mindmap, (node) => {
|
||||
const orgWidth = node.width;
|
||||
const orgX = node.x;
|
||||
node.width = node.height;
|
||||
node.height = orgWidth;
|
||||
node.x = node.y;
|
||||
node.y = orgX;
|
||||
});
|
||||
return mindmap;
|
||||
}
|
||||
/** @param {object} mindmap */
|
||||
function bottomToUp(mindmap) {
|
||||
log.debug('bottomToUp', mindmap);
|
||||
eachNode(mindmap.result, (node) => {
|
||||
// node.y = node.y - (node.y - bb.top) * 2 - node.height;
|
||||
node.y = node.y - (node.y - 0) * 2 - node.height;
|
||||
});
|
||||
return mindmap;
|
||||
}
|
||||
/** @param {object} mindmap The mindmap hierarchy */
|
||||
function rightToLeft(mindmap) {
|
||||
eachNode(mindmap.result, (node) => {
|
||||
// node.y = node.y - (node.y - bb.top) * 2 - node.height;
|
||||
node.x = node.x - (node.x - 0) * 2 - node.width;
|
||||
});
|
||||
return mindmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mindmap
|
||||
* @param dir
|
||||
*/
|
||||
function layout(mindmap, dir) {
|
||||
const bb = new BoundingBox(30, 60);
|
||||
|
||||
const layout = new Layout(bb);
|
||||
switch (dir) {
|
||||
case 'TB':
|
||||
return layout.layout(mindmap);
|
||||
case 'BT':
|
||||
return bottomToUp(layout.layout(mindmap));
|
||||
case 'RL': {
|
||||
transpose(mindmap);
|
||||
let newRes = layout.layout(mindmap);
|
||||
transpose(newRes.result);
|
||||
return rightToLeft(newRes);
|
||||
}
|
||||
case 'LR': {
|
||||
transpose(mindmap);
|
||||
let newRes = layout.layout(mindmap);
|
||||
transpose(newRes.result);
|
||||
return newRes;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
const dirFromIndex = (index) => {
|
||||
const dirNum = (index + 2) % 4;
|
||||
switch (dirNum) {
|
||||
case 0:
|
||||
return 'LR';
|
||||
case 1:
|
||||
return 'RL';
|
||||
case 2:
|
||||
return 'TB';
|
||||
case 3:
|
||||
return 'BT';
|
||||
default:
|
||||
return 'TB';
|
||||
}
|
||||
};
|
||||
|
||||
const mergeTrees = (node, trees) => {
|
||||
node.x = trees[0].result.x;
|
||||
node.y = trees[0].result.y;
|
||||
trees.forEach((tree) => {
|
||||
tree.result.children.forEach((child) => {
|
||||
const dx = node.x - tree.result.x;
|
||||
const dy = node.y - tree.result.y;
|
||||
eachNode(child, (childNode) => {
|
||||
const orgNode = db.getNodeById(childNode.id);
|
||||
if (orgNode) {
|
||||
orgNode.x = childNode.x + dx;
|
||||
orgNode.y = childNode.y + dy;
|
||||
}
|
||||
addNodes(child, cy, conf, level + 1);
|
||||
cy.add({
|
||||
group: 'edges',
|
||||
data: {
|
||||
id: `${mindmap.id}_${child.id}`,
|
||||
source: mindmap.id,
|
||||
target: child.id,
|
||||
depth: level,
|
||||
section: child.section,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
return node;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param conf
|
||||
* @param cy
|
||||
*/
|
||||
function layoutMindmap(node, conf) {
|
||||
// BoundingBox(gap, bottomPadding)
|
||||
// const bb = new BoundingBox(10, 10);
|
||||
// const layout = new Layout(bb);
|
||||
// // const layout = new HorizontalLayout(bb);
|
||||
if (node.children.length === 0) {
|
||||
return node;
|
||||
}
|
||||
const trees = [];
|
||||
// node.children.forEach((child, index) => {
|
||||
// const tree = clone(node);
|
||||
// tree.children = [tree.children[index]];
|
||||
// trees.push(layout(tree, dirFromIndex(index), conf));
|
||||
// });
|
||||
return new Promise((resolve) => {
|
||||
if (node.children.length === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
let cnt = 0;
|
||||
// For each direction, create a new tree with the same root, and add a ubset of the children to it.
|
||||
for (let i = 0; i < 4; i++) {
|
||||
// Calculate the number of the children of the root node that will be used in this direction
|
||||
const numChildren =
|
||||
Math.floor(node.children.length / 4) + (node.children.length % 4 > i ? 1 : 0);
|
||||
// Copy the original root node
|
||||
const tree = clone(node);
|
||||
// Setup the new copy with the children to be rendered in this direction
|
||||
tree.children = [];
|
||||
for (let j = 0; j < numChildren; j++) {
|
||||
tree.children.push(node.children[cnt]);
|
||||
cnt++;
|
||||
}
|
||||
if (tree.children.length > 0) {
|
||||
trees.push(layout(tree, dirFromIndex(i), conf));
|
||||
}
|
||||
}
|
||||
// Let each node know the direct of its tree for when we draw the branches.
|
||||
trees.forEach((tree, index) => {
|
||||
tree.result.direction = dirFromIndex(index);
|
||||
eachNode(tree.result, (node) => {
|
||||
node.direction = dirFromIndex(index);
|
||||
// Add temporary render element
|
||||
const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none');
|
||||
const cy = cytoscape({
|
||||
container: document.getElementById('cy'), // container to render in
|
||||
style: [
|
||||
{
|
||||
selector: 'edge',
|
||||
style: {
|
||||
'curve-style': 'bezier',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
// Remove element after layout
|
||||
renderEl.remove();
|
||||
addNodes(node, cy, conf, 0);
|
||||
|
||||
// Make cytoscape care about the dimensisions of the nodes
|
||||
cy.nodes().forEach(function (n) {
|
||||
n.layoutDimensions = () => {
|
||||
const data = n.data();
|
||||
return { w: data.width, h: data.height };
|
||||
};
|
||||
});
|
||||
|
||||
cy.layout({
|
||||
name: 'cose-bilkent',
|
||||
quality: 'proof',
|
||||
// headless: true,
|
||||
styleEnabled: false,
|
||||
animate: false,
|
||||
}).run();
|
||||
cy.ready((e) => {
|
||||
log.info('Ready', e);
|
||||
resolve(cy);
|
||||
});
|
||||
});
|
||||
|
||||
// Merge the trees into a single tree
|
||||
mergeTrees(node, trees);
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* @param node
|
||||
* @param cy
|
||||
* @param positionedMindmap
|
||||
* @param conf
|
||||
*/
|
||||
function positionNodes(node, conf) {
|
||||
svgDraw.positionNode(node, conf);
|
||||
if (node.children) {
|
||||
node.children.forEach((child) => {
|
||||
positionNodes(child, conf);
|
||||
});
|
||||
}
|
||||
function positionNodes(cy) {
|
||||
cy.nodes().map((node, id) => {
|
||||
const data = node.data();
|
||||
data.x = node.position().x;
|
||||
data.y = node.position().y;
|
||||
svgDraw.positionNode(data);
|
||||
const el = db.getElementById(data.nodeId);
|
||||
log.info('Id:', id, 'Position: (', node.position().x, ', ', node.position().y, ')', data);
|
||||
el.attr(
|
||||
'transform',
|
||||
`translate(${node.position().x - data.width / 2}, ${node.position().y - data.height / 2})`
|
||||
);
|
||||
el.attr('attr', `apa-${id})`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,7 +173,7 @@ function positionNodes(node, conf) {
|
||||
* @param diagObj
|
||||
*/
|
||||
|
||||
export const draw = (text, id, version, diagObj) => {
|
||||
export const draw = async (text, id, version, diagObj) => {
|
||||
const conf = getConfig();
|
||||
|
||||
// This is done only for throwing the error if the text is not valid.
|
||||
@@ -255,11 +211,11 @@ export const draw = (text, id, version, diagObj) => {
|
||||
|
||||
// Next step is to layout the mindmap, giving each node a position
|
||||
|
||||
const positionedMindmap = layoutMindmap(mm, conf);
|
||||
const cy = await layoutMindmap(mm, conf);
|
||||
|
||||
// After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf);
|
||||
positionNodes(positionedMindmap, conf);
|
||||
// // After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, cy, conf);
|
||||
positionNodes(cy, conf);
|
||||
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
|
||||
|
||||
@@ -1,269 +0,0 @@
|
||||
/** Created by knut on 14-12-11. */
|
||||
import { select } from 'd3';
|
||||
import { log, getConfig, setupGraphViewbox } from './mermaidUtils';
|
||||
import svgDraw from './svgDraw';
|
||||
import { BoundingBox, Layout } from 'non-layered-tidy-tree-layout';
|
||||
import clone from 'fast-clone';
|
||||
import * as db from './mindmapDb';
|
||||
|
||||
/**
|
||||
* @param {any} svg The svg element to draw the diagram onto
|
||||
* @param {object} mindmap The maindmap data and hierarchy
|
||||
* @param section
|
||||
* @param {object} conf The configuration object
|
||||
*/
|
||||
function drawNodes(svg, mindmap, section, conf) {
|
||||
svgDraw.drawNode(svg, mindmap, section, conf);
|
||||
if (mindmap.children) {
|
||||
mindmap.children.forEach((child, index) => {
|
||||
drawNodes(svg, child, section < 0 ? index : section, conf);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param edgesElem
|
||||
* @param mindmap
|
||||
* @param parent
|
||||
* @param depth
|
||||
* @param section
|
||||
* @param conf
|
||||
*/
|
||||
function drawEdges(edgesElem, mindmap, parent, depth, section, conf) {
|
||||
if (parent) {
|
||||
svgDraw.drawEdge(edgesElem, mindmap, parent, depth, section, conf);
|
||||
}
|
||||
if (mindmap.children) {
|
||||
mindmap.children.forEach((child, index) => {
|
||||
drawEdges(edgesElem, child, mindmap, depth + 1, section < 0 ? index : section, conf);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mindmap
|
||||
* @param callback
|
||||
*/
|
||||
function eachNode(mindmap, callback) {
|
||||
callback(mindmap);
|
||||
if (mindmap.children) {
|
||||
mindmap.children.forEach((child) => {
|
||||
eachNode(child, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
/** @param {object} mindmap */
|
||||
function transpose(mindmap) {
|
||||
eachNode(mindmap, (node) => {
|
||||
const orgWidth = node.width;
|
||||
const orgX = node.x;
|
||||
node.width = node.height;
|
||||
node.height = orgWidth;
|
||||
node.x = node.y;
|
||||
node.y = orgX;
|
||||
});
|
||||
return mindmap;
|
||||
}
|
||||
/** @param {object} mindmap */
|
||||
function bottomToUp(mindmap) {
|
||||
log.debug('bottomToUp', mindmap);
|
||||
eachNode(mindmap.result, (node) => {
|
||||
// node.y = node.y - (node.y - bb.top) * 2 - node.height;
|
||||
node.y = node.y - (node.y - 0) * 2 - node.height;
|
||||
});
|
||||
return mindmap;
|
||||
}
|
||||
/** @param {object} mindmap The mindmap hierarchy */
|
||||
function rightToLeft(mindmap) {
|
||||
eachNode(mindmap.result, (node) => {
|
||||
// node.y = node.y - (node.y - bb.top) * 2 - node.height;
|
||||
node.x = node.x - (node.x - 0) * 2 - node.width;
|
||||
});
|
||||
return mindmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mindmap
|
||||
* @param dir
|
||||
*/
|
||||
function layout(mindmap, dir) {
|
||||
const bb = new BoundingBox(30, 60);
|
||||
|
||||
const layout = new Layout(bb);
|
||||
switch (dir) {
|
||||
case 'TB':
|
||||
return layout.layout(mindmap);
|
||||
case 'BT':
|
||||
return bottomToUp(layout.layout(mindmap));
|
||||
case 'RL': {
|
||||
transpose(mindmap);
|
||||
let newRes = layout.layout(mindmap);
|
||||
transpose(newRes.result);
|
||||
return rightToLeft(newRes);
|
||||
}
|
||||
case 'LR': {
|
||||
transpose(mindmap);
|
||||
let newRes = layout.layout(mindmap);
|
||||
transpose(newRes.result);
|
||||
return newRes;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
const dirFromIndex = (index) => {
|
||||
const dirNum = (index + 2) % 4;
|
||||
switch (dirNum) {
|
||||
case 0:
|
||||
return 'LR';
|
||||
case 1:
|
||||
return 'RL';
|
||||
case 2:
|
||||
return 'TB';
|
||||
case 3:
|
||||
return 'BT';
|
||||
default:
|
||||
return 'TB';
|
||||
}
|
||||
};
|
||||
|
||||
const mergeTrees = (node, trees) => {
|
||||
node.x = trees[0].result.x;
|
||||
node.y = trees[0].result.y;
|
||||
trees.forEach((tree) => {
|
||||
tree.result.children.forEach((child) => {
|
||||
const dx = node.x - tree.result.x;
|
||||
const dy = node.y - tree.result.y;
|
||||
eachNode(child, (childNode) => {
|
||||
const orgNode = db.getNodeById(childNode.id);
|
||||
if (orgNode) {
|
||||
orgNode.x = childNode.x + dx;
|
||||
orgNode.y = childNode.y + dy;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param conf
|
||||
*/
|
||||
function layoutMindmap(node, conf) {
|
||||
// BoundingBox(gap, bottomPadding)
|
||||
// const bb = new BoundingBox(10, 10);
|
||||
// const layout = new Layout(bb);
|
||||
// // const layout = new HorizontalLayout(bb);
|
||||
if (node.children.length === 0) {
|
||||
return node;
|
||||
}
|
||||
const trees = [];
|
||||
// node.children.forEach((child, index) => {
|
||||
// const tree = clone(node);
|
||||
// tree.children = [tree.children[index]];
|
||||
// trees.push(layout(tree, dirFromIndex(index), conf));
|
||||
// });
|
||||
|
||||
let cnt = 0;
|
||||
// For each direction, create a new tree with the same root, and add a ubset of the children to it.
|
||||
for (let i = 0; i < 4; i++) {
|
||||
// Calculate the number of the children of the root node that will be used in this direction
|
||||
const numChildren =
|
||||
Math.floor(node.children.length / 4) + (node.children.length % 4 > i ? 1 : 0);
|
||||
// Copy the original root node
|
||||
const tree = clone(node);
|
||||
// Setup the new copy with the children to be rendered in this direction
|
||||
tree.children = [];
|
||||
for (let j = 0; j < numChildren; j++) {
|
||||
tree.children.push(node.children[cnt]);
|
||||
cnt++;
|
||||
}
|
||||
if (tree.children.length > 0) {
|
||||
trees.push(layout(tree, dirFromIndex(i), conf));
|
||||
}
|
||||
}
|
||||
// Let each node know the direct of its tree for when we draw the branches.
|
||||
trees.forEach((tree, index) => {
|
||||
tree.result.direction = dirFromIndex(index);
|
||||
eachNode(tree.result, (node) => {
|
||||
node.direction = dirFromIndex(index);
|
||||
});
|
||||
});
|
||||
|
||||
// Merge the trees into a single tree
|
||||
mergeTrees(node, trees);
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* @param node
|
||||
* @param conf
|
||||
*/
|
||||
function positionNodes(node, conf) {
|
||||
svgDraw.positionNode(node, conf);
|
||||
if (node.children) {
|
||||
node.children.forEach((child) => {
|
||||
positionNodes(child, conf);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a an info picture in the tag with id: id based on the graph definition in text.
|
||||
*
|
||||
* @param {any} text
|
||||
* @param {any} id
|
||||
* @param {any} version
|
||||
* @param diagObj
|
||||
*/
|
||||
|
||||
export const draw = (text, id, version, diagObj) => {
|
||||
const conf = getConfig();
|
||||
|
||||
// This is done only for throwing the error if the text is not valid.
|
||||
diagObj.db.clear();
|
||||
// Parse the graph definition
|
||||
diagObj.parser.parse(text);
|
||||
|
||||
log.debug('Renering info diagram\n' + text);
|
||||
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and Document for when rendering in sanbox mode
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
// Parse the graph definition
|
||||
|
||||
const svg = root.select('#' + id);
|
||||
|
||||
svg.append('g');
|
||||
const mm = diagObj.db.getMindmap();
|
||||
|
||||
// Draw the graph and start with drawing the nodes without proper position
|
||||
// this gives us the size of the nodes and we can set the positions later
|
||||
|
||||
const edgesElem = svg.append('g');
|
||||
edgesElem.attr('class', 'mindmap-edges');
|
||||
const nodesElem = svg.append('g');
|
||||
nodesElem.attr('class', 'mindmap-nodes');
|
||||
drawNodes(nodesElem, mm, -1, conf);
|
||||
|
||||
// Next step is to layout the mindmap, giving each node a position
|
||||
|
||||
const positionedMindmap = layoutMindmap(mm, conf);
|
||||
|
||||
// After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf);
|
||||
positionNodes(positionedMindmap, conf);
|
||||
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
|
||||
};
|
||||
|
||||
export default {
|
||||
draw,
|
||||
};
|
||||
@@ -1,24 +1,17 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import { mindmapDetector } from './mindmapDetector';
|
||||
|
||||
// const getBaseFolder = () => {
|
||||
const scriptElement = document.currentScript as HTMLScriptElement;
|
||||
const path = scriptElement.src;
|
||||
const lastSlash = path.lastIndexOf('/');
|
||||
const baseFolder = lastSlash < 0 ? path : path.substring(0, lastSlash + 1);
|
||||
|
||||
// };
|
||||
|
||||
// console.log('Current script', getBaseFolder(scriptElement !== null ? scriptElement.src : '')); // eslint-disable-line no-console
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
if (window.mermaid && typeof window.mermaid.detectors === 'object') {
|
||||
window.mermaid.detectors.push({ id: 'mindmap', detector: mindmapDetector });
|
||||
} else {
|
||||
// console.error('window.mermaid.detectors was not found!'); // eslint-disable-line no-console
|
||||
window.mermaid = {};
|
||||
window.mermaid.detectors = [{ id: 'mindmap', detector: mindmapDetector }];
|
||||
// console.error('Detectors now:', window.mermaid.detectors); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -3,8 +3,8 @@ import { darken, lighten, isDark } from 'khroma';
|
||||
const genSections = (options) => {
|
||||
let sections = '';
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
options['lineColor' + i] = options['lineColor' + i] || options['gitInv' + i];
|
||||
for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {
|
||||
options['lineColor' + i] = options['lineColor' + i] || options['cScaleInv' + i];
|
||||
if (isDark(options['lineColor' + i])) {
|
||||
options['lineColor' + i] = lighten(options['lineColor' + i], 20);
|
||||
} else {
|
||||
@@ -12,25 +12,25 @@ const genSections = (options) => {
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {
|
||||
const sw = '' + (17 - 3 * i);
|
||||
sections += `
|
||||
.section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${
|
||||
i - 1
|
||||
} path {
|
||||
fill: ${options['git' + i]};
|
||||
fill: ${options['cScale' + i]};
|
||||
}
|
||||
.section-${i - 1} text {
|
||||
fill: ${options['gitBranchLabel' + i]};
|
||||
fill: ${options['cScaleLabel' + i]};
|
||||
// fill: ${options['gitInv' + i]};
|
||||
}
|
||||
.node-icon-${i - 1} {
|
||||
font-size: 40px;
|
||||
color: ${options['gitBranchLabel' + i]};
|
||||
color: ${options['cScaleLabel' + i]};
|
||||
// color: ${options['gitInv' + i]};
|
||||
}
|
||||
.section-edge-${i - 1}{
|
||||
stroke: ${options['git' + i]};
|
||||
stroke: ${options['cScale' + i]};
|
||||
}
|
||||
.edge-depth-${i - 1}{
|
||||
stroke-width: ${sw};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { select } from 'd3';
|
||||
import * as db from './mindmapDb';
|
||||
const MAX_SECTIONS = 12;
|
||||
|
||||
/**
|
||||
* @param {string} text The text to be wrapped
|
||||
@@ -159,16 +160,19 @@ const roundedRectBkg = function (elem, node) {
|
||||
* @param {object} elem The D3 dom element in which the node is to be added
|
||||
* @param {object} node The node to be added
|
||||
* @param section
|
||||
* @param fullSection
|
||||
* @param {object} conf The configuration object
|
||||
* @returns {number} The height nodes dom element
|
||||
*/
|
||||
export const drawNode = function (elem, node, section, conf) {
|
||||
export const drawNode = function (elem, node, fullSection, conf) {
|
||||
const section = (fullSection % MAX_SECTIONS) - 1;
|
||||
const nodeElem = elem.append('g');
|
||||
node.section = section;
|
||||
nodeElem.attr(
|
||||
'class',
|
||||
(node.class ? node.class + ' ' : '') +
|
||||
'mindmap-node ' +
|
||||
(section === -1 ? 'section-root' : 'section-' + section)
|
||||
(section < 0 ? 'section-root' : 'section-' + section)
|
||||
);
|
||||
const bkgElem = nodeElem.append('g');
|
||||
|
||||
@@ -252,14 +256,15 @@ export const drawNode = function (elem, node, section, conf) {
|
||||
}
|
||||
|
||||
// Position the node to its coordinate
|
||||
if (typeof node.x !== 'undefined' && typeof node.y !== 'undefined') {
|
||||
nodeElem.attr('transform', 'translate(' + node.x + ',' + node.y + ')');
|
||||
}
|
||||
// if (typeof node.x !== 'undefined' && typeof node.y !== 'undefined') {
|
||||
// nodeElem.attr('transform', 'translate(' + node.x + ',' + node.y + ')');
|
||||
// }
|
||||
db.setElementForId(node.id, nodeElem);
|
||||
return node.height;
|
||||
};
|
||||
|
||||
export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, section) {
|
||||
export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, fullSection) {
|
||||
const section = (fullSection % MAX_SECTIONS) - 1;
|
||||
const sx = parent.x + parent.width / 2;
|
||||
const sy = parent.y + parent.height / 2;
|
||||
const ex = mindmap.x + mindmap.width / 2;
|
||||
|
||||
@@ -19,7 +19,13 @@ export const labelHelper = (parent, node, _classes, isNode) => {
|
||||
// Create the label and insert it after the rect
|
||||
const label = shapeSvg.insert('g').attr('class', 'label').attr('style', node.labelStyle);
|
||||
|
||||
const labelText = typeof node.labelText === 'string' ? node.labelText : node.labelText[0];
|
||||
// Replace labelText with default value if undefined
|
||||
let labelText;
|
||||
if (typeof node.labelText === 'undefined') {
|
||||
labelText = '';
|
||||
} else {
|
||||
labelText = typeof node.labelText === 'string' ? node.labelText : node.labelText[0];
|
||||
}
|
||||
|
||||
const text = label
|
||||
.node()
|
||||
|
||||
@@ -308,9 +308,9 @@ const render = async function (
|
||||
svg.insertBefore(style1, firstChild);
|
||||
|
||||
try {
|
||||
diag.renderer.draw(text, id, pkg.version, diag);
|
||||
await diag.renderer.draw(text, id, pkg.version, diag);
|
||||
} catch (e) {
|
||||
errorRenderer.draw(text, id, pkg.version);
|
||||
await errorRenderer.draw(text, id, pkg.version);
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ class Theme {
|
||||
this.noteBkgColor = '#fff5ad';
|
||||
this.noteTextColor = '#333';
|
||||
|
||||
this.THEME_COLOR_LIMIT = 12;
|
||||
|
||||
// dark
|
||||
|
||||
this.fontFamily = '"trebuchet ms", verdana, arial, sans-serif';
|
||||
@@ -123,6 +125,50 @@ class Theme {
|
||||
this.transitionColor = this.transitionColor || this.lineColor;
|
||||
this.specialStateColor = this.lineColor;
|
||||
|
||||
/* Color Scale */
|
||||
/* Each color-set will have a background, a forgroupnd and a border color */
|
||||
this.cScale0 = this.cScale0 || this.primaryColor;
|
||||
this.cScale1 = this.cScale1 || this.secondaryColor;
|
||||
this.cScale2 = this.cScale2 || this.tertiaryColor;
|
||||
this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 });
|
||||
this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 });
|
||||
this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 });
|
||||
this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 });
|
||||
this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 });
|
||||
this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210, l: 150 });
|
||||
this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 });
|
||||
this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 });
|
||||
this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 });
|
||||
if (this.darkMode) {
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScale' + i] = darken(this['cScale' + i], 75);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScale' + i] = darken(this['cScale' + i], 25);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the inverted color for the set
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleInv' + i] = this['cScaleInv' + i] || invert(this['cScale' + i]);
|
||||
}
|
||||
// Setup the peer color for the set, useful for borders
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
if (this.darkMode) {
|
||||
this['cScalePeer' + i] = this['cScalePeer' + i] || lighten(this['cScale' + i], 10);
|
||||
} else {
|
||||
this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup teh label color for the set
|
||||
this.scaleLabelColor = this.scaleLabelColor || this.labelTextColor;
|
||||
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor;
|
||||
}
|
||||
|
||||
/* class */
|
||||
this.classText = this.classText || this.textColor;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ class Theme {
|
||||
this.fontSize = '16px';
|
||||
this.labelBackground = '#181818';
|
||||
this.textColor = '#ccc';
|
||||
this.THEME_COLOR_LIMIT = 12;
|
||||
|
||||
/* Flowchart variables */
|
||||
this.nodeBkg = 'calculated';
|
||||
@@ -157,19 +158,55 @@ class Theme {
|
||||
this.fillType6 = adjust(this.primaryColor, { h: 128 });
|
||||
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
|
||||
|
||||
/* pie */
|
||||
this.pie1 = this.pie1 || '#0b0000';
|
||||
this.pie2 = this.pie2 || '#4d1037';
|
||||
this.pie3 = this.pie3 || '#3f5258';
|
||||
this.pie4 = this.pie4 || '#4f2f1b';
|
||||
this.pie5 = this.pie5 || '#6e0a0a';
|
||||
this.pie6 = this.pie6 || '#3b0048';
|
||||
this.pie7 = this.pie7 || '#995a01';
|
||||
this.pie8 = this.pie8 || '#154706';
|
||||
this.pie9 = this.pie9 || '#161722';
|
||||
this.pie10 = this.pie10 || '#00296f';
|
||||
this.pie11 = this.pie11 || '#01629c';
|
||||
this.pie12 = this.pie12 || '#010029';
|
||||
/* cScale */
|
||||
this.cScale1 = this.cScale1 || '#0b0000';
|
||||
this.cScale2 = this.cScale2 || '#4d1037';
|
||||
this.cScale3 = this.cScale3 || '#3f5258';
|
||||
this.cScale4 = this.cScale4 || '#4f2f1b';
|
||||
this.cScale5 = this.cScale5 || '#6e0a0a';
|
||||
this.cScale6 = this.cScale6 || '#3b0048';
|
||||
this.cScale7 = this.cScale7 || '#995a01';
|
||||
this.cScale8 = this.cScale8 || '#154706';
|
||||
this.cScale9 = this.cScale9 || '#161722';
|
||||
this.cScale10 = this.cScale10 || '#00296f';
|
||||
this.cScale11 = this.cScale11 || '#01629c';
|
||||
this.cScale12 = this.cScale12 || '#010029';
|
||||
|
||||
/* Color Scale */
|
||||
/* Each color-set will have a background, a forgroupnd and a border color */
|
||||
this.cScale0 = this.cScale0 || this.primaryColor;
|
||||
this.cScale1 = this.cScale1 || this.secondaryColor;
|
||||
this.cScale2 = this.cScale2 || this.tertiaryColor;
|
||||
this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 });
|
||||
this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 });
|
||||
this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 });
|
||||
this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 });
|
||||
this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 });
|
||||
this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210 });
|
||||
this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 });
|
||||
this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 });
|
||||
this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 });
|
||||
|
||||
// Setup the inverted color for the set
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleInv' + i] = this['cScaleInv' + i] || invert(this['cScale' + i]);
|
||||
}
|
||||
// Setup the peer color for the set, useful for borders
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScalePeer' + i] = this['cScalePeer' + i] || lighten(this['cScale' + i], 10);
|
||||
}
|
||||
|
||||
// Setup teh label color for the set
|
||||
this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor);
|
||||
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor;
|
||||
}
|
||||
|
||||
/* Pie diagram */
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['pie' + i] = this['cScale' + i];
|
||||
}
|
||||
this.pieTitleTextSize = this.pieTitleTextSize || '25px';
|
||||
this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor;
|
||||
this.pieSectionTextSize = this.pieSectionTextSize || '17px';
|
||||
|
||||
@@ -36,6 +36,7 @@ class Theme {
|
||||
this.fontSize = '16px';
|
||||
this.labelBackground = '#e8e8e8';
|
||||
this.textColor = '#333';
|
||||
this.THEME_COLOR_LIMIT = 12;
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
@@ -119,8 +120,41 @@ class Theme {
|
||||
this.updateColors();
|
||||
}
|
||||
updateColors() {
|
||||
/* Flowchart variables */
|
||||
/* Color Scale */
|
||||
/* Each color-set will have a background, a forgroupnd and a border color */
|
||||
this.cScale0 = this.cScale0 || this.primaryColor;
|
||||
this.cScale1 = this.cScale1 || this.secondaryColor;
|
||||
this.cScale2 = this.cScale2 || this.tertiaryColor;
|
||||
this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 });
|
||||
this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 });
|
||||
this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 });
|
||||
this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 });
|
||||
this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 });
|
||||
this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210 });
|
||||
this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 });
|
||||
this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 });
|
||||
this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 });
|
||||
this['cScalePeer' + 1] = this['cScalePeer' + 1] || darken(this.secondaryColor, 45);
|
||||
this['cScalePeer' + 2] = this['cScalePeer' + 2] || darken(this.tertiaryColor, 40);
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
// Setup the peer color for the set, useful for borders
|
||||
this['cScale' + i] = darken(this['cScale' + i], 10);
|
||||
this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 25);
|
||||
}
|
||||
|
||||
// Setup the inverted color for the set
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleInv' + i] = this['cScaleInv' + i] || adjust(this['cScale' + i], { h: 180 });
|
||||
}
|
||||
|
||||
// Setup teh label color for the set
|
||||
this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor);
|
||||
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor;
|
||||
}
|
||||
|
||||
/* Flowchart variables */
|
||||
this.nodeBkg = this.mainBkg;
|
||||
this.nodeBorder = this.border1; // border 1
|
||||
this.clusterBkg = this.secondBkg;
|
||||
|
||||
@@ -30,6 +30,7 @@ class Theme {
|
||||
this.tertiaryTextColor = invert(this.primaryColor);
|
||||
this.lineColor = invert(this.background);
|
||||
this.textColor = invert(this.background);
|
||||
this.THEME_COLOR_LIMIT = 12;
|
||||
|
||||
/* Flowchart variables */
|
||||
this.nodeBkg = 'calculated';
|
||||
@@ -93,6 +94,39 @@ class Theme {
|
||||
this.errorTextColor = '#552222';
|
||||
}
|
||||
updateColors() {
|
||||
/* Each color-set will have a background, a forgroupnd and a border color */
|
||||
this.cScale0 = this.cScale0 || this.primaryColor;
|
||||
this.cScale1 = this.cScale1 || this.secondaryColor;
|
||||
this.cScale2 = this.cScale2 || this.tertiaryColor;
|
||||
this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 });
|
||||
this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 });
|
||||
this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 });
|
||||
this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 });
|
||||
this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 });
|
||||
this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210 });
|
||||
this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 });
|
||||
this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 });
|
||||
this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 });
|
||||
this['cScalePeer' + 1] = this['cScalePeer' + 1] || darken(this.secondaryColor, 45);
|
||||
this['cScalePeer' + 2] = this['cScalePeer' + 2] || darken(this.tertiaryColor, 40);
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
// Setup the peer color for the set, useful for borders
|
||||
this['cScale' + i] = darken(this['cScale' + i], 10);
|
||||
this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 25);
|
||||
}
|
||||
|
||||
// Setup the inverted color for the set
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleInv' + i] = this['cScaleInv' + i] || adjust(this['cScale' + i], { h: 180 });
|
||||
}
|
||||
|
||||
// Setup teh label color for the set
|
||||
this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor);
|
||||
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor;
|
||||
}
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = this.mainBkg;
|
||||
|
||||
@@ -41,6 +41,7 @@ class Theme {
|
||||
this.arrowheadColor = '#333333';
|
||||
this.fontFamily = '"trebuchet ms", verdana, arial, sans-serif';
|
||||
this.fontSize = '16px';
|
||||
this.THEME_COLOR_LIMIT = 12;
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
@@ -108,6 +109,44 @@ class Theme {
|
||||
this.secondBkg = lighten(this.contrast, 55);
|
||||
this.border2 = this.contrast;
|
||||
|
||||
/* Color Scale */
|
||||
/* Each color-set will have a background, a forgroupnd and a border color */
|
||||
|
||||
this.cScale0 = this.cScale0 || '#555';
|
||||
this.cScale1 = this.cScale1 || '#F4F4F4';
|
||||
this.cScale2 = this.cScale2 || '#555';
|
||||
this.cScale3 = this.cScale3 || '#BBB';
|
||||
this.cScale4 = this.cScale4 || '#777';
|
||||
this.cScale5 = this.cScale5 || '#999';
|
||||
this.cScale6 = this.cScale6 || '#DDD';
|
||||
this.cScale7 = this.cScale7 || '#FFF';
|
||||
this.cScale8 = this.cScale8 || '#DDD';
|
||||
this.cScale9 = this.cScale9 || '#BBB';
|
||||
this.cScale10 = this.cScale10 || '#999';
|
||||
this.cScale11 = this.cScale11 || '#777';
|
||||
|
||||
// Setup the inverted color for the set
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleInv' + i] = this['cScaleInv' + i] || invert(this['cScale' + i]);
|
||||
}
|
||||
// Setup the peer color for the set, useful for borders
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
if (this.darkMode) {
|
||||
this['cScalePeer' + i] = this['cScalePeer' + i] || lighten(this['cScale' + i], 10);
|
||||
} else {
|
||||
this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the label color for the set
|
||||
this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor);
|
||||
|
||||
this['cScaleLabel0'] = this['cScaleLabel0'] || this.cScale1;
|
||||
this['cScaleLabel2'] = this['cScaleLabel2'] || this.cScale1;
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor;
|
||||
}
|
||||
|
||||
/* Flowchart variables */
|
||||
|
||||
this.nodeBkg = this.mainBkg;
|
||||
@@ -185,18 +224,11 @@ class Theme {
|
||||
this.fillType7 = adjust(this.secondaryColor, { h: 128 });
|
||||
|
||||
// /* pie */
|
||||
this.pie1 = this.pie1 || '#F4F4F4';
|
||||
this.pie2 = this.pie2 || '#555';
|
||||
this.pie3 = this.pie3 || '#BBB';
|
||||
this.pie4 = this.pie4 || '#777';
|
||||
this.pie5 = this.pie5 || '#999';
|
||||
this.pie6 = this.pie6 || '#DDD';
|
||||
this.pie7 = this.pie7 || '#FFF';
|
||||
this.pie8 = this.pie8 || '#DDD';
|
||||
this.pie9 = this.pie9 || '#BBB';
|
||||
this.pie10 = this.pie10 || '#999';
|
||||
this.pie11 = this.pie11 || '#777';
|
||||
this.pie12 = this.pie12 || '#555';
|
||||
/* Pie diagram */
|
||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||
this['pie' + i] = this['cScale' + i];
|
||||
}
|
||||
this.pie12 = this.pie0;
|
||||
this.pieTitleTextSize = this.pieTitleTextSize || '25px';
|
||||
this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor;
|
||||
this.pieSectionTextSize = this.pieSectionTextSize || '17px';
|
||||
@@ -207,19 +239,6 @@ class Theme {
|
||||
this.pieStrokeWidth = this.pieStrokeWidth || '2px';
|
||||
this.pieOpacity = this.pieOpacity || '0.7';
|
||||
|
||||
// this.pie1 = this.pie1 || '#212529';
|
||||
// this.pie2 = this.pie2 || '#343A40';
|
||||
// this.pie3 = this.pie3 || '#495057';
|
||||
// this.pie4 = this.pie4 || '#6C757D';
|
||||
// this.pie5 = this.pie5 || adjust(this.secondaryColor, { l: -10 });
|
||||
// this.pie6 = this.pie6 || adjust(this.tertiaryColor, { l: -10 });
|
||||
// this.pie7 = this.pie7 || adjust(this.primaryColor, { h: +60, l: -10 });
|
||||
// this.pie8 = this.pie8 || adjust(this.primaryColor, { h: -60, l: -10 });
|
||||
// this.pie9 = this.pie9 || adjust(this.primaryColor, { h: 120, l: 0 });
|
||||
// this.pie10 = this.pie10 || adjust(this.primaryColor, { h: +60, l: -20 });
|
||||
// this.pie11 = this.pie11 || adjust(this.primaryColor, { h: -60, l: -20 });
|
||||
// this.pie12 = this.pie12 || adjust(this.primaryColor, { h: 120, l: -10 });
|
||||
|
||||
/* requirement-diagram */
|
||||
this.requirementBackground = this.requirementBackground || this.primaryColor;
|
||||
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
|
||||
|
||||
Reference in New Issue
Block a user