mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-10 09:39:38 +02:00
Improve plot color selection
This commit is contained in:
@@ -40,7 +40,11 @@
|
||||
<h1>XY Charts demos</h1>
|
||||
<pre class="mermaid">
|
||||
xychart-beta
|
||||
line [23, 46, 75, 43]
|
||||
line [23, 46, 77, 34]
|
||||
line [45, 32, 33, 12]
|
||||
line [87, 54, 99, 85]
|
||||
line [78, 88, 22, 4]
|
||||
line [22, 29, 75, 33]
|
||||
bar "sample bat" [52, 96, 35, 10]
|
||||
</pre>
|
||||
|
||||
|
@@ -13,8 +13,7 @@ export interface XYChartThemeConfig {
|
||||
xychartYAxisLableColor: string;
|
||||
xychartYAxisTitleColor: string;
|
||||
xychartYAxisTickColor: string;
|
||||
xychartBarPlotPalette: string[];
|
||||
xychartLinePlotPalette: string[];
|
||||
xychartPlotBaseColor: string;
|
||||
}
|
||||
|
||||
export interface ChartComponent {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { XYChartConfig } from '../../../../../config.type.js';
|
||||
import { BarPlotData, BoundingRect, DrawableElem, XYChartThemeConfig } from '../../Interfaces.js';
|
||||
import { BarPlotData, BoundingRect, DrawableElem } from '../../Interfaces.js';
|
||||
import { IAxis } from '../axis/index.js';
|
||||
|
||||
export class BarPlot {
|
||||
@@ -9,7 +9,7 @@ export class BarPlot {
|
||||
private xAxis: IAxis,
|
||||
private yAxis: IAxis,
|
||||
private orientation: XYChartConfig['chartOrientation'],
|
||||
private chartThemeConfig: XYChartThemeConfig
|
||||
private plotIndex: number
|
||||
) {}
|
||||
|
||||
getDrawableElement(): DrawableElem[] {
|
||||
@@ -28,7 +28,7 @@ export class BarPlot {
|
||||
if (this.orientation === 'horizontal') {
|
||||
return [
|
||||
{
|
||||
groupTexts: ['plot', 'bar-plot'],
|
||||
groupTexts: ['plot', `bar-plot-${this.plotIndex}`],
|
||||
type: 'rect',
|
||||
data: finalData.map((data) => ({
|
||||
x: this.boundingRect.x,
|
||||
@@ -44,7 +44,7 @@ export class BarPlot {
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
groupTexts: ['plot', 'bar-plot'],
|
||||
groupTexts: ['plot', `bar-plot-${this.plotIndex}`],
|
||||
type: 'rect',
|
||||
data: finalData.map((data) => ({
|
||||
x: data[0] - barWidthHalf,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { line } from 'd3';
|
||||
import { DrawableElem, LinePlotData, XYChartThemeConfig } from '../../Interfaces.js';
|
||||
import { IAxis } from '../axis/index.js';
|
||||
import { XYChartConfig } from '../../../../../config.type.js';
|
||||
import { DrawableElem, LinePlotData } from '../../Interfaces.js';
|
||||
import { IAxis } from '../axis/index.js';
|
||||
|
||||
export class LinePlot {
|
||||
constructor(
|
||||
@@ -9,7 +9,7 @@ export class LinePlot {
|
||||
private xAxis: IAxis,
|
||||
private yAxis: IAxis,
|
||||
private orientation: XYChartConfig['chartOrientation'],
|
||||
private chartThemeConfig: XYChartThemeConfig
|
||||
private plotIndex: number
|
||||
) {}
|
||||
|
||||
getDrawableElement(): DrawableElem[] {
|
||||
@@ -33,7 +33,7 @@ export class LinePlot {
|
||||
}
|
||||
return [
|
||||
{
|
||||
groupTexts: ['plot', 'line-plot'],
|
||||
groupTexts: ['plot', `line-plot-${this.plotIndex}`],
|
||||
type: 'path',
|
||||
data: [
|
||||
{
|
||||
|
@@ -62,7 +62,7 @@ export class Plot implements IPlot {
|
||||
this.chartThemeConfig
|
||||
).getDrawableElement(),
|
||||
];
|
||||
for (const plot of this.chartData.plots) {
|
||||
for (const [i, plot] of this.chartData.plots.entries()) {
|
||||
switch (plot.type) {
|
||||
case 'line':
|
||||
{
|
||||
@@ -71,7 +71,7 @@ export class Plot implements IPlot {
|
||||
this.xAxis,
|
||||
this.yAxis,
|
||||
this.chartConfig.chartOrientation,
|
||||
this.chartThemeConfig
|
||||
i
|
||||
);
|
||||
drawableElem.push(...linePlot.getDrawableElement());
|
||||
}
|
||||
@@ -84,7 +84,7 @@ export class Plot implements IPlot {
|
||||
this.xAxis,
|
||||
this.yAxis,
|
||||
this.chartConfig.chartOrientation,
|
||||
this.chartThemeConfig
|
||||
i
|
||||
);
|
||||
drawableElem.push(...barPlot.getDrawableElement());
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { log } from '../../logger.js';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import { adjust, channel, toHsla, isDark, lighten, darken } from 'khroma';
|
||||
import mermaidAPI from '../../mermaidAPI.js';
|
||||
import * as configApi from '../../config.js';
|
||||
import { sanitizeText } from '../common/common.js';
|
||||
@@ -27,6 +28,24 @@ const defaultThemeVariables = getThemeVariables();
|
||||
|
||||
const config = configApi.getConfig();
|
||||
|
||||
function plotColorPaletteGenerator(baseColor: string, noOfColorNeeded = 15): string[] {
|
||||
const colors = [];
|
||||
const MAX_HUE_VALUE = 360;
|
||||
const baseHue = channel(baseColor, 'h');
|
||||
if (baseHue > MAX_HUE_VALUE / 2) {
|
||||
const decr = Math.floor(baseHue / noOfColorNeeded);
|
||||
for (let i = 0; i <= baseHue; i += decr) {
|
||||
colors.push(adjust(baseColor, { h: -i }));
|
||||
}
|
||||
} else {
|
||||
const incr = Math.floor((MAX_HUE_VALUE - baseHue) / noOfColorNeeded);
|
||||
for (let i = 0; i <= baseHue; i += incr) {
|
||||
colors.push(adjust(baseColor, { h: i }));
|
||||
}
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
function getChartDefaultThemeConfig(): XYChartThemeConfig {
|
||||
return {
|
||||
xychartTitleColor:
|
||||
@@ -45,10 +64,8 @@ function getChartDefaultThemeConfig(): XYChartThemeConfig {
|
||||
config.themeVariables?.xychartYAxisTitleColor || defaultThemeVariables.xychartYAxisTitleColor,
|
||||
xychartYAxisTickColor:
|
||||
config.themeVariables?.xychartYAxisTickColor || defaultThemeVariables.xychartYAxisTickColor,
|
||||
xychartBarPlotPalette:
|
||||
config.themeVariables?.xychartBarPlotPalette || defaultThemeVariables.xychartBarPlotPalette,
|
||||
xychartLinePlotPalette:
|
||||
config.themeVariables?.xychartLinePlotPalette || defaultThemeVariables.xychartLinePlotPalette,
|
||||
xychartPlotBaseColor:
|
||||
config.themeVariables?.xychartPlotBaseColor || defaultThemeVariables.xychartPlotBaseColor,
|
||||
};
|
||||
}
|
||||
function getChartDefaultConfig(): XYChartConfig {
|
||||
@@ -110,6 +127,9 @@ function getChartDefalutData(): XYChartData {
|
||||
let xyChartConfig: XYChartConfig = getChartDefaultConfig();
|
||||
let xyChartThemeConfig: XYChartThemeConfig = getChartDefaultThemeConfig();
|
||||
let xyChartData: XYChartData = getChartDefalutData();
|
||||
let plotColorPalette = Array.isArray(xyChartThemeConfig.xychartPlotBaseColor)
|
||||
? xyChartThemeConfig.xychartPlotBaseColor
|
||||
: plotColorPaletteGenerator(xyChartThemeConfig.xychartPlotBaseColor);
|
||||
let hasSetXAxis = false;
|
||||
let hasSetYAxis = false;
|
||||
|
||||
@@ -197,27 +217,32 @@ function transformDataWithOutCategory(data: number[]): SimplePlotDataType {
|
||||
|
||||
return retData;
|
||||
}
|
||||
|
||||
let plotIndex = 0;
|
||||
|
||||
function getPlotColorFromPalette(plotIndex: number): string {
|
||||
return plotColorPalette[plotIndex === 0 ? 0 : plotIndex % (plotColorPalette.length - 1)];
|
||||
}
|
||||
|
||||
function setLineData(title: string, data: number[]) {
|
||||
const plotData = transformDataWithOutCategory(data);
|
||||
xyChartData.plots.push({
|
||||
type: 'line',
|
||||
strokeFill:
|
||||
xyChartThemeConfig.xychartLinePlotPalette[
|
||||
Math.floor(Math.random() * (xyChartThemeConfig.xychartLinePlotPalette.length - 1))
|
||||
],
|
||||
strokeFill: getPlotColorFromPalette(plotIndex),
|
||||
strokeWidth: 2,
|
||||
data: plotData,
|
||||
});
|
||||
plotIndex++;
|
||||
}
|
||||
|
||||
function setBarData(title: string, data: number[]) {
|
||||
const plotData = transformDataWithOutCategory(data);
|
||||
xyChartData.plots.push({
|
||||
type: 'bar',
|
||||
fill: xyChartThemeConfig.xychartBarPlotPalette[
|
||||
Math.floor(Math.random() * (xyChartThemeConfig.xychartBarPlotPalette.length - 1))
|
||||
],
|
||||
fill: getPlotColorFromPalette(plotIndex),
|
||||
data: plotData,
|
||||
});
|
||||
plotIndex++;
|
||||
}
|
||||
|
||||
function getDrawableElem(): DrawableElem[] {
|
||||
@@ -238,9 +263,13 @@ function setWidth(width: number) {
|
||||
|
||||
const clear = function () {
|
||||
commonClear();
|
||||
plotIndex = 0;
|
||||
xyChartConfig = getChartDefaultConfig();
|
||||
xyChartData = getChartDefalutData();
|
||||
xyChartThemeConfig = getChartDefaultThemeConfig();
|
||||
plotColorPalette = Array.isArray(xyChartThemeConfig.xychartPlotBaseColor)
|
||||
? xyChartThemeConfig.xychartPlotBaseColor
|
||||
: plotColorPaletteGenerator(xyChartThemeConfig.xychartPlotBaseColor);
|
||||
hasSetXAxis = false;
|
||||
hasSetYAxis = false;
|
||||
};
|
||||
|
@@ -282,10 +282,7 @@ class Theme {
|
||||
this.xychartYAxisTitleColor = this.xychartYAxisTitleColor || this.primaryTextColor;
|
||||
this.xychartYAxisLableColor = this.xychartYAxisLableColor || this.primaryTextColor;
|
||||
this.xychartYAxisTickColor = this.xychartYAxisTickColor || this.primaryTextColor;
|
||||
this.xychartBarPlotPalette = this.xychartBarPlotPalette || [this.primaryColor];
|
||||
this.xychartLinePlotPalette = this.xychartLinePlotPalette || [
|
||||
adjust(this.primaryColor, { r: -100, g: -100, b: -100 }),
|
||||
];
|
||||
this.xychartPlotBaseColor = this.xychartPlotBaseColor || darken(this.primaryColor, 25);
|
||||
|
||||
/* requirement-diagram */
|
||||
this.requirementBackground = this.requirementBackground || this.primaryColor;
|
||||
|
Reference in New Issue
Block a user