@linemap/core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/index.mjs +2 -2
- package/package.json +1 -1
- package/src/render.mjs +3 -3
- package/src/theme.mjs +29 -2
package/README.md
CHANGED
|
@@ -15,10 +15,11 @@ const svg = render(layout(parseFlow(dotText)), { theme: 'dark' });
|
|
|
15
15
|
- `parseFlow(text)` reads a linemap DOT file into a model; errors are thrown with one-line messages.
|
|
16
16
|
- `layout(model, { hiddenLines, through, fixed })` places, routes and bundles it. Call it once
|
|
17
17
|
per parsed model.
|
|
18
|
-
- `render(model, { theme, css })` returns the SVG. Themes: `
|
|
18
|
+
- `render(model, { theme, css })` returns the SVG. Themes: `minimal` (default),
|
|
19
|
+
`light`, `dark`, `neon`, `neond`, each also as `-fancy` (shadows, glows, moving arrows; costlier).
|
|
19
20
|
- `positions(model)` gives the computed positions of unpinned nodes, ready to pin with `pos`.
|
|
20
21
|
|
|
21
|
-
The command line is [
|
|
22
|
+
The command line is [`@linemap/cli`](https://www.npmjs.com/package/@linemap/cli): `npx @linemap/cli flow.dot out.svg`.
|
|
22
23
|
The DOT format, themes and the studio are described in the
|
|
23
24
|
[project README](https://github.com/mergezalot/linemap#readme).
|
|
24
25
|
|
package/index.mjs
CHANGED
|
@@ -6,9 +6,9 @@ import { route } from './src/route.mjs';
|
|
|
6
6
|
import { bundle, markColor } from './src/bundle.mjs';
|
|
7
7
|
import { inside } from './src/inside.mjs';
|
|
8
8
|
import { render } from './src/render.mjs';
|
|
9
|
-
import { THEMES, THEME_NAMES, PALETTE, themeCss, paintLines } from './src/theme.mjs';
|
|
9
|
+
import { THEMES, THEME_NAMES, DEFAULT_THEME, PALETTE, themeCss, paintLines } from './src/theme.mjs';
|
|
10
10
|
|
|
11
|
-
export { parseFlow, crowding, render, canThrough, STYLE, markColor, THEMES, THEME_NAMES, PALETTE, themeCss, paintLines };
|
|
11
|
+
export { parseFlow, crowding, render, canThrough, STYLE, markColor, THEMES, THEME_NAMES, DEFAULT_THEME, PALETTE, themeCss, paintLines };
|
|
12
12
|
|
|
13
13
|
// Every stage between parsing and rendering, in order. Mutates and returns the model.
|
|
14
14
|
// Route, bundle and inside do not move items, so `crowding` gives the same answer after this.
|
package/package.json
CHANGED
package/src/render.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { STYLE, groupRects, textWidth, edgeLabelSize } from './model.mjs';
|
|
3
3
|
import { markColor } from './bundle.mjs';
|
|
4
4
|
import { f } from './geom.mjs';
|
|
5
|
-
import { getTheme, themeCss, accentStyle, shadowFilters, paintLines, tabText } from './theme.mjs';
|
|
5
|
+
import { getTheme, DEFAULT_THEME, themeCss, accentStyle, shadowFilters, paintLines, tabText } from './theme.mjs';
|
|
6
6
|
|
|
7
7
|
const esc = (s) => String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
8
8
|
// For attribute values: also keep newlines and tabs, which a parser would turn into spaces.
|
|
@@ -165,13 +165,13 @@ function legend(model, box, ctx = FLAT) {
|
|
|
165
165
|
|
|
166
166
|
// Options:
|
|
167
167
|
// legend false leaves out the legend and the room for it
|
|
168
|
-
// theme a theme name (theme.mjs); default: the DOT file's `theme`, else
|
|
168
|
+
// theme a theme name (theme.mjs); default: the DOT file's `theme`, else minimal
|
|
169
169
|
// css more CSS, after the theme's: restyle any lm-* class
|
|
170
170
|
// Elements carry data-* attributes (line ids, labels, shapes) for scripts; they change nothing drawn.
|
|
171
171
|
export function render(model, { legend: withLegend = true, theme, css = '' } = {}) {
|
|
172
172
|
// the CSS goes inside <style>, so it must not be able to end that element
|
|
173
173
|
if (/<\/style/i.test(css)) throw new Error('css: must not contain "</style"');
|
|
174
|
-
const themeName = theme ?? model.theme ??
|
|
174
|
+
const themeName = theme ?? model.theme ?? DEFAULT_THEME;
|
|
175
175
|
const T = getTheme(themeName);
|
|
176
176
|
paintLines(model.lines, T);
|
|
177
177
|
const fx = shadowFilters(T, themeName);
|
package/src/theme.mjs
CHANGED
|
@@ -51,7 +51,7 @@ const SOFT = (color, k = 1) => ({
|
|
|
51
51
|
group: [{ dy: 2, blur: 8, color, opacity: 0.05 * k }],
|
|
52
52
|
small: [{ dy: 1, blur: 2, color, opacity: 0.1 * k }],
|
|
53
53
|
});
|
|
54
|
-
|
|
54
|
+
const FANCY = {
|
|
55
55
|
light: {
|
|
56
56
|
label: 'Light',
|
|
57
57
|
font: SANS,
|
|
@@ -161,9 +161,36 @@ export const THEMES = {
|
|
|
161
161
|
},
|
|
162
162
|
},
|
|
163
163
|
};
|
|
164
|
+
|
|
165
|
+
// The plain themes leave out what costs the most to draw: the shadows and glows done with SVG blur
|
|
166
|
+
// filters (redrawn on every pan and zoom) and the travelling arrows (redrawn every frame, for as
|
|
167
|
+
// long as the map is on screen). The `-fancy` themes keep them. `edits` replaces parts of the
|
|
168
|
+
// fancy theme, for themes that lean on their shadows to set boxes apart.
|
|
169
|
+
const plain = (t, edits = {}) => {
|
|
170
|
+
const { shadow, line, ...rest } = t;
|
|
171
|
+
const { flow, ...still } = line ?? {};
|
|
172
|
+
return { ...rest, ...(Object.keys(still).length ? { line: still } : {}), ...edits };
|
|
173
|
+
};
|
|
174
|
+
const M = FANCY.minimal;
|
|
175
|
+
export const THEMES = {
|
|
176
|
+
// the default: minimal without its shadows, so its white cards get a faint outline instead
|
|
177
|
+
minimal: plain(M, {
|
|
178
|
+
node: { ...M.node, stroke: '#d5dbe3', width: 1.25 },
|
|
179
|
+
note: { ...M.note, stroke: '#e1e6ec' },
|
|
180
|
+
edgeLabel: { ...M.edgeLabel, stroke: '#d5dbe3' },
|
|
181
|
+
legend: { ...M.legend, stroke: '#d5dbe3' },
|
|
182
|
+
}),
|
|
183
|
+
light: plain(FANCY.light),
|
|
184
|
+
dark: plain(FANCY.dark),
|
|
185
|
+
neon: plain(FANCY.neon),
|
|
186
|
+
neond: plain(FANCY.neond),
|
|
187
|
+
...Object.fromEntries(['minimal', 'light', 'dark', 'neon', 'neond'].map((n) =>
|
|
188
|
+
[`${n}-fancy`, { ...FANCY[n], label: `${FANCY[n].label} fancy` }])),
|
|
189
|
+
};
|
|
164
190
|
export const THEME_NAMES = Object.keys(THEMES);
|
|
191
|
+
export const DEFAULT_THEME = 'minimal';
|
|
165
192
|
|
|
166
|
-
export function getTheme(name =
|
|
193
|
+
export function getTheme(name = DEFAULT_THEME) {
|
|
167
194
|
const t = THEMES[name];
|
|
168
195
|
if (!t) throw new Error(`unknown theme "${name}" (known: ${THEME_NAMES.join(', ')})`);
|
|
169
196
|
return t;
|