mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-18 23:09:49 +02:00
support for multiple datasets added
This commit is contained in:
@@ -52,7 +52,7 @@
|
|||||||
line [+1.3, .6, 2.4, -.34]
|
line [+1.3, .6, 2.4, -.34]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h1>XY Charts Bar with multiple category</h1>
|
<h1>XY Charts bar with single dataset</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart-beta
|
||||||
title "Basic xychart with many categories"
|
title "Basic xychart with many categories"
|
||||||
@@ -61,7 +61,25 @@
|
|||||||
bar "sample bar" [52, 96, 35, 10, 87, 34, 67, 99]
|
bar "sample bar" [52, 96, 35, 10, 87, 34, 67, 99]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h1>XY Charts line with multiple category</h1>
|
<h1>XY Charts bar with multiple datasets</h1>
|
||||||
|
<pre class="mermaid">
|
||||||
|
xychart-beta
|
||||||
|
title "Basic xychart with multiple datasets"
|
||||||
|
x-axis "Relevant categories" [category1, "category 2", category3, category4, category5, category6, category7]
|
||||||
|
y-axis Animals 10 --> 200
|
||||||
|
bar [["dogs" [52, 96, 35, 10, 87, 34, 67, 99]],["cats" [15, 7, 23, 55, 11, 41, 26, 3]]]
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>XY Charts bar horizontal with multiple datasets</h1>
|
||||||
|
<pre class="mermaid">
|
||||||
|
xychart-beta horizontal
|
||||||
|
title "Basic xychart with multiple datasets"
|
||||||
|
x-axis "Relevant categories" [category1, "category 2", category3, category4, category5, category6, category7]
|
||||||
|
y-axis Animals 10 --> 200
|
||||||
|
bar [["dogs" [52, 96, 35, 10, 87, 34, 67, 99]],["cats" [15, 7, 23, 55, 11, 41, 26, 3]]]
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>XY Charts line single dataset</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart-beta
|
||||||
title "Line chart with many category"
|
title "Line chart with many category"
|
||||||
@@ -70,7 +88,7 @@
|
|||||||
line "sample line" [52, 96, 35, 10, 87, 34, 67, 99]
|
line "sample line" [52, 96, 35, 10, 87, 34, 67, 99]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h1>XY Charts category with large text</h1>
|
<h1>XY Charts bar with large text</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart-beta
|
xychart-beta
|
||||||
title "Basic xychart with many categories with category overlap"
|
title "Basic xychart with many categories with category overlap"
|
||||||
|
@@ -3,7 +3,7 @@ import type { Axis } from '../axis/index.js';
|
|||||||
|
|
||||||
export class BarPlot {
|
export class BarPlot {
|
||||||
constructor(
|
constructor(
|
||||||
private barData: BarPlotData,
|
private barData: BarPlotData[],
|
||||||
private boundingRect: BoundingRect,
|
private boundingRect: BoundingRect,
|
||||||
private xAxis: Axis,
|
private xAxis: Axis,
|
||||||
private yAxis: Axis,
|
private yAxis: Axis,
|
||||||
@@ -12,49 +12,58 @@ export class BarPlot {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
getDrawableElement(): DrawableElem[] {
|
getDrawableElement(): DrawableElem[] {
|
||||||
const finalData: [number, number][] = this.barData.data.map((d) => [
|
const offset = new Array(this.barData[0].data.length).fill(0);
|
||||||
this.xAxis.getScaleValue(d[0]),
|
return this.barData.map((barData, dataIndex) => {
|
||||||
this.yAxis.getScaleValue(d[1]),
|
const finalData: [number, number][] = barData.data.map((d) => [
|
||||||
]);
|
this.xAxis.getScaleValue(d[0]),
|
||||||
|
this.yAxis.getScaleValue(d[1]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const barPaddingPercent = 0.05;
|
||||||
|
|
||||||
const barPaddingPercent = 0.05;
|
const barWidth =
|
||||||
|
Math.min(this.xAxis.getAxisOuterPadding() * 2, this.xAxis.getTickDistance()) *
|
||||||
const barWidth =
|
(1 - barPaddingPercent);
|
||||||
Math.min(this.xAxis.getAxisOuterPadding() * 2, this.xAxis.getTickDistance()) *
|
const barWidthHalf = barWidth / 2;
|
||||||
(1 - barPaddingPercent);
|
|
||||||
const barWidthHalf = barWidth / 2;
|
if (this.orientation === 'horizontal') {
|
||||||
|
return {
|
||||||
if (this.orientation === 'horizontal') {
|
groupTexts: ['plot', `bar-plot-${this.plotIndex}-${dataIndex}`],
|
||||||
return [
|
type: 'rect',
|
||||||
{
|
data: finalData.map((data, index) => {
|
||||||
groupTexts: ['plot', `bar-plot-${this.plotIndex}`],
|
const x = offset[index] + this.boundingRect.x;
|
||||||
|
const width = data[1] - this.boundingRect.x;
|
||||||
|
offset[index] += width;
|
||||||
|
return {
|
||||||
|
x,
|
||||||
|
y: data[0] - barWidthHalf,
|
||||||
|
height: barWidth,
|
||||||
|
width,
|
||||||
|
fill: barData.fill,
|
||||||
|
strokeWidth: 0,
|
||||||
|
strokeFill: barData.fill,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
groupTexts: ['plot', `bar-plot-${this.plotIndex}-${dataIndex}`],
|
||||||
type: 'rect',
|
type: 'rect',
|
||||||
data: finalData.map((data) => ({
|
data: finalData.map((data, index) => {
|
||||||
x: this.boundingRect.x,
|
const y = data[1] - offset[index];
|
||||||
y: data[0] - barWidthHalf,
|
const height = this.boundingRect.y + this.boundingRect.height - data[1];
|
||||||
height: barWidth,
|
offset[index] += height;
|
||||||
width: data[1] - this.boundingRect.x,
|
return {
|
||||||
fill: this.barData.fill,
|
x: data[0] - barWidthHalf,
|
||||||
strokeWidth: 0,
|
y,
|
||||||
strokeFill: this.barData.fill,
|
width: barWidth,
|
||||||
})),
|
height,
|
||||||
},
|
fill: barData.fill,
|
||||||
];
|
strokeWidth: 0,
|
||||||
}
|
strokeFill: barData.fill,
|
||||||
return [
|
};
|
||||||
{
|
}),
|
||||||
groupTexts: ['plot', `bar-plot-${this.plotIndex}`],
|
};
|
||||||
type: 'rect',
|
});
|
||||||
data: finalData.map((data) => ({
|
|
||||||
x: data[0] - barWidthHalf,
|
|
||||||
y: data[1],
|
|
||||||
width: barWidth,
|
|
||||||
height: this.boundingRect.y + this.boundingRect.height - data[1],
|
|
||||||
fill: this.barData.fill,
|
|
||||||
strokeWidth: 0,
|
|
||||||
strokeFill: this.barData.fill,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,8 @@ import type {
|
|||||||
Point,
|
Point,
|
||||||
XYChartThemeConfig,
|
XYChartThemeConfig,
|
||||||
XYChartConfig,
|
XYChartConfig,
|
||||||
|
BarPlotData,
|
||||||
|
LinePlotData,
|
||||||
} from '../../interfaces.js';
|
} from '../../interfaces.js';
|
||||||
import type { Axis } from '../axis/index.js';
|
import type { Axis } from '../axis/index.js';
|
||||||
import type { ChartComponent } from '../../interfaces.js';
|
import type { ChartComponent } from '../../interfaces.js';
|
||||||
@@ -55,34 +57,31 @@ export class BasePlot implements Plot {
|
|||||||
throw Error('Axes must be passed to render Plots');
|
throw Error('Axes must be passed to render Plots');
|
||||||
}
|
}
|
||||||
const drawableElem: DrawableElem[] = [];
|
const drawableElem: DrawableElem[] = [];
|
||||||
for (const [i, plot] of this.chartData.plots.entries()) {
|
const linePlots = this.chartData.plots.filter(plot => plot.type === 'line') as LinePlotData[];
|
||||||
switch (plot.type) {
|
const barPlots = this.chartData.plots.filter(plot => plot.type === 'bar') as BarPlotData[];
|
||||||
case 'line':
|
|
||||||
{
|
let plotIndex = 0;
|
||||||
const linePlot = new LinePlot(
|
if(linePlots.length) {
|
||||||
plot,
|
const linePlot = new LinePlot(
|
||||||
this.xAxis,
|
linePlots[0],
|
||||||
this.yAxis,
|
this.xAxis,
|
||||||
this.chartConfig.chartOrientation,
|
this.yAxis,
|
||||||
i
|
this.chartConfig.chartOrientation,
|
||||||
);
|
plotIndex
|
||||||
drawableElem.push(...linePlot.getDrawableElement());
|
);
|
||||||
}
|
drawableElem.push(...linePlot.getDrawableElement());
|
||||||
break;
|
}
|
||||||
case 'bar':
|
if(barPlots.length) {
|
||||||
{
|
const barPlot = new BarPlot(
|
||||||
const barPlot = new BarPlot(
|
barPlots,
|
||||||
plot,
|
this.boundingRect,
|
||||||
this.boundingRect,
|
this.xAxis,
|
||||||
this.xAxis,
|
this.yAxis,
|
||||||
this.yAxis,
|
this.chartConfig.chartOrientation,
|
||||||
this.chartConfig.chartOrientation,
|
plotIndex
|
||||||
i
|
);
|
||||||
);
|
drawableElem.push(...barPlot.getDrawableElement());
|
||||||
drawableElem.push(...barPlot.getDrawableElement());
|
plotIndex++;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return drawableElem;
|
return drawableElem;
|
||||||
}
|
}
|
||||||
|
@@ -102,13 +102,28 @@ statement
|
|||||||
| Y_AXIS parseYAxis
|
| Y_AXIS parseYAxis
|
||||||
| LINE plotData { yy.setLineData({text: '', type: 'text'}, $plotData); }
|
| LINE plotData { yy.setLineData({text: '', type: 'text'}, $plotData); }
|
||||||
| LINE text plotData { yy.setLineData($text, $plotData); }
|
| LINE text plotData { yy.setLineData($text, $plotData); }
|
||||||
| BAR plotData { yy.setBarData({text: '', type: 'text'}, $plotData); }
|
| BAR datasets { yy.setBarData($datasets); }
|
||||||
| BAR text plotData { yy.setBarData($text, $plotData); }
|
|
||||||
| acc_title acc_title_value { $$=$acc_title_value.trim();yy.setAccTitle($$); }
|
| acc_title acc_title_value { $$=$acc_title_value.trim();yy.setAccTitle($$); }
|
||||||
| acc_descr acc_descr_value { $$=$acc_descr_value.trim();yy.setAccDescription($$); }
|
| acc_descr acc_descr_value { $$=$acc_descr_value.trim();yy.setAccDescription($$); }
|
||||||
| acc_descr_multiline_value { $$=$acc_descr_multiline_value.trim();yy.setAccDescription($$); }
|
| acc_descr_multiline_value { $$=$acc_descr_multiline_value.trim();yy.setAccDescription($$); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
datasets
|
||||||
|
: SQUARE_BRACES_START datasetBraced COMMA datasets SQUARE_BRACES_END { $$ = [$datasetBraced, ...$datasets] }
|
||||||
|
| SQUARE_BRACES_START datasetBraced SQUARE_BRACES_END { $$ = [$datasetBraced] }
|
||||||
|
| datasetBraced { $$ = [$datasetBraced] }
|
||||||
|
| dataset { $$ = [$dataset] }
|
||||||
|
;
|
||||||
|
|
||||||
|
datasetBraced
|
||||||
|
: SQUARE_BRACES_START dataset SQUARE_BRACES_END { $$ = $dataset }
|
||||||
|
;
|
||||||
|
|
||||||
|
dataset
|
||||||
|
: plotData { $$ = ['', $plotData] }
|
||||||
|
| text plotData { $$ = [$text, $plotData] }
|
||||||
|
;
|
||||||
|
|
||||||
plotData
|
plotData
|
||||||
: SQUARE_BRACES_START commaSeparatedNumbers SQUARE_BRACES_END { $$ = $commaSeparatedNumbers }
|
: SQUARE_BRACES_START commaSeparatedNumbers SQUARE_BRACES_END { $$ = $commaSeparatedNumbers }
|
||||||
;
|
;
|
||||||
|
@@ -169,14 +169,18 @@ function setLineData(title: NormalTextType, data: number[]) {
|
|||||||
plotIndex++;
|
plotIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBarData(title: NormalTextType, data: number[]) {
|
type NamedDataset = [title: NormalTextType, data: number[]];
|
||||||
const plotData = transformDataWithoutCategory(data);
|
|
||||||
xyChartData.plots.push({
|
function setBarData(datasets: NamedDataset[]) {
|
||||||
type: 'bar',
|
datasets.forEach(dataset => {
|
||||||
fill: getPlotColorFromPalette(plotIndex),
|
const plotData = transformDataWithoutCategory(dataset[1]);
|
||||||
data: plotData,
|
xyChartData.plots.push({
|
||||||
|
type: 'bar',
|
||||||
|
fill: getPlotColorFromPalette(plotIndex),
|
||||||
|
data: plotData,
|
||||||
|
});
|
||||||
|
plotIndex++;
|
||||||
});
|
});
|
||||||
plotIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDrawableElem(): DrawableElem[] {
|
function getDrawableElem(): DrawableElem[] {
|
||||||
|
Reference in New Issue
Block a user