@hirokisakabe/pom 2.0.0 → 3.0.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.
Files changed (57) hide show
  1. package/README.md +158 -38
  2. package/dist/buildPptx.js +1 -1
  3. package/dist/calcYogaLayout/calcYogaLayout.d.ts.map +1 -1
  4. package/dist/calcYogaLayout/calcYogaLayout.js +95 -19
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -1
  8. package/dist/{inputSchema.d.ts → parseXml/inputSchema.d.ts} +253 -24
  9. package/dist/parseXml/inputSchema.d.ts.map +1 -0
  10. package/dist/{inputSchema.js → parseXml/inputSchema.js} +36 -2
  11. package/dist/{parseXml.d.ts → parseXml/parseXml.d.ts} +1 -1
  12. package/dist/parseXml/parseXml.d.ts.map +1 -0
  13. package/dist/{parseXml.js → parseXml/parseXml.js} +30 -2
  14. package/dist/renderPptx/nodes/flow.d.ts.map +1 -1
  15. package/dist/renderPptx/nodes/flow.js +26 -16
  16. package/dist/renderPptx/nodes/index.d.ts +1 -0
  17. package/dist/renderPptx/nodes/index.d.ts.map +1 -1
  18. package/dist/renderPptx/nodes/index.js +1 -0
  19. package/dist/renderPptx/nodes/list.d.ts +12 -0
  20. package/dist/renderPptx/nodes/list.d.ts.map +1 -0
  21. package/dist/renderPptx/nodes/list.js +145 -0
  22. package/dist/renderPptx/nodes/matrix.d.ts.map +1 -1
  23. package/dist/renderPptx/nodes/matrix.js +43 -31
  24. package/dist/renderPptx/nodes/processArrow.d.ts.map +1 -1
  25. package/dist/renderPptx/nodes/processArrow.js +14 -6
  26. package/dist/renderPptx/nodes/shape.js +2 -2
  27. package/dist/renderPptx/nodes/table.d.ts.map +1 -1
  28. package/dist/renderPptx/nodes/table.js +1 -1
  29. package/dist/renderPptx/nodes/timeline.d.ts.map +1 -1
  30. package/dist/renderPptx/nodes/timeline.js +58 -37
  31. package/dist/renderPptx/nodes/tree.d.ts.map +1 -1
  32. package/dist/renderPptx/nodes/tree.js +49 -40
  33. package/dist/renderPptx/renderPptx.d.ts.map +1 -1
  34. package/dist/renderPptx/renderPptx.js +8 -2
  35. package/dist/renderPptx/textOptions.d.ts +1 -28
  36. package/dist/renderPptx/textOptions.d.ts.map +1 -1
  37. package/dist/renderPptx/textOptions.js +1 -27
  38. package/dist/renderPptx/utils/backgroundBorder.js +1 -1
  39. package/dist/renderPptx/utils/scaleToFit.d.ts +8 -0
  40. package/dist/renderPptx/utils/scaleToFit.d.ts.map +1 -0
  41. package/dist/renderPptx/utils/scaleToFit.js +19 -0
  42. package/dist/shared/measureImage.d.ts.map +1 -0
  43. package/dist/{table/utils.d.ts → shared/tableUtils.d.ts} +1 -1
  44. package/dist/shared/tableUtils.d.ts.map +1 -0
  45. package/dist/toPositioned/toPositioned.d.ts.map +1 -1
  46. package/dist/toPositioned/toPositioned.js +4 -2
  47. package/dist/types.d.ts +277 -52
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/types.js +48 -8
  50. package/package.json +1 -1
  51. package/dist/calcYogaLayout/measureImage.d.ts.map +0 -1
  52. package/dist/inputSchema.d.ts.map +0 -1
  53. package/dist/parseXml.d.ts.map +0 -1
  54. package/dist/table/utils.d.ts.map +0 -1
  55. /package/dist/{calcYogaLayout → shared}/measureImage.d.ts +0 -0
  56. /package/dist/{calcYogaLayout → shared}/measureImage.js +0 -0
  57. /package/dist/{table/utils.js → shared/tableUtils.js} +0 -0
