@ai-gui/plugin-figure 0.11.0 → 0.12.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/CHANGELOG.md +14 -0
- package/dist/index.cjs +33 -4
- package/dist/index.js +33 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @ai-gui/plugin-figure
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [32f827c]
|
|
8
|
+
- @ai-gui/core@0.12.0
|
|
9
|
+
|
|
10
|
+
## 0.11.1
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [f84cb1d]
|
|
15
|
+
- @ai-gui/core@0.11.1
|
|
16
|
+
|
|
3
17
|
## 0.11.0
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -199,6 +199,10 @@ function figureBounds(diagram) {
|
|
|
199
199
|
* The side has to follow the part, not its turn in the list. Alternating sides sends the leader for
|
|
200
200
|
* a part on the left out to the right, straight across everything drawn in between, and a figure
|
|
201
201
|
* whose lines cross the thing they are labelling cannot be read.
|
|
202
|
+
*
|
|
203
|
+
* Concentric parts are the exception, and a common one — a cell drawn as membrane, cytoplasm and
|
|
204
|
+
* nucleus shares one centre, so following the part would pile every label into one gutter and leave
|
|
205
|
+
* the other empty. A part with no side of its own alternates instead.
|
|
202
206
|
*/
|
|
203
207
|
function layOutCallouts(diagram, bounds) {
|
|
204
208
|
const [minX, minY, maxX, maxY] = bounds;
|
|
@@ -206,7 +210,9 @@ function layOutCallouts(diagram, bounds) {
|
|
|
206
210
|
const labelled = diagram.parts.filter((part) => part.label !== void 0);
|
|
207
211
|
const placed = [];
|
|
208
212
|
const gutter = 56;
|
|
213
|
+
const offCentre = Math.max(1, maxX - minX) * .06;
|
|
209
214
|
const automatic = [];
|
|
215
|
+
let alternated = 0;
|
|
210
216
|
for (const part of labelled) {
|
|
211
217
|
if (part.labelAt) {
|
|
212
218
|
const { at: at$1 } = boundsOf(part);
|
|
@@ -218,9 +224,16 @@ function layOutCallouts(diagram, bounds) {
|
|
|
218
224
|
continue;
|
|
219
225
|
}
|
|
220
226
|
const { at } = boundsOf(part);
|
|
227
|
+
const offset = at[0] - centreX;
|
|
228
|
+
let side;
|
|
229
|
+
if (Math.abs(offset) > offCentre) side = offset < 0 ? "left" : "right";
|
|
230
|
+
else {
|
|
231
|
+
side = alternated % 2 === 0 ? "left" : "right";
|
|
232
|
+
alternated += 1;
|
|
233
|
+
}
|
|
221
234
|
automatic.push({
|
|
222
235
|
part,
|
|
223
|
-
side
|
|
236
|
+
side,
|
|
224
237
|
y: at[1]
|
|
225
238
|
});
|
|
226
239
|
}
|
|
@@ -312,14 +325,30 @@ function renderFigureSVG(diagram, options = {}) {
|
|
|
312
325
|
"</g></svg>"
|
|
313
326
|
].join("");
|
|
314
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* How wide a string will draw, near enough to reserve space for.
|
|
330
|
+
*
|
|
331
|
+
* The browser lays the text out, so this cannot be measured here — and a fixed allowance is what
|
|
332
|
+
* clipped "control center containing DNA" to "trol center containing DNA" against the left edge. A
|
|
333
|
+
* CJK glyph is about as wide as the font size; Latin runs a little over half.
|
|
334
|
+
*/
|
|
335
|
+
function textWidth(text, fontSize) {
|
|
336
|
+
let width = 0;
|
|
337
|
+
for (const character of text) {
|
|
338
|
+
const code = character.codePointAt(0) ?? 0;
|
|
339
|
+
const wide = code > 11903 && code < 40960;
|
|
340
|
+
width += wide ? fontSize : fontSize * .58;
|
|
341
|
+
}
|
|
342
|
+
return width;
|
|
343
|
+
}
|
|
315
344
|
/** Widen the drawing box until every callout, and the caption, is inside it. */
|
|
316
345
|
function viewWithCallouts(bounds, callouts, hasCaption) {
|
|
317
|
-
const textRoom = 120;
|
|
318
346
|
const xs = [bounds[0], bounds[2]];
|
|
319
347
|
const ys = [bounds[1], bounds[3]];
|
|
320
348
|
for (const callout of callouts) {
|
|
321
|
-
|
|
322
|
-
|
|
349
|
+
const room = Math.max(textWidth(callout.part.label ?? "", 13), textWidth(callout.part.note ?? "", 11));
|
|
350
|
+
xs.push(callout.side === "left" ? callout.at[0] - room : callout.at[0] + room);
|
|
351
|
+
ys.push(callout.at[1] - (callout.part.note ? 26 : 12), callout.at[1] + 12);
|
|
323
352
|
}
|
|
324
353
|
const pad = 12;
|
|
325
354
|
return [
|
package/dist/index.js
CHANGED
|
@@ -197,6 +197,10 @@ function figureBounds(diagram) {
|
|
|
197
197
|
* The side has to follow the part, not its turn in the list. Alternating sides sends the leader for
|
|
198
198
|
* a part on the left out to the right, straight across everything drawn in between, and a figure
|
|
199
199
|
* whose lines cross the thing they are labelling cannot be read.
|
|
200
|
+
*
|
|
201
|
+
* Concentric parts are the exception, and a common one — a cell drawn as membrane, cytoplasm and
|
|
202
|
+
* nucleus shares one centre, so following the part would pile every label into one gutter and leave
|
|
203
|
+
* the other empty. A part with no side of its own alternates instead.
|
|
200
204
|
*/
|
|
201
205
|
function layOutCallouts(diagram, bounds) {
|
|
202
206
|
const [minX, minY, maxX, maxY] = bounds;
|
|
@@ -204,7 +208,9 @@ function layOutCallouts(diagram, bounds) {
|
|
|
204
208
|
const labelled = diagram.parts.filter((part) => part.label !== void 0);
|
|
205
209
|
const placed = [];
|
|
206
210
|
const gutter = 56;
|
|
211
|
+
const offCentre = Math.max(1, maxX - minX) * .06;
|
|
207
212
|
const automatic = [];
|
|
213
|
+
let alternated = 0;
|
|
208
214
|
for (const part of labelled) {
|
|
209
215
|
if (part.labelAt) {
|
|
210
216
|
const { at: at$1 } = boundsOf(part);
|
|
@@ -216,9 +222,16 @@ function layOutCallouts(diagram, bounds) {
|
|
|
216
222
|
continue;
|
|
217
223
|
}
|
|
218
224
|
const { at } = boundsOf(part);
|
|
225
|
+
const offset = at[0] - centreX;
|
|
226
|
+
let side;
|
|
227
|
+
if (Math.abs(offset) > offCentre) side = offset < 0 ? "left" : "right";
|
|
228
|
+
else {
|
|
229
|
+
side = alternated % 2 === 0 ? "left" : "right";
|
|
230
|
+
alternated += 1;
|
|
231
|
+
}
|
|
219
232
|
automatic.push({
|
|
220
233
|
part,
|
|
221
|
-
side
|
|
234
|
+
side,
|
|
222
235
|
y: at[1]
|
|
223
236
|
});
|
|
224
237
|
}
|
|
@@ -310,14 +323,30 @@ function renderFigureSVG(diagram, options = {}) {
|
|
|
310
323
|
"</g></svg>"
|
|
311
324
|
].join("");
|
|
312
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* How wide a string will draw, near enough to reserve space for.
|
|
328
|
+
*
|
|
329
|
+
* The browser lays the text out, so this cannot be measured here — and a fixed allowance is what
|
|
330
|
+
* clipped "control center containing DNA" to "trol center containing DNA" against the left edge. A
|
|
331
|
+
* CJK glyph is about as wide as the font size; Latin runs a little over half.
|
|
332
|
+
*/
|
|
333
|
+
function textWidth(text, fontSize) {
|
|
334
|
+
let width = 0;
|
|
335
|
+
for (const character of text) {
|
|
336
|
+
const code = character.codePointAt(0) ?? 0;
|
|
337
|
+
const wide = code > 11903 && code < 40960;
|
|
338
|
+
width += wide ? fontSize : fontSize * .58;
|
|
339
|
+
}
|
|
340
|
+
return width;
|
|
341
|
+
}
|
|
313
342
|
/** Widen the drawing box until every callout, and the caption, is inside it. */
|
|
314
343
|
function viewWithCallouts(bounds, callouts, hasCaption) {
|
|
315
|
-
const textRoom = 120;
|
|
316
344
|
const xs = [bounds[0], bounds[2]];
|
|
317
345
|
const ys = [bounds[1], bounds[3]];
|
|
318
346
|
for (const callout of callouts) {
|
|
319
|
-
|
|
320
|
-
|
|
347
|
+
const room = Math.max(textWidth(callout.part.label ?? "", 13), textWidth(callout.part.note ?? "", 11));
|
|
348
|
+
xs.push(callout.side === "left" ? callout.at[0] - room : callout.at[0] + room);
|
|
349
|
+
ys.push(callout.at[1] - (callout.part.note ? 26 : 12), callout.at[1] + 12);
|
|
321
350
|
}
|
|
322
351
|
const pad = 12;
|
|
323
352
|
return [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-gui/plugin-figure",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Labelled figures — regions with leader-line callouts — rendered as SVG from a declarative block.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"llm",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"access": "public"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@ai-gui/core": "0.
|
|
57
|
+
"@ai-gui/core": "0.12.0"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
60
|
"build": "tsdown",
|