mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-15 06:19:24 +02:00
96 lines
3.1 KiB
TypeScript
96 lines
3.1 KiB
TypeScript
import type { Diagram } from '../../Diagram.js';
|
|
import type { PacketDiagramConfig } from '../../config.type.js';
|
|
import type { DiagramRenderer, DrawDefinition, Group, SVG } from '../../diagram-api/types.js';
|
|
import { selectSvgElement } from '../../rendering-util/selectSvgElement.js';
|
|
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
|
import type { PacketDB, PacketWord } from './types.js';
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
const draw: DrawDefinition = (_text, id, _version, diagram: Diagram) => {
|
|
const db = diagram.db as PacketDB;
|
|
const config = db.getConfig();
|
|
const { rowHeight, paddingY, bitWidth, bitsPerRow } = config;
|
|
const words = db.getPacket();
|
|
const title = db.getDiagramTitle();
|
|
const totalRowHeight = rowHeight + paddingY;
|
|
const svgHeight = totalRowHeight * (words.length + 1) - (title ? 0 : rowHeight);
|
|
const svgWidth = bitWidth * bitsPerRow + 2;
|
|
const svg: SVG = selectSvgElement(id);
|
|
|
|
configureSvgSize(svg, svgHeight, svgWidth, true);
|
|
svg.attr('height', svgHeight + 'px');
|
|
|
|
for (const [row, packet] of words.entries()) {
|
|
drawWord(svg, packet, row, config);
|
|
}
|
|
|
|
svg
|
|
.append('text')
|
|
.text(title)
|
|
.attr('x', svgWidth / 2)
|
|
.attr('y', svgHeight - rowHeight)
|
|
.attr('dominant-baseline', 'middle')
|
|
.attr('text-anchor', 'middle')
|
|
.attr('class', 'packetTitle');
|
|
};
|
|
|
|
const drawWord = (
|
|
svg: SVG,
|
|
word: PacketWord,
|
|
rowNumber: number,
|
|
{ rowHeight, paddingX, paddingY, bitWidth, bitsPerRow, showBits }: Required<PacketDiagramConfig>
|
|
) => {
|
|
const group: Group = svg.append('g');
|
|
const wordY = rowNumber * (rowHeight + paddingY) + paddingY;
|
|
for (const block of word) {
|
|
const blockX = (block.start % bitsPerRow) * bitWidth + 1;
|
|
const width = (block.end - block.start + 1) * bitWidth - paddingX;
|
|
// Block rectangle
|
|
group
|
|
.append('rect')
|
|
.attr('x', blockX)
|
|
.attr('y', wordY)
|
|
.attr('width', width)
|
|
.attr('height', rowHeight)
|
|
.attr('class', 'packetBlock');
|
|
|
|
// Block label
|
|
group
|
|
.append('text')
|
|
.attr('x', blockX + width / 2)
|
|
.attr('y', wordY + rowHeight / 2)
|
|
.attr('class', 'packetLabel')
|
|
.attr('dominant-baseline', 'middle')
|
|
.attr('text-anchor', 'middle')
|
|
.text(block.label);
|
|
|
|
if (!showBits) {
|
|
continue;
|
|
}
|
|
// Start byte count
|
|
const isSingleBlock = block.end === block.start;
|
|
const bitNumberY = wordY - 2;
|
|
group
|
|
.append('text')
|
|
.attr('x', blockX + (isSingleBlock ? width / 2 : 0))
|
|
.attr('y', bitNumberY)
|
|
.attr('class', 'packetByte start')
|
|
.attr('dominant-baseline', 'auto')
|
|
.attr('text-anchor', isSingleBlock ? 'middle' : 'start')
|
|
.text(block.start);
|
|
|
|
// Draw end byte count if it is not the same as start byte count
|
|
if (!isSingleBlock) {
|
|
group
|
|
.append('text')
|
|
.attr('x', blockX + width)
|
|
.attr('y', bitNumberY)
|
|
.attr('class', 'packetByte end')
|
|
.attr('dominant-baseline', 'auto')
|
|
.attr('text-anchor', 'end')
|
|
.text(block.end);
|
|
}
|
|
}
|
|
};
|
|
export const renderer: DiagramRenderer = { draw };
|