mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-26 02:39:41 +02:00
Improved parsing to work for minimal configuration possible.
This commit is contained in:
@@ -39,11 +39,9 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<h1>XY Charts demos</h1>
|
<h1>XY Charts demos</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta horizontal
|
xychart-beta
|
||||||
title Basic xychart
|
|
||||||
x-axis "this is x axis" [category1, "category 2", category3, category4]
|
|
||||||
y-axis yaxisText 10 --> 150
|
|
||||||
line [23, 46, 75, 43]
|
line [23, 46, 75, 43]
|
||||||
|
bar "sample bat" [52, 96, 35, 10]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
@@ -4,7 +4,7 @@ export interface ChartComponent {
|
|||||||
getDrawableElements(): DrawableElem[];
|
getDrawableElements(): DrawableElem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SimplePlotDataType = [string | number, number][];
|
export type SimplePlotDataType = [string, number][];
|
||||||
|
|
||||||
export interface LinePlotData {
|
export interface LinePlotData {
|
||||||
type: 'line';
|
type: 'line';
|
||||||
@@ -26,11 +26,13 @@ export function isBarPlot(data: PlotData): data is BarPlotData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface BandAxisDataType {
|
export interface BandAxisDataType {
|
||||||
|
type: 'band';
|
||||||
title: string;
|
title: string;
|
||||||
categories: string[];
|
categories: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LinearAxisDataType {
|
export interface LinearAxisDataType {
|
||||||
|
type: 'linear';
|
||||||
title: string;
|
title: string;
|
||||||
min: number;
|
min: number;
|
||||||
max: number;
|
max: number;
|
||||||
@@ -38,8 +40,12 @@ export interface LinearAxisDataType {
|
|||||||
|
|
||||||
export type AxisDataType = LinearAxisDataType | BandAxisDataType;
|
export type AxisDataType = LinearAxisDataType | BandAxisDataType;
|
||||||
|
|
||||||
export function isBandAxisData(data: any): data is BandAxisDataType {
|
export function isBandAxisData(data: AxisDataType): data is BandAxisDataType {
|
||||||
return data.categories && Array.isArray(data.categories);
|
return data.type === 'band';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isLinearAxisData(data: AxisDataType): data is LinearAxisDataType {
|
||||||
|
return data.type === 'linear';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface XYChartData {
|
export interface XYChartData {
|
||||||
|
@@ -12,7 +12,13 @@ import {
|
|||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
} from '../../commonDb.js';
|
} from '../../commonDb.js';
|
||||||
import { XYChartBuilder } from './chartBuilder/index.js';
|
import { XYChartBuilder } from './chartBuilder/index.js';
|
||||||
import { DrawableElem, XYChartData, isBandAxisData } from './chartBuilder/Interfaces.js';
|
import {
|
||||||
|
DrawableElem,
|
||||||
|
SimplePlotDataType,
|
||||||
|
XYChartData,
|
||||||
|
isBandAxisData,
|
||||||
|
isLinearAxisData,
|
||||||
|
} from './chartBuilder/Interfaces.js';
|
||||||
import { XYChartConfig } from '../../config.type.js';
|
import { XYChartConfig } from '../../config.type.js';
|
||||||
|
|
||||||
const config = configApi.getConfig();
|
const config = configApi.getConfig();
|
||||||
@@ -64,12 +70,14 @@ function getChartDefaultConfig(): XYChartConfig {
|
|||||||
function getChartDefalutData(): XYChartData {
|
function getChartDefalutData(): XYChartData {
|
||||||
return {
|
return {
|
||||||
yAxis: {
|
yAxis: {
|
||||||
title: 'yAxis1',
|
type: 'linear',
|
||||||
min: 0,
|
title: '',
|
||||||
max: 100,
|
min: Infinity,
|
||||||
|
max: -Infinity,
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
title: 'xAxis',
|
type: 'band',
|
||||||
|
title: '',
|
||||||
categories: [],
|
categories: [],
|
||||||
},
|
},
|
||||||
title: '',
|
title: '',
|
||||||
@@ -79,6 +87,8 @@ function getChartDefalutData(): XYChartData {
|
|||||||
|
|
||||||
let xyChartConfig: XYChartConfig = getChartDefaultConfig();
|
let xyChartConfig: XYChartConfig = getChartDefaultConfig();
|
||||||
let xyChartData: XYChartData = getChartDefalutData();
|
let xyChartData: XYChartData = getChartDefalutData();
|
||||||
|
let hasSetXAxis = false;
|
||||||
|
let hasSetYAxis = false;
|
||||||
|
|
||||||
function textSanitizer(text: string) {
|
function textSanitizer(text: string) {
|
||||||
return sanitizeText(text.trim(), config);
|
return sanitizeText(text.trim(), config);
|
||||||
@@ -100,41 +110,92 @@ function setXAxisTitle(title: string) {
|
|||||||
xyChartData.xAxis.title = textSanitizer(title);
|
xyChartData.xAxis.title = textSanitizer(title);
|
||||||
}
|
}
|
||||||
function setXAxisRangeData(min: number, max: number) {
|
function setXAxisRangeData(min: number, max: number) {
|
||||||
xyChartData.xAxis = { title: xyChartData.xAxis.title, min, max };
|
xyChartData.xAxis = { type: 'linear', title: xyChartData.xAxis.title, min, max };
|
||||||
|
hasSetXAxis = true;
|
||||||
}
|
}
|
||||||
function setXAxisBand(categories: string[]) {
|
function setXAxisBand(categories: string[]) {
|
||||||
xyChartData.xAxis = {
|
xyChartData.xAxis = {
|
||||||
|
type: 'band',
|
||||||
title: xyChartData.xAxis.title,
|
title: xyChartData.xAxis.title,
|
||||||
categories: categories.map((c) => textSanitizer(c)),
|
categories: categories.map((c) => textSanitizer(c)),
|
||||||
};
|
};
|
||||||
|
hasSetXAxis = true;
|
||||||
}
|
}
|
||||||
function setYAxisTitle(title: string) {
|
function setYAxisTitle(title: string) {
|
||||||
xyChartData.yAxis.title = textSanitizer(title);
|
xyChartData.yAxis.title = textSanitizer(title);
|
||||||
}
|
}
|
||||||
function setYAxisRangeData(min: number, max: number) {
|
function setYAxisRangeData(min: number, max: number) {
|
||||||
xyChartData.yAxis = { title: xyChartData.yAxis.title, min, max };
|
xyChartData.yAxis = { type: 'linear', title: xyChartData.yAxis.title, min, max };
|
||||||
|
hasSetYAxis = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function does not set `hasSetYAxis` as there can be multiple data so we should calculate the range accordingly
|
||||||
|
function setYAxisRangeFromPlotData(data: number[]) {
|
||||||
|
const minValue = Math.min(...data);
|
||||||
|
const maxValue = Math.max(...data);
|
||||||
|
const prevMinValue = isLinearAxisData(xyChartData.yAxis) ? xyChartData.yAxis.min : Infinity;
|
||||||
|
const prevMaxValue = isLinearAxisData(xyChartData.yAxis) ? xyChartData.yAxis.max : -Infinity;
|
||||||
|
xyChartData.yAxis = {
|
||||||
|
type: 'linear',
|
||||||
|
title: xyChartData.yAxis.title,
|
||||||
|
min: Math.min(prevMinValue, minValue),
|
||||||
|
max: Math.max(prevMaxValue, maxValue),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformDataWithOutCategory(data: number[]): SimplePlotDataType {
|
||||||
|
let retData: SimplePlotDataType = [];
|
||||||
|
if (data.length === 0) {
|
||||||
|
return retData;
|
||||||
|
}
|
||||||
|
if (!hasSetXAxis) {
|
||||||
|
const prevMinValue = isLinearAxisData(xyChartData.xAxis) ? xyChartData.xAxis.min : Infinity;
|
||||||
|
const prevMaxValue = isLinearAxisData(xyChartData.xAxis) ? xyChartData.xAxis.max : -Infinity;
|
||||||
|
setXAxisRangeData(Math.min(prevMinValue, 1), Math.max(prevMaxValue, data.length));
|
||||||
|
}
|
||||||
|
if (!hasSetYAxis) {
|
||||||
|
setYAxisRangeFromPlotData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBandAxisData(xyChartData.xAxis)) {
|
||||||
|
retData = xyChartData.xAxis.categories.map((c, i) => [c, data[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLinearAxisData(xyChartData.xAxis)) {
|
||||||
|
const min = xyChartData.xAxis.min;
|
||||||
|
const max = xyChartData.xAxis.max;
|
||||||
|
const step = (max - min + 1) / data.length;
|
||||||
|
const categories: string[] = [];
|
||||||
|
for (let i = min; i <= max; i += step) {
|
||||||
|
categories.push(`${i}`);
|
||||||
|
}
|
||||||
|
retData = categories.map((c, i) => [c, data[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retData;
|
||||||
}
|
}
|
||||||
function setLineData(title: string, data: number[]) {
|
function setLineData(title: string, data: number[]) {
|
||||||
if (isBandAxisData(xyChartData.xAxis)) {
|
const plotData = transformDataWithOutCategory(data);
|
||||||
xyChartData.plots.push({
|
xyChartData.plots.push({
|
||||||
type: 'line',
|
type: 'line',
|
||||||
strokeFill: '#00ff00',
|
strokeFill: '#00ff00',
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
data: xyChartData.xAxis.categories.map((c, i) => [c, data[i]]),
|
data: plotData,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
function setBarData(title: string, data: number[]) {
|
function setBarData(title: string, data: number[]) {
|
||||||
if (isBandAxisData(xyChartData.xAxis)) {
|
const plotData = transformDataWithOutCategory(data);
|
||||||
xyChartData.plots.push({
|
xyChartData.plots.push({
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
fill: '#0000bb',
|
fill: '#0000bb',
|
||||||
data: xyChartData.xAxis.categories.map((c, i) => [c, data[i]]),
|
data: plotData,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function getDrawableElem(): DrawableElem[] {
|
function getDrawableElem(): DrawableElem[] {
|
||||||
|
if (xyChartData.plots.length === 0) {
|
||||||
|
throw Error('No Plot to render, please provide a plot with some data');
|
||||||
|
}
|
||||||
xyChartData.title = getDiagramTitle();
|
xyChartData.title = getDiagramTitle();
|
||||||
return XYChartBuilder.build(xyChartConfig, xyChartData);
|
return XYChartBuilder.build(xyChartConfig, xyChartData);
|
||||||
}
|
}
|
||||||
@@ -151,6 +212,8 @@ const clear = function () {
|
|||||||
commonClear();
|
commonClear();
|
||||||
xyChartConfig = getChartDefaultConfig();
|
xyChartConfig = getChartDefaultConfig();
|
||||||
xyChartData = getChartDefalutData();
|
xyChartData = getChartDefalutData();
|
||||||
|
hasSetXAxis = false;
|
||||||
|
hasSetYAxis = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
Reference in New Issue
Block a user