@@ -0,0 +1,145 @@
1
+ import { pxToIn, pxToPt } from "../units.js";
2
+ import { convertUnderline, convertStrike } from "../textOptions.js";
3
+ function resolveStyle(li, parent) {
4
+ return {
5
+ fontPx: li.fontPx ?? parent.fontPx ?? 24,
6
+ color: li.color ?? parent.color,
7
+ bold: li.bold ?? parent.bold,
8
+ italic: li.italic ?? parent.italic,
9
+ underline: li.underline ?? parent.underline,
10
+ strike: li.strike ?? parent.strike,
11
+ highlight: li.highlight ?? parent.highlight,
12
+ fontFamily: li.fontFamily ?? parent.fontFamily ?? "Noto Sans JP",
13
+ };
14
+ }
15
+ function hasItemStyleOverride(items) {
16
+ return items.some((li) => li.fontPx !== undefined ||
17
+ li.color !== undefined ||
18
+ li.bold !== undefined ||
19
+ li.italic !== undefined ||
20
+ li.underline !== undefined ||
21
+ li.strike !== undefined ||
22
+ li.highlight !== undefined ||
23
+ li.fontFamily !== undefined);
24
+ }
25
+ export function renderUlNode(node, ctx) {
26
+ const fontSizePx = node.fontPx ?? 24;
27
+ const fontFamily = node.fontFamily ?? "Noto Sans JP";
28
+ const lineSpacingMultiple = node.lineSpacingMultiple ?? 1.3;
29
+ if (hasItemStyleOverride(node.items)) {
30
+ // Li に個別スタイルがある場合は配列形式を使用
31
+ const textItems = node.items.map((li, i) => {
32
+ const style = resolveStyle(li, node);
33
+ return {
34
+ text: i < node.items.length - 1 ? li.text + "\n" : li.text,
35
+ options: {
36
+ fontSize: pxToPt(style.fontPx),
37
+ fontFace: style.fontFamily,
38
+ color: style.color,
39
+ bold: style.bold,
40
+ italic: style.italic,
41
+ underline: convertUnderline(style.underline),
42
+ strike: convertStrike(style.strike),
43
+ highlight: style.highlight,
44
+ bullet: true,
45
+ },
46
+ };
47
+ });
48
+ ctx.slide.addText(textItems, {
49
+ x: pxToIn(node.x),
50
+ y: pxToIn(node.y),
51
+ w: pxToIn(node.w),
52
+ h: pxToIn(node.h),
53
+ align: node.alignText ?? "left",
54
+ valign: "top",
55
+ margin: 0,
56
+ lineSpacingMultiple,
57
+ });
58
+ }
59
+ else {
60
+ // Li にスタイルオーバーライドがない場合は単一文字列形式を使用
61
+ const text = node.items.map((li) => li.text).join("\n");
62
+ ctx.slide.addText(text, {
63
+ x: pxToIn(node.x),
64
+ y: pxToIn(node.y),
65
+ w: pxToIn(node.w),
66
+ h: pxToIn(node.h),
67
+ fontSize: pxToPt(fontSizePx),
68
+ fontFace: fontFamily,
69
+ align: node.alignText ?? "left",
70
+ valign: "top",
71
+ margin: 0,
72
+ lineSpacingMultiple,
73
+ color: node.color,
74
+ bold: node.bold,
75
+ italic: node.italic,
76
+ underline: convertUnderline(node.underline),
77
+ strike: convertStrike(node.strike),
78
+ highlight: node.highlight,
79
+ bullet: true,
80
+ });
81
+ }
82
+ }
83
+ export function renderOlNode(node, ctx) {
84
+ const fontSizePx = node.fontPx ?? 24;
85
+ const fontFamily = node.fontFamily ?? "Noto Sans JP";
86
+ const lineSpacingMultiple = node.lineSpacingMultiple ?? 1.3;
87
+ const bulletOptions = { type: "number" };
88
+ if (node.numberType !== undefined) {
89
+ bulletOptions.numberType = node.numberType;
90
+ }
91
+ if (node.numberStartAt !== undefined) {
92
+ bulletOptions.numberStartAt = node.numberStartAt;
93
+ }
94
+ if (hasItemStyleOverride(node.items)) {
95
+ const textItems = node.items.map((li, i) => {
96
+ const style = resolveStyle(li, node);
97
+ return {
98
+ text: i < node.items.length - 1 ? li.text + "\n" : li.text,
99
+ options: {
100
+ fontSize: pxToPt(style.fontPx),
101
+ fontFace: style.fontFamily,
102
+ color: style.color,
103
+ bold: style.bold,
104
+ italic: style.italic,
105
+ underline: convertUnderline(style.underline),
106
+ strike: convertStrike(style.strike),
107
+ highlight: style.highlight,
108
+ bullet: bulletOptions,
109
+ },
110
+ };
111
+ });
112
+ ctx.slide.addText(textItems, {
113
+ x: pxToIn(node.x),
114
+ y: pxToIn(node.y),
115
+ w: pxToIn(node.w),
116
+ h: pxToIn(node.h),
117
+ align: node.alignText ?? "left",
118
+ valign: "top",
119
+ margin: 0,
120
+ lineSpacingMultiple,
121
+ });
122
+ }
123
+ else {
124
+ const text = node.items.map((li) => li.text).join("\n");
125
+ ctx.slide.addText(text, {
126
+ x: pxToIn(node.x),
127
+ y: pxToIn(node.y),
128
+ w: pxToIn(node.w),
129
+ h: pxToIn(node.h),
130
+ fontSize: pxToPt(fontSizePx),
131
+ fontFace: fontFamily,
132
+ align: node.alignText ?? "left",
133
+ valign: "top",
134
+ margin: 0,
135
+ lineSpacingMultiple,
136
+ color: node.color,
137
+ bold: node.bold,
138
+ italic: node.italic,
139
+ underline: convertUnderline(node.underline),
140
+ strike: convertStrike(node.strike),
141
+ highlight: node.highlight,
142
+ bullet: bulletOptions,
143
+ });
144
+ }
145
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/matrix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,KAAK,oBAAoB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAExE,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,aAAa,GACjB,IAAI,CAkHN"}
1
+ {"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/matrix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,KAAK,oBAAoB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAExE,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,aAAa,GACjB,IAAI,CAsIN"}
@@ -1,14 +1,21 @@
1
1
  import { pxToIn, pxToPt } from "../units.js";
2
+ import { measureMatrix } from "../../calcYogaLayout/measureCompositeNodes.js";
3
+ import { calcScaleFactor } from "../utils/scaleToFit.js";
2
4
  export function renderMatrixNode(node, ctx) {
3
5
  const items = node.items;
4
6
  const axes = node.axes;
5
7
  const quadrants = node.quadrants;
6
8
  const defaultItemColor = "1D4ED8"; // blue
7
- const itemSize = 24; // px
8
- const lineWidth = 2; // px
9
+ const baseItemSize = 24; // px
10
+ const baseLineWidth = 2; // px
9
11
  const axisColor = "E2E8F0";
12
+ // スケール係数を計算
13
+ const intrinsic = measureMatrix(node);
14
+ const scaleFactor = calcScaleFactor(node.w, node.h, intrinsic.width, intrinsic.height, "matrix");
15
+ const itemSize = baseItemSize * scaleFactor;
16
+ const lineWidth = baseLineWidth * scaleFactor;
10
17
  // マトリクスの描画領域(パディングを考慮)
11
- const padding = 60; // 軸ラベル用の余白
18
+ const padding = 60 * scaleFactor; // 軸ラベル用の余白
12
19
  const areaX = node.x + padding;
13
20
  const areaY = node.y + padding;
14
21
  const areaW = node.w - padding * 2;
@@ -34,13 +41,15 @@ export function renderMatrixNode(node, ctx) {
34
41
  line: { color: axisColor, width: pxToPt(lineWidth) },
35
42
  });
36
43
  // === 2. 軸ラベルを描画 ===
44
+ const axisLabelW = 120 * scaleFactor;
45
+ const axisLabelH = 24 * scaleFactor;
37
46
  // X軸ラベル(下部中央)
38
47
  ctx.slide.addText(axes.x, {
39
- x: pxToIn(centerX - 60),
40
- y: pxToIn(areaY + areaH + 8),
41
- w: pxToIn(120),
42
- h: pxToIn(24),
43
- fontSize: pxToPt(12),
48
+ x: pxToIn(centerX - axisLabelW / 2),
49
+ y: pxToIn(areaY + areaH + 8 * scaleFactor),
50
+ w: pxToIn(axisLabelW),
51
+ h: pxToIn(axisLabelH),
52
+ fontSize: pxToPt(12 * scaleFactor),
44
53
  fontFace: "Noto Sans JP",
45
54
  color: "64748B",
46
55
  align: "center",
@@ -48,11 +57,11 @@ export function renderMatrixNode(node, ctx) {
48
57
  });
49
58
  // Y軸ラベル(左部中央)
50
59
  ctx.slide.addText(axes.y, {
51
- x: pxToIn(node.x + 4),
52
- y: pxToIn(centerY - 12),
53
- w: pxToIn(48),
54
- h: pxToIn(24),
55
- fontSize: pxToPt(12),
60
+ x: pxToIn(node.x + 4 * scaleFactor),
61
+ y: pxToIn(centerY - 12 * scaleFactor),
62
+ w: pxToIn(48 * scaleFactor),
63
+ h: pxToIn(axisLabelH),
64
+ fontSize: pxToPt(12 * scaleFactor),
56
65
  fontFace: "Noto Sans JP",
57
66
  color: "64748B",
58
67
  align: "center",
@@ -60,9 +69,11 @@ export function renderMatrixNode(node, ctx) {
60
69
  });
61
70
  // === 3. 象限ラベルを描画 ===
62
71
  if (quadrants) {
63
- renderQuadrantLabels(ctx, quadrants, areaX, areaY, areaW, areaH, centerX, centerY);
72
+ renderQuadrantLabels(ctx, quadrants, areaX, areaY, areaW, areaH, centerX, centerY, scaleFactor);
64
73
  }
65
74
  // === 4. アイテムをプロット ===
75
+ const itemLabelW = 100 * scaleFactor;
76
+ const itemLabelH = 18 * scaleFactor;
66
77
  for (const item of items) {
67
78
  // 座標変換: (0,0)=左下, (1,1)=右上
68
79
  // x: 0 -> areaX, 1 -> areaX + areaW
@@ -81,11 +92,11 @@ export function renderMatrixNode(node, ctx) {
81
92
  });
82
93
  // ラベルを描画(円の上)
83
94
  ctx.slide.addText(item.label, {
84
- x: pxToIn(itemX - 50),
85
- y: pxToIn(itemY - itemSize / 2 - 20),
86
- w: pxToIn(100),
87
- h: pxToIn(18),
88
- fontSize: pxToPt(11),
95
+ x: pxToIn(itemX - itemLabelW / 2),
96
+ y: pxToIn(itemY - itemSize / 2 - 20 * scaleFactor),
97
+ w: pxToIn(itemLabelW),
98
+ h: pxToIn(itemLabelH),
99
+ fontSize: pxToPt(11 * scaleFactor),
89
100
  fontFace: "Noto Sans JP",
90
101
  color: "1E293B",
91
102
  bold: true,
@@ -94,15 +105,16 @@ export function renderMatrixNode(node, ctx) {
94
105
  });
95
106
  }
96
107
  }
97
- function renderQuadrantLabels(ctx, quadrants, areaX, areaY, areaW, areaH, centerX, centerY) {
98
- const quadrantFontSize = 11;
108
+ function renderQuadrantLabels(ctx, quadrants, areaX, areaY, areaW, areaH, centerX, centerY, scaleFactor) {
109
+ const quadrantFontSize = 11 * scaleFactor;
99
110
  const quadrantColor = "94A3B8"; // slate-400
100
- const quadrantW = areaW / 2 - 20;
101
- const quadrantH = 48;
111
+ const quadrantInset = 10 * scaleFactor;
112
+ const quadrantW = areaW / 2 - 20 * scaleFactor;
113
+ const quadrantH = 48 * scaleFactor;
102
114
  // 左上
103
115
  ctx.slide.addText(quadrants.topLeft, {
104
- x: pxToIn(areaX + 10),
105
- y: pxToIn(areaY + 10),
116
+ x: pxToIn(areaX + quadrantInset),
117
+ y: pxToIn(areaY + quadrantInset),
106
118
  w: pxToIn(quadrantW),
107
119
  h: pxToIn(quadrantH),
108
120
  fontSize: pxToPt(quadrantFontSize),
@@ -113,8 +125,8 @@ function renderQuadrantLabels(ctx, quadrants, areaX, areaY, areaW, areaH, center
113
125
  });
114
126
  // 右上
115
127
  ctx.slide.addText(quadrants.topRight, {
116
- x: pxToIn(centerX + 10),
117
- y: pxToIn(areaY + 10),
128
+ x: pxToIn(centerX + quadrantInset),
129
+ y: pxToIn(areaY + quadrantInset),
118
130
  w: pxToIn(quadrantW),
119
131
  h: pxToIn(quadrantH),
120
132
  fontSize: pxToPt(quadrantFontSize),
@@ -125,8 +137,8 @@ function renderQuadrantLabels(ctx, quadrants, areaX, areaY, areaW, areaH, center
125
137
  });
126
138
  // 左下
127
139
  ctx.slide.addText(quadrants.bottomLeft, {
128
- x: pxToIn(areaX + 10),
129
- y: pxToIn(centerY + areaH / 2 - quadrantH - 10),
140
+ x: pxToIn(areaX + quadrantInset),
141
+ y: pxToIn(centerY + areaH / 2 - quadrantH - quadrantInset),
130
142
  w: pxToIn(quadrantW),
131
143
  h: pxToIn(quadrantH),
132
144
  fontSize: pxToPt(quadrantFontSize),
@@ -137,8 +149,8 @@ function renderQuadrantLabels(ctx, quadrants, areaX, areaY, areaW, areaH, center
137
149
  });
138
150
  // 右下
139
151
  ctx.slide.addText(quadrants.bottomRight, {
140
- x: pxToIn(centerX + 10),
141
- y: pxToIn(centerY + areaH / 2 - quadrantH - 10),
152
+ x: pxToIn(centerX + quadrantInset),
153
+ y: pxToIn(centerY + areaH / 2 - quadrantH - quadrantInset),
142
154
  w: pxToIn(quadrantW),
143
155
  h: pxToIn(quadrantH),
144
156
  fontSize: pxToPt(quadrantFontSize),
@@ -1 +1 @@
1
- {"version":3,"file":"processArrow.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/processArrow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,KAAK,0BAA0B,GAAG,OAAO,CACvC,cAAc,EACd;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CACzB,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,0BAA0B,EAChC,GAAG,EAAE,aAAa,GACjB,IAAI,CAsCN"}
1
+ {"version":3,"file":"processArrow.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/processArrow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,KAAK,0BAA0B,GAAG,OAAO,CACvC,cAAc,EACd;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CACzB,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,0BAA0B,EAChC,GAAG,EAAE,aAAa,GACjB,IAAI,CAsDN"}
@@ -1,5 +1,7 @@
1
1
  import { pxToIn, pxToPt } from "../units.js";
2
2
  import { convertUnderline, convertStrike } from "../textOptions.js";
3
+ import { measureProcessArrow } from "../../calcYogaLayout/measureCompositeNodes.js";
4
+ import { calcScaleFactor } from "../utils/scaleToFit.js";
3
5
  export function renderProcessArrowNode(node, ctx) {
4
6
  const direction = node.direction ?? "horizontal";
5
7
  const steps = node.steps;
@@ -11,14 +13,20 @@ export function renderProcessArrowNode(node, ctx) {
11
13
  const itemWidth = node.itemWidth ?? 150;
12
14
  const itemHeight = node.itemHeight ?? 60;
13
15
  const gap = node.gap ?? -15; // 負の値でシェブロンを重ねる
16
+ // スケール係数を計算
17
+ const intrinsic = measureProcessArrow(node);
18
+ const scaleFactor = calcScaleFactor(node.w, node.h, intrinsic.width, intrinsic.height, "processArrow");
19
+ const scaledItemWidth = itemWidth * scaleFactor;
20
+ const scaledItemHeight = itemHeight * scaleFactor;
21
+ const scaledGap = gap * scaleFactor;
14
22
  if (direction === "horizontal") {
15
- renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, defaultColor, defaultTextColor);
23
+ renderHorizontalProcessArrow(node, ctx, steps, stepCount, scaledItemWidth, scaledItemHeight, scaledGap, defaultColor, defaultTextColor, scaleFactor);
16
24
  }
17
25
  else {
18
- renderVerticalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, defaultColor, defaultTextColor);
26
+ renderVerticalProcessArrow(node, ctx, steps, stepCount, scaledItemWidth, scaledItemHeight, scaledGap, defaultColor, defaultTextColor, scaleFactor);
19
27
  }
20
28
  }
21
- function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, defaultColor, defaultTextColor) {
29
+ function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, defaultColor, defaultTextColor, scaleFactor) {
22
30
  const totalWidth = stepCount * itemWidth + (stepCount - 1) * gap;
23
31
  const startX = node.x + (node.w - totalWidth) / 2;
24
32
  const centerY = node.y + node.h / 2;
@@ -37,7 +45,7 @@ function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, it
37
45
  shape: shapeType,
38
46
  fill: { color: fillColor },
39
47
  line: { type: "none" },
40
- fontSize: pxToPt(node.fontPx ?? 14),
48
+ fontSize: pxToPt((node.fontPx ?? 14) * scaleFactor),
41
49
  fontFace: "Noto Sans JP",
42
50
  color: textColor,
43
51
  bold: node.bold ?? false,
@@ -50,7 +58,7 @@ function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, it
50
58
  });
51
59
  });
52
60
  }
53
- function renderVerticalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, defaultColor, defaultTextColor) {
61
+ function renderVerticalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, defaultColor, defaultTextColor, scaleFactor) {
54
62
  const totalHeight = stepCount * itemHeight + (stepCount - 1) * gap;
55
63
  const startY = node.y + (node.h - totalHeight) / 2;
56
64
  const centerX = node.x + node.w / 2;
@@ -69,7 +77,7 @@ function renderVerticalProcessArrow(node, ctx, steps, stepCount, itemWidth, item
69
77
  shape: shapeType,
70
78
  fill: { color: fillColor },
71
79
  line: { type: "none" },
72
- fontSize: pxToPt(node.fontPx ?? 14),
80
+ fontSize: pxToPt((node.fontPx ?? 14) * scaleFactor),
73
81
  fontFace: "Noto Sans JP",
74
82
  color: textColor,
75
83
  bold: node.bold ?? false,
@@ -36,7 +36,7 @@ export function renderShapeNode(node, ctx) {
36
36
  ...shapeOptions,
37
37
  shape: node.shapeType,
38
38
  fontSize: pxToPt(node.fontPx ?? 24),
39
- fontFace: "Noto Sans JP",
39
+ fontFace: node.fontFamily ?? "Noto Sans JP",
40
40
  color: node.color,
41
41
  bold: node.bold,
42
42
  italic: node.italic,
@@ -45,7 +45,7 @@ export function renderShapeNode(node, ctx) {
45
45
  highlight: node.highlight,
46
46
  align: node.alignText ?? "center",
47
47
  valign: "middle",
48
- lineSpacingMultiple: 1.3,
48
+ lineSpacingMultiple: node.lineSpacingMultiple ?? 1.3,
49
49
  });
50
50
  }
51
51
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,KAAK,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEtE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,aAAa,GACjB,IAAI,CAmCN"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQjD,KAAK,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEtE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,aAAa,GACjB,IAAI,CAmCN"}
@@ -1,4 +1,4 @@
1
- import { resolveColumnWidths, resolveRowHeights } from "../../table/utils.js";
1
+ import { resolveColumnWidths, resolveRowHeights, } from "../../shared/tableUtils.js";
2
2
  import { pxToIn, pxToPt } from "../units.js";
3
3
  import { convertUnderline, convertStrike } from "../textOptions.js";
4
4
  export function renderTableNode(node, ctx) {
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/timeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,KAAK,sBAAsB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAE5E,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,sBAAsB,EAC5B,GAAG,EAAE,aAAa,GACjB,IAAI,CA8BN"}
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/timeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,KAAK,sBAAsB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAE5E,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,sBAAsB,EAC5B,GAAG,EAAE,aAAa,GACjB,IAAI,CA6CN"}
@@ -1,4 +1,6 @@
1
1
  import { pxToIn, pxToPt } from "../units.js";
2
+ import { measureTimeline } from "../../calcYogaLayout/measureCompositeNodes.js";
3
+ import { calcScaleFactor } from "../utils/scaleToFit.js";
2
4
  export function renderTimelineNode(node, ctx) {
3
5
  const direction = node.direction ?? "horizontal";
4
6
  const items = node.items;
@@ -6,16 +8,21 @@ export function renderTimelineNode(node, ctx) {
6
8
  if (itemCount === 0)
7
9
  return;
8
10
  const defaultColor = "1D4ED8"; // blue
9
- const nodeRadius = 12; // px
10
- const lineWidth = 4; // px
11
+ const baseNodeRadius = 12; // px
12
+ const baseLineWidth = 4; // px
13
+ // スケール係数を計算
14
+ const intrinsic = measureTimeline(node);
15
+ const scaleFactor = calcScaleFactor(node.w, node.h, intrinsic.width, intrinsic.height, "timeline");
16
+ const nodeRadius = baseNodeRadius * scaleFactor;
17
+ const lineWidth = baseLineWidth * scaleFactor;
11
18
  if (direction === "horizontal") {
12
- renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, lineWidth);
19
+ renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, lineWidth, scaleFactor);
13
20
  }
14
21
  else {
15
- renderVerticalTimeline(node, ctx, items, defaultColor, nodeRadius, lineWidth);
22
+ renderVerticalTimeline(node, ctx, items, defaultColor, nodeRadius, lineWidth, scaleFactor);
16
23
  }
17
24
  }
18
- function renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, lineWidth) {
25
+ function renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, lineWidth, scaleFactor) {
19
26
  const itemCount = items.length;
20
27
  const lineY = node.y + node.h / 2;
21
28
  const startX = node.x + nodeRadius;
@@ -29,6 +36,13 @@ function renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, li
29
36
  h: 0,
30
37
  line: { color: "E2E8F0", width: pxToPt(lineWidth) },
31
38
  });
