diff --git a/src/config.js b/src/config.js index 263c46c8f..f762f00ad 100644 --- a/src/config.js +++ b/src/config.js @@ -6,7 +6,7 @@ import { logger } from './logger'; const themes = {}; -for (const themeName of ['default', 'forest', 'dark', 'neutral']) { +for (const themeName of ['default', 'forest', 'dark', 'neutral', 'base']) { themes[themeName] = require(`./themes/theme-${themeName}.js`); } /** diff --git a/src/diagrams/class/styles.js b/src/diagrams/class/styles.js index 5a272e7a9..345784221 100644 --- a/src/diagrams/class/styles.js +++ b/src/diagrams/class/styles.js @@ -1,9 +1,9 @@ const getStyles = options => `g.classGroup text { fill: ${options.nodeBorder}; + fill: ${options.classText}; stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-family: var(--mermaid-font-family); + font-family: ${options.fontFamily}; font-size: 10px; .title { diff --git a/src/diagrams/er/styles.js b/src/diagrams/er/styles.js index 3e5083a0b..2dec402f1 100644 --- a/src/diagrams/er/styles.js +++ b/src/diagrams/er/styles.js @@ -1,5 +1,18 @@ -const getStyles = () => +Base theme for cusom themeingconst getStyles = options => ` + .entityBox { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + } + + .relationshipLabelBox { + fill: ${options.edgeLabelBackground}; + fillopactity: 0; + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.5; + } + } `; export default getStyles; diff --git a/src/diagrams/user-journey/journeyRenderer.js b/src/diagrams/user-journey/journeyRenderer.js index f1c42e544..7ec69a228 100644 --- a/src/diagrams/user-journey/journeyRenderer.js +++ b/src/diagrams/user-journey/journeyRenderer.js @@ -232,12 +232,14 @@ export const drawTasks = function(diagram, tasks, verticalPos) { let sectionNumber = 0; let fill = '#CCC'; let colour = 'black'; + let num = 0; // Draw the tasks for (let i = 0; i < tasks.length; i++) { let task = tasks[i]; if (lastSection !== task.section) { fill = fills[sectionNumber % fills.length]; + num = sectionNumber % fills.length; colour = textColours[sectionNumber % textColours.length]; const section = { @@ -245,6 +247,7 @@ export const drawTasks = function(diagram, tasks, verticalPos) { y: 50, text: task.section, fill, + num, colour }; @@ -269,6 +272,7 @@ export const drawTasks = function(diagram, tasks, verticalPos) { task.height = conf.diagramMarginY; task.colour = colour; task.fill = fill; + task.num = num; task.actors = taskActors; // Draw the box with the attached line diff --git a/src/diagrams/user-journey/styles.js b/src/diagrams/user-journey/styles.js index c736b4d5f..8c90bad29 100644 --- a/src/diagrams/user-journey/styles.js +++ b/src/diagrams/user-journey/styles.js @@ -88,6 +88,31 @@ const getStyles = options => pointer-events: none; z-index: 100; } + + .task-type-0, .section-type-0 { + ${options.fillType0 ? `fill: ${options.fillType0}` : ''}; + } + .task-type-1, .section-type-1 { + ${options.fillType0 ? `fill: ${options.fillType1}` : ''}; + } + .task-type-2, .section-type-2 { + ${options.fillType0 ? `fill: ${options.fillType2}` : ''}; + } + .task-type-3, .section-type-3 { + ${options.fillType0 ? `fill: ${options.fillType3}` : ''}; + } + .task-type-4, .section-type-4 { + ${options.fillType0 ? `fill: ${options.fillType4}` : ''}; + } + .task-type-5, .section-type-5 { + ${options.fillType0 ? `fill: ${options.fillType5}` : ''}; + } + .task-type-6, .section-type-6 { + ${options.fillType0 ? `fill: ${options.fillType6}` : ''}; + } + .task-type-7, .section-type-7 { + ${options.fillType0 ? `fill: ${options.fillType7}` : ''}; + } `; export default getStyles; diff --git a/src/diagrams/user-journey/svgDraw.js b/src/diagrams/user-journey/svgDraw.js index 7b84262f3..02f63dbde 100644 --- a/src/diagrams/user-journey/svgDraw.js +++ b/src/diagrams/user-journey/svgDraw.js @@ -187,7 +187,7 @@ export const drawSection = function(elem, section, conf) { rect.fill = section.fill; rect.width = conf.width; rect.height = conf.height; - rect.class = 'journey-section'; + rect.class = 'journey-section section-type-' + section.num; rect.rx = 3; rect.ry = 3; drawRect(g, rect); @@ -199,7 +199,7 @@ export const drawSection = function(elem, section, conf) { rect.y, rect.width, rect.height, - { class: 'journey-section' }, + { class: 'journey-section section-type-' + section.num }, conf, section.colour ); @@ -240,7 +240,7 @@ export const drawTask = function(elem, task, conf) { rect.fill = task.fill; rect.width = conf.width; rect.height = conf.height; - rect.class = 'task'; + rect.class = 'task task-type-' + task.num; rect.rx = 3; rect.ry = 3; drawRect(g, rect); diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js index 170d09259..f2eb9d2f1 100644 --- a/src/mermaidAPI.js +++ b/src/mermaidAPI.js @@ -53,7 +53,7 @@ import configApi from './config'; import getStyles from './styles'; const themes = {}; -for (const themeName of ['default', 'forest', 'dark', 'neutral']) { +for (const themeName of ['default', 'forest', 'dark', 'neutral', 'base']) { themes[themeName] = require(`./themes/theme-${themeName}.js`); } diff --git a/src/styles.js b/src/styles.js index 19790b243..810760bdb 100644 --- a/src/styles.js +++ b/src/styles.js @@ -1,5 +1,5 @@ import classDiagram from './diagrams/class/styles'; -import er from './diagrams/flowchart/styles'; +import er from './diagrams/er/styles'; import flowchart from './diagrams/flowchart/styles'; import gantt from './diagrams/gantt/styles'; import git from './diagrams/git/styles'; @@ -75,6 +75,8 @@ const getStyles = (type, userStyles, options) => { ${themes[type](options)} ${userStyles} + + ${type} { fill: apa;} `; }; diff --git a/src/themes/theme-base.js b/src/themes/theme-base.js new file mode 100644 index 000000000..df5cbc920 --- /dev/null +++ b/src/themes/theme-base.js @@ -0,0 +1,127 @@ +import { darken, lighten, rgba, adjust } from 'khroma'; + +class Theme { + constructor() { + /* Base variables */ + this.primaryColor = '#fa255e'; + this.secondaryColor = '#c39ea0'; + this.tertiaryColor = '#f8e5e5'; + this.background = 'white'; + this.lineColor = '#333333'; + this.border1 = '#9370DB'; + this.arrowheadColor = '#333333'; + this.fontFamily = '"trebuchet ms", verdana, arial'; + this.fontSize = '16px'; + this.labelBackground = '#e8e8e8'; + this.textColor = '#333'; + this.noteBkgColor = '#fff5ad'; + this.noteBorderColor = '#aaaa33'; + this.updateColors(); + } + updateColors() { + this.secondBkg = this.tertiaryColor; + + /* Flowchart variables */ + + this.nodeBkg = this.primaryColor; + this.mainBkg = this.primaryColor; + this.nodeBorder = darken(this.primaryColor, 23); // border 1 + this.clusterBkg = this.tertiaryColor; + this.clusterBorder = darken(this.tertiaryColor, 10); + this.defaultLinkColor = this.lineColor; + this.titleColor = this.textColor; + this.edgeLabelBackground = this.labelBackground; + + /* Sequence Diagram variables */ + + // this.actorBorder = lighten(this.border1, 0.5); + this.actorBorder = lighten(this.border1, 23); + this.actorBkg = this.mainBkg; + this.actorTextColor = 'black'; + this.actorLineColor = 'grey'; + this.labelBoxBkgColor = this.actorBkg; + this.signalColor = this.textColor; + this.signalTextColor = this.textColor; + this.labelBoxBorderColor = this.actorBorder; + this.labelTextColor = this.actorTextColor; + this.loopTextColor = this.actorTextColor; + this.noteBorderColor = this.border2; + this.noteTextColor = this.actorTextColor; + this.activationBorderColor = darken(this.secondaryColor, 10); + this.activationBkgColor = this.secondaryColor; + this.sequenceNumberColor = 'white'; + + /* Gantt chart variables */ + + this.taskTextColor = this.taskTextLightColor; + this.taskTextOutsideColor = this.taskTextDarkColor; + this.sectionBkgColor = rgba(102, 102, 255, 0.49); + this.altSectionBkgColor = 'white'; + this.sectionBkgColor2 = '#fff400'; + this.sectionBkgColor = rgba(102, 102, 255, 0.49); + this.altSectionBkgColor = 'white'; + this.sectionBkgColor2 = '#fff400'; + this.taskBorderColor = '#534fbc'; + this.taskBkgColor = '#8a90dd'; + this.taskTextLightColor = 'white'; + this.taskTextColor = 'calculated'; + this.taskTextDarkColor = 'black'; + this.taskTextOutsideColor = 'calculated'; + this.taskTextClickableColor = '#003163'; + this.activeTaskBorderColor = '#534fbc'; + this.activeTaskBkgColor = '#bfc7ff'; + this.gridColor = 'lightgrey'; + this.doneTaskBkgColor = 'lightgrey'; + this.doneTaskBorderColor = 'grey'; + this.critBorderColor = '#ff8888'; + this.critBkgColor = 'red'; + this.todayLineColor = 'red'; + + /* state colors */ + this.labelColor = 'black'; + this.errorBkgColor = '#552222'; + this.errorTextColor = '#552222'; + + /* state colors */ + + /* class */ + this.classText = this.textColor; + + /* user-journey */ + this.fillType0 = this.primaryColor; + this.fillType1 = this.secondaryColor; + this.fillType2 = adjust(this.primaryColor, { h: 64 }); + this.fillType3 = adjust(this.secondaryColor, { h: 64 }); + this.fillType4 = adjust(this.primaryColor, { h: -64 }); + this.fillType5 = adjust(this.secondaryColor, { h: -64 }); + this.fillType6 = adjust(this.primaryColor, { h: 128 }); + this.fillType7 = adjust(this.secondaryColor, { h: 128 }); + } + calculate(overrides) { + if (typeof overrides !== 'object') { + // Calculate colors form base colors + this.updateColors(); + return; + } + + const keys = Object.keys(overrides); + + // Copy values from overrides, this is mainly for base colors + keys.forEach(k => { + this[k] = overrides[k]; + }); + + // Calculate colors form base colors + this.updateColors(); + // Copy values from overrides again in case of an override of derived value + keys.forEach(k => { + this[k] = overrides[k]; + }); + } +} + +export const getThemeVariables = userOverrides => { + const theme = new Theme(); + theme.calculate(userOverrides); + return theme; +}; diff --git a/src/themes/theme-dark.js b/src/themes/theme-dark.js index 643a9e565..9101abad1 100644 --- a/src/themes/theme-dark.js +++ b/src/themes/theme-dark.js @@ -114,6 +114,8 @@ class Theme { /* state colors */ this.labelColor = this.textColor; + /* class */ + this.classText = this.nodeBorder; } calculate(overrides) { if (typeof overrides !== 'object') { diff --git a/src/themes/theme-default.js b/src/themes/theme-default.js index 2da7ca9ce..f239b93ab 100644 --- a/src/themes/theme-default.js +++ b/src/themes/theme-default.js @@ -121,6 +121,8 @@ class Theme { this.taskTextOutsideColor = this.taskTextDarkColor; /* state colors */ + /* class */ + this.classText = this.nodeBorder; } calculate(overrides) { if (typeof overrides !== 'object') { diff --git a/src/themes/theme-forest.js b/src/themes/theme-forest.js index 3d15ed740..616b73411 100644 --- a/src/themes/theme-forest.js +++ b/src/themes/theme-forest.js @@ -96,6 +96,8 @@ class Theme { this.activeTaskBkgColor = this.mainBkg; /* state colors */ + /* class */ + this.classText = this.nodeBorder; } calculate(overrides) { if (typeof overrides !== 'object') { diff --git a/src/themes/theme-neutral.js b/src/themes/theme-neutral.js index 540089b9e..4dbe6db03 100644 --- a/src/themes/theme-neutral.js +++ b/src/themes/theme-neutral.js @@ -1,6 +1,4 @@ -import Color from 'color'; -import { lighten } from 'khroma'; -window.lighten = lighten; +import { darken, lighten } from 'khroma'; // const Color = require ( 'khroma/dist/color' ).default // Color.format.hex.stringify(Color.parse('hsl(210, 66.6666666667%, 95%)')); // => "#EAF2FB" @@ -103,29 +101,16 @@ class Theme { this.labelBoxBorderColor = this.actorBorder; this.labelTextColor = this.text; this.loopTextColor = this.text; - this.noteBorderColor = Color(this.note) - .darken(0.6) - .hsl() - .string(); + this.noteBorderColor = darken(this.note, 60); this.noteBkgColor = this.note; this.noteTextColor = this.actorTextColor; /* Gantt chart variables */ - this.sectionBkgColor = Color(this.contrast) - .lighten(0.3) - .hsl() - .string(); + this.sectionBkgColor = lighten(this.contrast, 30); + this.sectionBkgColor2 = lighten(this.contrast, 30); - this.sectionBkgColor2 = Color(this.contrast) - .lighten(0.3) - .hsl() - .string(); - - this.taskBorderColor = Color(this.contrast) - .darken(0.1) - .hsl() - .string(); + this.taskBorderColor = darken(this.contrast, 10); this.taskBkgColor = this.contrast; this.taskTextColor = this.taskTextLightColor; @@ -133,22 +118,18 @@ class Theme { this.taskTextOutsideColor = this.taskTextDarkColor; this.activeTaskBorderColor = this.taskBorderColor; this.activeTaskBkgColor = this.mainBkg; - this.gridColor = Color(this.border1) - .lighten(0.3) - .hsl() - .string(); + this.gridColor = lighten(this.border1, 30); this.doneTaskBkgColor = this.done; this.doneTaskBorderColor = this.lineColor; this.critBkgColor = this.critical; - this.critBorderColor = Color(this.critBkgColor) - .darken(0.1) - .hsl() - .string(); + this.critBorderColor = darken(this.critBkgColor, 10); this.todayLineColor = this.critBkgColor; /* state colors */ + /* class */ + this.classText = this.nodeBorder; } calculate(overrides) { if (typeof overrides !== 'object') {