39
+ const labelW = 120 * scaleFactor;
40
+ const dateLabelH = 24 * scaleFactor;
41
+ const titleLabelH = 24 * scaleFactor;
42
+ const descLabelH = 32 * scaleFactor;
43
+ const dateOffset = 40 * scaleFactor;
44
+ const titleGap = 8 * scaleFactor;
45
+ const descOffset = 32 * scaleFactor;
32
46
  // 各アイテムを描画
33
47
  items.forEach((item, index) => {
34
48
  const progress = itemCount === 1 ? 0.5 : index / (itemCount - 1);
@@ -46,11 +60,11 @@ function renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, li
46
60
  });
47
61
  // 日付を上に表示
48
62
  ctx.slide.addText(item.date, {
49
- x: pxToIn(cx - 60),
50
- y: pxToIn(cy - nodeRadius - 40),
51
- w: pxToIn(120),
52
- h: pxToIn(24),
53
- fontSize: pxToPt(12),
63
+ x: pxToIn(cx - labelW / 2),
64
+ y: pxToIn(cy - nodeRadius - dateOffset),
65
+ w: pxToIn(labelW),
66
+ h: pxToIn(dateLabelH),
67
+ fontSize: pxToPt(12 * scaleFactor),
54
68
  fontFace: "Noto Sans JP",
55
69
  color: "64748B",
56
70
  align: "center",
@@ -58,11 +72,11 @@ function renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, li
58
72
  });
59
73
  // タイトルを下に表示
60
74
  ctx.slide.addText(item.title, {
61
- x: pxToIn(cx - 60),
62
- y: pxToIn(cy + nodeRadius + 8),
63
- w: pxToIn(120),
64
- h: pxToIn(24),
65
- fontSize: pxToPt(14),
75
+ x: pxToIn(cx - labelW / 2),
76
+ y: pxToIn(cy + nodeRadius + titleGap),
77
+ w: pxToIn(labelW),
78
+ h: pxToIn(titleLabelH),
79
+ fontSize: pxToPt(14 * scaleFactor),
66
80
  fontFace: "Noto Sans JP",
67
81
  color: "1E293B",
68
82
  bold: true,
@@ -72,11 +86,11 @@ function renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, li
72
86
  // 説明を表示
73
87
  if (item.description) {
74
88
  ctx.slide.addText(item.description, {
75
- x: pxToIn(cx - 60),
76
- y: pxToIn(cy + nodeRadius + 32),
77
- w: pxToIn(120),
78
- h: pxToIn(32),
79
- fontSize: pxToPt(11),
89
+ x: pxToIn(cx - labelW / 2),
90
+ y: pxToIn(cy + nodeRadius + descOffset),
91
+ w: pxToIn(labelW),
92
+ h: pxToIn(descLabelH),
93
+ fontSize: pxToPt(11 * scaleFactor),
80
94
  fontFace: "Noto Sans JP",
81
95
  color: "64748B",
82
96
  align: "center",
@@ -85,9 +99,9 @@ function renderHorizontalTimeline(node, ctx, items, defaultColor, nodeRadius, li
85
99
  }
86
100
  });
87
101
  }
88
- function renderVerticalTimeline(node, ctx, items, defaultColor, nodeRadius, lineWidth) {
102
+ function renderVerticalTimeline(node, ctx, items, defaultColor, nodeRadius, lineWidth, scaleFactor) {
89
103
  const itemCount = items.length;
90
- const lineX = node.x + 40;
104
+ const lineX = node.x + 40 * scaleFactor;
91
105
  const startY = node.y + nodeRadius;
92
106
  const endY = node.y + node.h - nodeRadius;
93
107
  const lineLength = endY - startY;
@@ -99,6 +113,13 @@ function renderVerticalTimeline(node, ctx, items, defaultColor, nodeRadius, line
99
113
  h: pxToIn(lineLength),
100
114
  line: { color: "E2E8F0", width: pxToPt(lineWidth) },
101
115
  });
116
+ const labelGap = 16 * scaleFactor;
117
+ const dateLabelW = 100 * scaleFactor;
118
+ const dateLabelH = 20 * scaleFactor;
119
+ const titleLabelH = 24 * scaleFactor;
120
+ const descLabelH = 32 * scaleFactor;
121
+ const titleLabelW = node.w - 80 * scaleFactor;
122
+ const descLabelW = node.w - 80 * scaleFactor;
102
123
  // 各アイテムを描画
103
124
  items.forEach((item, index) => {
104
125
  const progress = itemCount === 1 ? 0.5 : index / (itemCount - 1);
@@ -116,11 +137,11 @@ function renderVerticalTimeline(node, ctx, items, defaultColor, nodeRadius, line
116
137
  });
117
138
  // 日付を左上に表示
118
139
  ctx.slide.addText(item.date, {
119
- x: pxToIn(cx + nodeRadius + 16),
120
- y: pxToIn(cy - nodeRadius - 4),
121
- w: pxToIn(100),
122
- h: pxToIn(20),
123
- fontSize: pxToPt(12),
140
+ x: pxToIn(cx + nodeRadius + labelGap),
141
+ y: pxToIn(cy - nodeRadius - 4 * scaleFactor),
142
+ w: pxToIn(dateLabelW),
143
+ h: pxToIn(dateLabelH),
144
+ fontSize: pxToPt(12 * scaleFactor),
124
145
  fontFace: "Noto Sans JP",
125
146
  color: "64748B",
126
147
  align: "left",
@@ -128,11 +149,11 @@ function renderVerticalTimeline(node, ctx, items, defaultColor, nodeRadius, line
128
149
  });
129
150
  // タイトルを右に表示
130
151
  ctx.slide.addText(item.title, {
131
- x: pxToIn(cx + nodeRadius + 16),
132
- y: pxToIn(cy - 4),
133
- w: pxToIn(node.w - 80),
134
- h: pxToIn(24),
135
- fontSize: pxToPt(14),
152
+ x: pxToIn(cx + nodeRadius + labelGap),
153
+ y: pxToIn(cy - 4 * scaleFactor),
154
+ w: pxToIn(titleLabelW),
155
+ h: pxToIn(titleLabelH),
156
+ fontSize: pxToPt(14 * scaleFactor),
136
157
  fontFace: "Noto Sans JP",
137
158
  color: "1E293B",
138
159
  bold: true,
@@ -142,11 +163,11 @@ function renderVerticalTimeline(node, ctx, items, defaultColor, nodeRadius, line
142
163
  // 説明を表示
143
164
  if (item.description) {
144
165
  ctx.slide.addText(item.description, {
145
- x: pxToIn(cx + nodeRadius + 16),
146
- y: pxToIn(cy + 20),
147
- w: pxToIn(node.w - 80),
148
- h: pxToIn(32),
149
- fontSize: pxToPt(11),
166
+ x: pxToIn(cx + nodeRadius + labelGap),
167
+ y: pxToIn(cy + 20 * scaleFactor),
168
+ w: pxToIn(descLabelW),
169
+ h: pxToIn(descLabelH),
170
+ fontSize: pxToPt(11 * scaleFactor),
150
171
  fontFace: "Noto Sans JP",
151
172
  color: "64748B",
152
173
  align: "left",
@@ -1 +1 @@
1
- {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,KAAK,kBAAkB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAWpE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,kBAAkB,EACxB,GAAG,EAAE,aAAa,GACjB,IAAI,CAwQN"}
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,KAAK,kBAAkB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAWpE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,kBAAkB,EACxB,GAAG,EAAE,aAAa,GACjB,IAAI,CAwSN"}