ngwr 14.2.0 → 14.3.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 (120) hide show
  1. package/README.md +23 -22
  2. package/fesm2022/ngwr-calendar.mjs +4 -2
  3. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  4. package/fesm2022/ngwr-event-calendar.mjs +17 -5
  5. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  6. package/fesm2022/ngwr-form.mjs +30 -1
  7. package/fesm2022/ngwr-form.mjs.map +1 -1
  8. package/fesm2022/ngwr-i18n-ar.mjs +429 -0
  9. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -0
  10. package/fesm2022/ngwr-i18n-cs.mjs +399 -0
  11. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -0
  12. package/fesm2022/ngwr-i18n-de.mjs +418 -0
  13. package/fesm2022/ngwr-i18n-de.mjs.map +1 -0
  14. package/fesm2022/ngwr-i18n-en.mjs +23 -0
  15. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  16. package/fesm2022/ngwr-i18n-es.mjs +399 -0
  17. package/fesm2022/ngwr-i18n-es.mjs.map +1 -0
  18. package/fesm2022/ngwr-i18n-fr.mjs +423 -0
  19. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -0
  20. package/fesm2022/ngwr-i18n-he.mjs +422 -0
  21. package/fesm2022/ngwr-i18n-he.mjs.map +1 -0
  22. package/fesm2022/ngwr-i18n-hi.mjs +399 -0
  23. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -0
  24. package/fesm2022/ngwr-i18n-id.mjs +399 -0
  25. package/fesm2022/ngwr-i18n-id.mjs.map +1 -0
  26. package/fesm2022/ngwr-i18n-it.mjs +418 -0
  27. package/fesm2022/ngwr-i18n-it.mjs.map +1 -0
  28. package/fesm2022/ngwr-i18n-ja.mjs +403 -0
  29. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -0
  30. package/fesm2022/ngwr-i18n-ko.mjs +411 -0
  31. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -0
  32. package/fesm2022/ngwr-i18n-nl.mjs +415 -0
  33. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -0
  34. package/fesm2022/ngwr-i18n-pl.mjs +425 -0
  35. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -0
  36. package/fesm2022/ngwr-i18n-pt.mjs +408 -0
  37. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -0
  38. package/fesm2022/ngwr-i18n-ru.mjs +11 -0
  39. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  40. package/fesm2022/ngwr-i18n-sv.mjs +399 -0
  41. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -0
  42. package/fesm2022/ngwr-i18n-tr.mjs +423 -0
  43. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -0
  44. package/fesm2022/ngwr-i18n-uk.mjs +420 -0
  45. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -0
  46. package/fesm2022/ngwr-i18n-vi.mjs +416 -0
  47. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -0
  48. package/fesm2022/ngwr-i18n-zh-TW.mjs +407 -0
  49. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -0
  50. package/fesm2022/ngwr-i18n-zh.mjs +398 -0
  51. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -0
  52. package/fesm2022/ngwr-line-chart.mjs +24 -4
  53. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  54. package/fesm2022/ngwr-pipes.mjs +75 -10
  55. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  56. package/fesm2022/ngwr-schema-form.mjs +185 -0
  57. package/fesm2022/ngwr-schema-form.mjs.map +1 -0
  58. package/fesm2022/ngwr-select.mjs +2 -2
  59. package/fesm2022/ngwr-select.mjs.map +1 -1
  60. package/fesm2022/ngwr-validators.mjs +8 -1
  61. package/fesm2022/ngwr-validators.mjs.map +1 -1
  62. package/fesm2022/ngwr-version.mjs +1 -1
  63. package/fesm2022/ngwr-version.mjs.map +1 -1
  64. package/i18n/ar.json +389 -0
  65. package/i18n/cs.json +389 -0
  66. package/i18n/de.json +389 -0
  67. package/i18n/en.json +10 -2
  68. package/i18n/es.json +389 -0
  69. package/i18n/fr.json +389 -0
  70. package/i18n/he.json +389 -0
  71. package/i18n/hi.json +389 -0
  72. package/i18n/id.json +389 -0
  73. package/i18n/it.json +389 -0
  74. package/i18n/ja.json +389 -0
  75. package/i18n/ko.json +389 -0
  76. package/i18n/nl.json +389 -0
  77. package/i18n/pl.json +389 -0
  78. package/i18n/pt.json +389 -0
  79. package/i18n/ru.json +10 -2
  80. package/i18n/sv.json +389 -0
  81. package/i18n/tr.json +389 -0
  82. package/i18n/uk.json +389 -0
  83. package/i18n/vi.json +389 -0
  84. package/i18n/zh-TW.json +389 -0
  85. package/i18n/zh.json +389 -0
  86. package/llms-full.txt +87 -1
  87. package/llms.txt +1 -1
  88. package/package.json +89 -7
  89. package/schema-form/styles/_index.scss +15 -0
  90. package/schematics/use/symbol-map.json +1 -0
  91. package/skills/ngwr/SKILL.md +1 -1
  92. package/skills/ngwr/references/catalog.md +21 -0
  93. package/styles.scss +1 -0
  94. package/types/ngwr-calendar.d.ts +2 -0
  95. package/types/ngwr-event-calendar.d.ts +5 -0
  96. package/types/ngwr-form.d.ts +88 -2
  97. package/types/ngwr-i18n-ar.d.ts +6 -0
  98. package/types/ngwr-i18n-cs.d.ts +6 -0
  99. package/types/ngwr-i18n-de.d.ts +6 -0
  100. package/types/ngwr-i18n-es.d.ts +6 -0
  101. package/types/ngwr-i18n-fr.d.ts +6 -0
  102. package/types/ngwr-i18n-he.d.ts +6 -0
  103. package/types/ngwr-i18n-hi.d.ts +6 -0
  104. package/types/ngwr-i18n-id.d.ts +6 -0
  105. package/types/ngwr-i18n-it.d.ts +6 -0
  106. package/types/ngwr-i18n-ja.d.ts +6 -0
  107. package/types/ngwr-i18n-ko.d.ts +6 -0
  108. package/types/ngwr-i18n-nl.d.ts +6 -0
  109. package/types/ngwr-i18n-pl.d.ts +6 -0
  110. package/types/ngwr-i18n-pt.d.ts +6 -0
  111. package/types/ngwr-i18n-sv.d.ts +6 -0
  112. package/types/ngwr-i18n-tr.d.ts +6 -0
  113. package/types/ngwr-i18n-uk.d.ts +6 -0
  114. package/types/ngwr-i18n-vi.d.ts +6 -0
  115. package/types/ngwr-i18n-zh-TW.d.ts +6 -0
  116. package/types/ngwr-i18n-zh.d.ts +6 -0
  117. package/types/ngwr-line-chart.d.ts +15 -0
  118. package/types/ngwr-pipes.d.ts +45 -4
  119. package/types/ngwr-schema-form.d.ts +90 -0
  120. package/types/ngwr-version.d.ts +1 -1
@@ -0,0 +1,398 @@
1
+ /** Base Simplified Chinese catalog for ngwr built-in component strings. */
2
+ const wrZh = {
3
+ common: {
4
+ ok: '确定',
5
+ cancel: '取消',
6
+ close: '关闭',
7
+ confirm: '确认',
8
+ delete: '删除',
9
+ save: '保存',
10
+ edit: '编辑',
11
+ add: '添加',
12
+ remove: '移除',
13
+ clear: '清除',
14
+ search: '搜索',
15
+ loading: '加载中…',
16
+ select: '选择',
17
+ next: '下一步',
18
+ previous: '上一步',
19
+ back: '返回',
20
+ today: '今天',
21
+ yesterday: '昨天',
22
+ tomorrow: '明天',
23
+ of: '共',
24
+ },
25
+ pagination: {
26
+ prev: '上一页',
27
+ next: '下一页',
28
+ itemsPerPage: '每页条数',
29
+ perPage: '{{size}} 条/页',
30
+ goToPage: '跳转到第 {{page}} 页',
31
+ label: '分页',
32
+ pageOf: '第 {{current}} 页,共 {{total}} 页',
33
+ range: '{{from}}–{{to}},共 {{total}} 条',
34
+ compact: '{{current}} / {{total}}',
35
+ },
36
+ table: {
37
+ empty: '暂无数据',
38
+ loading: '加载中…',
39
+ sort: '对此列排序',
40
+ filter: '筛选此列',
41
+ selectAll: '选择所有行',
42
+ selectRow: '选择行',
43
+ expandRow: '展开或收起行详情',
44
+ toggleRow: '展开或收起子行',
45
+ selectGroup: '选择分组',
46
+ toggleGroup: '展开或收起分组',
47
+ noMatches: '无匹配结果',
48
+ search: '搜索',
49
+ reset: '重置',
50
+ },
51
+ eventCalendar: {
52
+ today: '今天',
53
+ previous: '上一个',
54
+ next: '下一个',
55
+ month: '月',
56
+ week: '周',
57
+ day: '日',
58
+ time: '时间',
59
+ allDay: '全天',
60
+ label: '日历',
61
+ more: '+{{count}} 项',
62
+ header: '{{year}}年{{month}}',
63
+ range: '{{from}} – {{to}}',
64
+ chipLabel: '{{title}},{{time}}',
65
+ slotLabel: '{{date}} {{time}}',
66
+ allDayCellLabel: '{{date}} {{label}}',
67
+ },
68
+ tour: {
69
+ next: '下一步',
70
+ back: '上一步',
71
+ done: '完成',
72
+ skip: '跳过引导',
73
+ progress: '第 {{current}} 步,共 {{total}} 步',
74
+ },
75
+ splitter: {
76
+ divider: '调整面板大小',
77
+ },
78
+ stepper: {
79
+ optional: '可选',
80
+ },
81
+ transfer: {
82
+ source: '待选',
83
+ target: '已选',
84
+ search: '搜索',
85
+ empty: '暂无内容',
86
+ selectAll: '全选',
87
+ toTarget: '移至已选',
88
+ toSource: '移回待选',
89
+ count: '{{checked}} / {{total}}',
90
+ },
91
+ form: {
92
+ optional: '选填',
93
+ },
94
+ validation: {
95
+ required: '此项为必填项。',
96
+ requiredTrue: '请勾选此项。',
97
+ email: '请输入有效的电子邮箱地址。',
98
+ minlength: '请至少输入 {{requiredLength}} 个字符。',
99
+ maxlength: '最多可输入 {{requiredLength}} 个字符。',
100
+ min: '请输入不小于 {{min}} 的值。',
101
+ max: '请输入不大于 {{max}} 的值。',
102
+ pattern: '此值的格式不正确。',
103
+ noWhitespace: '此值不能包含空格。',
104
+ hexColor: '请输入十六进制颜色值,例如 #1a2b3c。',
105
+ url: '请输入有效的网址。',
106
+ cardNumber: '请输入有效的卡号。',
107
+ cvc: '请输入 {{length}} 位安全码。',
108
+ iban: '请输入有效的 IBAN。',
109
+ match: '两个值不一致。',
110
+ matchFields: '这些字段的值不一致。',
111
+ oneOf: '请从允许的值中选择。',
112
+ minDate: '请选择更晚的日期。',
113
+ maxDate: '请选择更早的日期。',
114
+ },
115
+ select: {
116
+ label: '选择',
117
+ placeholder: '请选择',
118
+ empty: '暂无选项',
119
+ clearSelection: '清除选择',
120
+ removeItem: '移除 {{label}}',
121
+ noResults: '无搜索结果',
122
+ loading: '加载中…',
123
+ more: '+{{count}} 项',
124
+ },
125
+ tree: {
126
+ expand: '展开',
127
+ collapse: '收起',
128
+ placeholder: '请选择',
129
+ clearSelection: '清除选择',
130
+ removeItem: '移除 {{label}}',
131
+ more: '+{{count}} 项',
132
+ },
133
+ commandPalette: {
134
+ label: '命令面板',
135
+ placeholder: '输入命令或搜索…',
136
+ noResults: '无搜索结果',
137
+ loading: '搜索中…',
138
+ escHint: 'esc',
139
+ },
140
+ empty: {
141
+ noData: '暂无数据',
142
+ },
143
+ fileUpload: {
144
+ browse: '点击选择文件',
145
+ dropZone: '或将文件拖放到此处',
146
+ dropZoneLabel: '文件拖放区域,点击或拖放文件',
147
+ removeFile: '移除文件',
148
+ invalid: '不支持的文件类型',
149
+ tooBig: '文件过大',
150
+ size: '{{value}} {{unit}}',
151
+ unitByte: 'B',
152
+ unitKb: 'KB',
153
+ unitMb: 'MB',
154
+ unitGb: 'GB',
155
+ unitTb: 'TB',
156
+ },
157
+ popconfirm: {
158
+ label: '确认操作',
159
+ confirm: '确认',
160
+ cancel: '取消',
161
+ },
162
+ toast: {
163
+ region: '通知',
164
+ close: '关闭',
165
+ copy: '复制',
166
+ copied: '已复制',
167
+ closeAll: '全部关闭',
168
+ },
169
+ input: {
170
+ showPassword: '显示密码',
171
+ hidePassword: '隐藏密码',
172
+ },
173
+ inputNumber: {
174
+ increment: '增加',
175
+ decrement: '减少',
176
+ },
177
+ inputOtp: {
178
+ label: '验证码',
179
+ digit: '第 {{index}} 位数字',
180
+ character: '第 {{index}} 个字符',
181
+ },
182
+ anchor: {
183
+ label: '目录',
184
+ },
185
+ avatar: {
186
+ alt: '头像',
187
+ },
188
+ backTop: {
189
+ label: '返回顶部',
190
+ },
191
+ breadcrumbs: {
192
+ label: '面包屑导航',
193
+ },
194
+ burger: {
195
+ label: '打开或关闭菜单',
196
+ },
197
+ calendar: {
198
+ prevMonth: '上个月',
199
+ nextMonth: '下个月',
200
+ prevYear: '上一年',
201
+ nextYear: '下一年',
202
+ monthList: '月份',
203
+ yearList: '年份',
204
+ prevYears: '前 12 年',
205
+ nextYears: '后 12 年',
206
+ header: '{{year}}年{{month}}',
207
+ yearRange: '{{from}} – {{to}}',
208
+ dayLabel: '{{date}} {{weekday}}',
209
+ },
210
+ imageCropper: {
211
+ empty: '暂无图片',
212
+ window: '裁剪区域',
213
+ keyHelp: '方向键移动裁剪框。按住 Alt 加方向键可调整大小,按住 Shift 可加大步长。' +
214
+ '裁剪框会以图像像素为单位,依次朗读左、上、宽、高四个值。',
215
+ },
216
+ sortableList: {
217
+ keyHelp: '按空格键拿起此项,然后用方向键移动。再次按空格键放下,或按 Esc 键放回原位。',
218
+ grabbed: '已拿起。第 {{index}} 项,共 {{total}} 项。',
219
+ moved: '第 {{index}} 项,共 {{total}} 项。',
220
+ dropped: '已放下。第 {{index}} 项,共 {{total}} 项。',
221
+ cancelled: '已取消移动。',
222
+ },
223
+ colorPicker: {
224
+ area: '饱和度 {{saturation}}%,明度 {{brightness}}%',
225
+ hue: '色相',
226
+ alpha: '不透明度',
227
+ formatHex: 'HEX',
228
+ formatRgb: 'RGB',
229
+ formatHsl: 'HSL',
230
+ channelHex: 'HEX',
231
+ channelRed: 'R',
232
+ channelGreen: 'G',
233
+ channelBlue: 'B',
234
+ channelHue: 'H',
235
+ channelSaturation: 'S%',
236
+ channelLightness: 'L%',
237
+ channelAlpha: 'A%',
238
+ },
239
+ calendarHeatmap: {
240
+ label: '日历热力图',
241
+ },
242
+ lineChart: {
243
+ label: '折线图',
244
+ thousands: '{{value}}千',
245
+ },
246
+ donutChart: {
247
+ label: '环形图',
248
+ },
249
+ compare: {
250
+ label: '对比分隔条',
251
+ },
252
+ carousel: {
253
+ label: '轮播图',
254
+ goToSlide: '转到第 {{index}} 张幻灯片',
255
+ prev: '上一张幻灯片',
256
+ next: '下一张幻灯片',
257
+ pagination: '轮播分页',
258
+ roledescription: '轮播图',
259
+ slideRoledescription: '幻灯片',
260
+ },
261
+ actionSheet: {
262
+ label: '操作',
263
+ },
264
+ alert: {
265
+ close: '关闭提示',
266
+ },
267
+ qr: {
268
+ label: '二维码',
269
+ },
270
+ image: {
271
+ viewer: '图片预览',
272
+ open: '打开预览',
273
+ close: '关闭预览',
274
+ },
275
+ window: {
276
+ close: '关闭',
277
+ minimize: '最小化',
278
+ maximize: '最大化',
279
+ restore: '还原',
280
+ restoreDown: '向下还原',
281
+ restoreWindow: '还原 {{title}}',
282
+ closeWindow: '关闭窗口',
283
+ untitled: '无标题',
284
+ taskbar: '已最小化的窗口',
285
+ },
286
+ dialog: {
287
+ close: '关闭对话框',
288
+ },
289
+ popover: {
290
+ label: '弹出面板',
291
+ },
292
+ markdown: {
293
+ copy: '复制代码',
294
+ copied: '已复制',
295
+ taskDone: '已完成:',
296
+ taskTodo: '待办:',
297
+ },
298
+ marquee: {
299
+ label: '跑马灯',
300
+ link: '链接',
301
+ },
302
+ mention: {
303
+ listbox: '提及',
304
+ available: '匹配项:{{count}}',
305
+ inserted: '已插入:{{label}}',
306
+ },
307
+ drawer: {
308
+ close: '关闭抽屉',
309
+ },
310
+ datePicker: {
311
+ open: '打开日历',
312
+ openTime: '打开时间选择器',
313
+ openDateTime: '打开日期时间选择器',
314
+ openRange: '打开日期范围日历',
315
+ panel: '选择日期',
316
+ panelTime: '选择时间',
317
+ panelDateTime: '选择日期和时间',
318
+ panelRange: '选择日期范围',
319
+ panelRangeDateTime: '选择日期和时间范围',
320
+ rangeStart: '起始日期',
321
+ rangeEnd: '结束日期',
322
+ startTime: '开始时间',
323
+ endTime: '结束时间',
324
+ hours: '小时',
325
+ minutes: '分钟',
326
+ seconds: '秒',
327
+ incrementHours: '增加小时',
328
+ decrementHours: '减少小时',
329
+ incrementMinutes: '增加分钟',
330
+ decrementMinutes: '减少分钟',
331
+ incrementSeconds: '增加秒',
332
+ decrementSeconds: '减少秒',
333
+ toggleAmPm: '切换上午/下午',
334
+ am: '上午',
335
+ pm: '下午',
336
+ },
337
+ sidebar: {
338
+ label: '侧边栏',
339
+ },
340
+ spinner: {
341
+ label: '加载中',
342
+ },
343
+ rating: {
344
+ label: '评分',
345
+ },
346
+ gauge: {
347
+ label: '仪表盘',
348
+ },
349
+ progress: {
350
+ label: '进度',
351
+ },
352
+ meterGroup: {
353
+ label: '计量条',
354
+ },
355
+ knob: {
356
+ label: '数值',
357
+ },
358
+ slider: {
359
+ label: '数值',
360
+ lower: '下限值',
361
+ upper: '上限值',
362
+ },
363
+ speedDial: {
364
+ label: '操作',
365
+ },
366
+ statistic: {
367
+ delta: '{{value}}{{suffix}}',
368
+ deltaSuffix: '%',
369
+ },
370
+ result: {
371
+ notFound: '抱歉,您访问的页面不存在。',
372
+ forbidden: '抱歉,您无权访问此页面。',
373
+ serverError: '抱歉,出错了。',
374
+ },
375
+ date: {
376
+ months: {
377
+ jan: '一月',
378
+ feb: '二月',
379
+ mar: '三月',
380
+ apr: '四月',
381
+ may: '五月',
382
+ jun: '六月',
383
+ jul: '七月',
384
+ aug: '八月',
385
+ sep: '九月',
386
+ oct: '十月',
387
+ nov: '十一月',
388
+ dec: '十二月',
389
+ },
390
+ },
391
+ };
392
+
393
+ /**
394
+ * Generated bundle index. Do not edit.
395
+ */
396
+
397
+ export { wrZh };
398
+ //# sourceMappingURL=ngwr-i18n-zh.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngwr-i18n-zh.mjs","sources":["../../../projects/lib/i18n/zh/public-api.ts","../../../projects/lib/i18n/zh/ngwr-i18n-zh.ts"],"sourcesContent":["import { type WrI18nCatalog } from 'ngwr/i18n';\n\n/** Base Simplified Chinese catalog for ngwr built-in component strings. */\nexport const wrZh: WrI18nCatalog = {\n common: {\n ok: '确定',\n cancel: '取消',\n close: '关闭',\n confirm: '确认',\n delete: '删除',\n save: '保存',\n edit: '编辑',\n add: '添加',\n remove: '移除',\n clear: '清除',\n search: '搜索',\n loading: '加载中…',\n select: '选择',\n next: '下一步',\n previous: '上一步',\n back: '返回',\n today: '今天',\n yesterday: '昨天',\n tomorrow: '明天',\n of: '共',\n },\n pagination: {\n prev: '上一页',\n next: '下一页',\n itemsPerPage: '每页条数',\n perPage: '{{size}} 条/页',\n goToPage: '跳转到第 {{page}} 页',\n label: '分页',\n pageOf: '第 {{current}} 页,共 {{total}} 页',\n range: '{{from}}–{{to}},共 {{total}} 条',\n compact: '{{current}} / {{total}}',\n },\n table: {\n empty: '暂无数据',\n loading: '加载中…',\n sort: '对此列排序',\n filter: '筛选此列',\n selectAll: '选择所有行',\n selectRow: '选择行',\n expandRow: '展开或收起行详情',\n toggleRow: '展开或收起子行',\n selectGroup: '选择分组',\n toggleGroup: '展开或收起分组',\n noMatches: '无匹配结果',\n search: '搜索',\n reset: '重置',\n },\n eventCalendar: {\n today: '今天',\n previous: '上一个',\n next: '下一个',\n month: '月',\n week: '周',\n day: '日',\n time: '时间',\n allDay: '全天',\n label: '日历',\n more: '+{{count}} 项',\n header: '{{year}}年{{month}}',\n range: '{{from}} – {{to}}',\n chipLabel: '{{title}},{{time}}',\n slotLabel: '{{date}} {{time}}',\n allDayCellLabel: '{{date}} {{label}}',\n },\n tour: {\n next: '下一步',\n back: '上一步',\n done: '完成',\n skip: '跳过引导',\n progress: '第 {{current}} 步,共 {{total}} 步',\n },\n splitter: {\n divider: '调整面板大小',\n },\n stepper: {\n optional: '可选',\n },\n transfer: {\n source: '待选',\n target: '已选',\n search: '搜索',\n empty: '暂无内容',\n selectAll: '全选',\n toTarget: '移至已选',\n toSource: '移回待选',\n count: '{{checked}} / {{total}}',\n },\n form: {\n optional: '选填',\n },\n validation: {\n required: '此项为必填项。',\n requiredTrue: '请勾选此项。',\n email: '请输入有效的电子邮箱地址。',\n minlength: '请至少输入 {{requiredLength}} 个字符。',\n maxlength: '最多可输入 {{requiredLength}} 个字符。',\n min: '请输入不小于 {{min}} 的值。',\n max: '请输入不大于 {{max}} 的值。',\n pattern: '此值的格式不正确。',\n noWhitespace: '此值不能包含空格。',\n hexColor: '请输入十六进制颜色值,例如 #1a2b3c。',\n url: '请输入有效的网址。',\n cardNumber: '请输入有效的卡号。',\n cvc: '请输入 {{length}} 位安全码。',\n iban: '请输入有效的 IBAN。',\n match: '两个值不一致。',\n matchFields: '这些字段的值不一致。',\n oneOf: '请从允许的值中选择。',\n minDate: '请选择更晚的日期。',\n maxDate: '请选择更早的日期。',\n },\n select: {\n label: '选择',\n placeholder: '请选择',\n empty: '暂无选项',\n clearSelection: '清除选择',\n removeItem: '移除 {{label}}',\n noResults: '无搜索结果',\n loading: '加载中…',\n more: '+{{count}} 项',\n },\n tree: {\n expand: '展开',\n collapse: '收起',\n placeholder: '请选择',\n clearSelection: '清除选择',\n removeItem: '移除 {{label}}',\n more: '+{{count}} 项',\n },\n commandPalette: {\n label: '命令面板',\n placeholder: '输入命令或搜索…',\n noResults: '无搜索结果',\n loading: '搜索中…',\n escHint: 'esc',\n },\n empty: {\n noData: '暂无数据',\n },\n fileUpload: {\n browse: '点击选择文件',\n dropZone: '或将文件拖放到此处',\n dropZoneLabel: '文件拖放区域,点击或拖放文件',\n removeFile: '移除文件',\n invalid: '不支持的文件类型',\n tooBig: '文件过大',\n size: '{{value}} {{unit}}',\n unitByte: 'B',\n unitKb: 'KB',\n unitMb: 'MB',\n unitGb: 'GB',\n unitTb: 'TB',\n },\n popconfirm: {\n label: '确认操作',\n confirm: '确认',\n cancel: '取消',\n },\n toast: {\n region: '通知',\n close: '关闭',\n copy: '复制',\n copied: '已复制',\n closeAll: '全部关闭',\n },\n input: {\n showPassword: '显示密码',\n hidePassword: '隐藏密码',\n },\n inputNumber: {\n increment: '增加',\n decrement: '减少',\n },\n inputOtp: {\n label: '验证码',\n digit: '第 {{index}} 位数字',\n character: '第 {{index}} 个字符',\n },\n anchor: {\n label: '目录',\n },\n avatar: {\n alt: '头像',\n },\n backTop: {\n label: '返回顶部',\n },\n breadcrumbs: {\n label: '面包屑导航',\n },\n burger: {\n label: '打开或关闭菜单',\n },\n calendar: {\n prevMonth: '上个月',\n nextMonth: '下个月',\n prevYear: '上一年',\n nextYear: '下一年',\n monthList: '月份',\n yearList: '年份',\n prevYears: '前 12 年',\n nextYears: '后 12 年',\n header: '{{year}}年{{month}}',\n yearRange: '{{from}} – {{to}}',\n dayLabel: '{{date}} {{weekday}}',\n },\n imageCropper: {\n empty: '暂无图片',\n window: '裁剪区域',\n keyHelp:\n '方向键移动裁剪框。按住 Alt 加方向键可调整大小,按住 Shift 可加大步长。' +\n '裁剪框会以图像像素为单位,依次朗读左、上、宽、高四个值。',\n },\n sortableList: {\n keyHelp: '按空格键拿起此项,然后用方向键移动。再次按空格键放下,或按 Esc 键放回原位。',\n grabbed: '已拿起。第 {{index}} 项,共 {{total}} 项。',\n moved: '第 {{index}} 项,共 {{total}} 项。',\n dropped: '已放下。第 {{index}} 项,共 {{total}} 项。',\n cancelled: '已取消移动。',\n },\n colorPicker: {\n area: '饱和度 {{saturation}}%,明度 {{brightness}}%',\n hue: '色相',\n alpha: '不透明度',\n formatHex: 'HEX',\n formatRgb: 'RGB',\n formatHsl: 'HSL',\n channelHex: 'HEX',\n channelRed: 'R',\n channelGreen: 'G',\n channelBlue: 'B',\n channelHue: 'H',\n channelSaturation: 'S%',\n channelLightness: 'L%',\n channelAlpha: 'A%',\n },\n calendarHeatmap: {\n label: '日历热力图',\n },\n lineChart: {\n label: '折线图',\n thousands: '{{value}}千',\n },\n donutChart: {\n label: '环形图',\n },\n compare: {\n label: '对比分隔条',\n },\n carousel: {\n label: '轮播图',\n goToSlide: '转到第 {{index}} 张幻灯片',\n prev: '上一张幻灯片',\n next: '下一张幻灯片',\n pagination: '轮播分页',\n roledescription: '轮播图',\n slideRoledescription: '幻灯片',\n },\n actionSheet: {\n label: '操作',\n },\n alert: {\n close: '关闭提示',\n },\n qr: {\n label: '二维码',\n },\n image: {\n viewer: '图片预览',\n open: '打开预览',\n close: '关闭预览',\n },\n window: {\n close: '关闭',\n minimize: '最小化',\n maximize: '最大化',\n restore: '还原',\n restoreDown: '向下还原',\n restoreWindow: '还原 {{title}}',\n closeWindow: '关闭窗口',\n untitled: '无标题',\n taskbar: '已最小化的窗口',\n },\n dialog: {\n close: '关闭对话框',\n },\n popover: {\n label: '弹出面板',\n },\n markdown: {\n copy: '复制代码',\n copied: '已复制',\n taskDone: '已完成:',\n taskTodo: '待办:',\n },\n marquee: {\n label: '跑马灯',\n link: '链接',\n },\n mention: {\n listbox: '提及',\n available: '匹配项:{{count}}',\n inserted: '已插入:{{label}}',\n },\n drawer: {\n close: '关闭抽屉',\n },\n datePicker: {\n open: '打开日历',\n openTime: '打开时间选择器',\n openDateTime: '打开日期时间选择器',\n openRange: '打开日期范围日历',\n panel: '选择日期',\n panelTime: '选择时间',\n panelDateTime: '选择日期和时间',\n panelRange: '选择日期范围',\n panelRangeDateTime: '选择日期和时间范围',\n rangeStart: '起始日期',\n rangeEnd: '结束日期',\n startTime: '开始时间',\n endTime: '结束时间',\n hours: '小时',\n minutes: '分钟',\n seconds: '秒',\n incrementHours: '增加小时',\n decrementHours: '减少小时',\n incrementMinutes: '增加分钟',\n decrementMinutes: '减少分钟',\n incrementSeconds: '增加秒',\n decrementSeconds: '减少秒',\n toggleAmPm: '切换上午/下午',\n am: '上午',\n pm: '下午',\n },\n sidebar: {\n label: '侧边栏',\n },\n spinner: {\n label: '加载中',\n },\n rating: {\n label: '评分',\n },\n gauge: {\n label: '仪表盘',\n },\n progress: {\n label: '进度',\n },\n meterGroup: {\n label: '计量条',\n },\n knob: {\n label: '数值',\n },\n slider: {\n label: '数值',\n lower: '下限值',\n upper: '上限值',\n },\n speedDial: {\n label: '操作',\n },\n statistic: {\n delta: '{{value}}{{suffix}}',\n deltaSuffix: '%',\n },\n result: {\n notFound: '抱歉,您访问的页面不存在。',\n forbidden: '抱歉,您无权访问此页面。',\n serverError: '抱歉,出错了。',\n },\n date: {\n months: {\n jan: '一月',\n feb: '二月',\n mar: '三月',\n apr: '四月',\n may: '五月',\n jun: '六月',\n jul: '七月',\n aug: '八月',\n sep: '九月',\n oct: '十月',\n nov: '十一月',\n dec: '十二月',\n },\n },\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
2
2
  import * as i0 from '@angular/core';
3
- import { input, inject, ElementRef, signal, computed, ViewEncapsulation, Component } from '@angular/core';
4
- import { useI18nText } from 'ngwr/i18n';
3
+ import { input, inject, LOCALE_ID, ElementRef, signal, computed, ViewEncapsulation, Component } from '@angular/core';
4
+ import { useI18nText, useI18nFormatter } from 'ngwr/i18n';
5
5
 
6
6
  /**
7
7
  * @license
@@ -44,6 +44,8 @@ class WrLineChart {
44
44
  ariaLabel = input(null, /* @ts-ignore */
45
45
  ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
46
46
  resolvedAriaLabel = useI18nText(this.ariaLabel, 'lineChart.label', 'Line chart');
47
+ locale = inject(LOCALE_ID);
48
+ thousandsText = useI18nFormatter('lineChart.thousands', '{{value}}k');
47
49
  /** Labels for the X axis (one per data point). */
48
50
  xLabels = input([], /* @ts-ignore */
49
51
  ...(ngDevMode ? [{ debugName: "xLabels" }] : /* istanbul ignore next */ []));
@@ -211,10 +213,28 @@ class WrLineChart {
211
213
  onPointerLeave() {
212
214
  this.hoveredIndex.set(null);
213
215
  }
216
+ /**
217
+ * A Y-axis tick, in the reader's own language.
218
+ *
219
+ * Two halves and both were English. The `k` was a hardcoded Latin
220
+ * abbreviation — `тыс.` in Russian — so it goes through the catalog like every
221
+ * other word the library paints. The digits went through `toFixed`, which
222
+ * always writes a full stop, so a German axis read `1.5` where the rest of the
223
+ * page read `1,5`; they go through `Intl` now, the way `wrNumber`, `wrDate`
224
+ * and `wrPlural` already did.
225
+ *
226
+ * Grouping is OFF deliberately: a tick is a short axis label, and `5,000k`
227
+ * would be both wider and a change to what every existing chart draws.
228
+ */
214
229
  formatTick(v) {
230
+ const digits = (n, fraction) => new Intl.NumberFormat(this.locale, {
231
+ useGrouping: false,
232
+ minimumFractionDigits: fraction,
233
+ maximumFractionDigits: fraction,
234
+ }).format(n);
215
235
  if (Math.abs(v) >= 1000)
216
- return `${(v / 1000).toFixed(v % 1000 === 0 ? 0 : 1)}k`;
217
- return v.toFixed(v % 1 === 0 ? 0 : 1);
236
+ return this.thousandsText({ value: digits(v / 1000, v % 1000 === 0 ? 0 : 1) });
237
+ return digits(v, v % 1 === 0 ? 0 : 1);
218
238
  }
219
239
  viewBox = computed(() => `0 0 ${this.vbW} ${this.vbH}`, /* @ts-ignore */
220
240
  ...(ngDevMode ? [{ debugName: "viewBox" }] : /* istanbul ignore next */ []));
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-line-chart.mjs","sources":["../../../projects/lib/line-chart/line-chart.ts","../../../projects/lib/line-chart/line-chart.html","../../../projects/lib/line-chart/ngwr-line-chart.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, ElementRef, ViewEncapsulation, computed, inject, input, signal } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\nimport type { WrLineSeries } from './interfaces';\n\nconst FALLBACK_COLORS = [\n 'var(--wr-color-primary)',\n 'var(--wr-color-secondary)',\n 'var(--wr-color-success)',\n 'var(--wr-color-warning)',\n 'var(--wr-color-danger)',\n];\n\n/**\n * Multi-series line chart with axes, gridlines, and a hover tooltip.\n * SVG-only — no external dependency.\n *\n * @example\n * ```html\n * <wr-line-chart\n * [series]=\"[\n * { label: 'Visits', data: [12, 18, 9, 22, 30, 27, 35] },\n * { label: 'Signups', data: [3, 5, 4, 8, 11, 9, 14], color: 'var(--wr-color-success)' }\n * ]\"\n * [xLabels]=\"['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']\"\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/line-chart\n */\n@Component({\n selector: 'wr-line-chart',\n templateUrl: './line-chart.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-line-chart' },\n})\nexport class WrLineChart {\n readonly series = input<readonly WrLineSeries[]>([]);\n\n /**\n * Accessible name of the chart. The legend carries the series NAMES only — the numbers\n * are nowhere in text — so without this the plot is nothing at all to a screen reader.\n * Falls back to `lineChart.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'lineChart.label', 'Line chart');\n\n /** Labels for the X axis (one per data point). */\n readonly xLabels = input<readonly string[]>([]);\n\n /** Chart pixel height. @default 240 */\n readonly height = input(240, { transform: (v: unknown): number => Math.max(80, coerceNumberProperty(v, 240)) });\n\n /** Show gridlines + axis ticks. @default true */\n readonly showGrid = input(true, { transform: coerceBooleanProperty });\n\n /** Show the legend above the chart. @default true */\n readonly showLegend = input(true, { transform: coerceBooleanProperty });\n\n /** Show dots at each data point. @default true */\n readonly showDots = input(true, { transform: coerceBooleanProperty });\n\n // Drawn in a 600×300 viewBox with reserved space for axis labels.\n protected readonly vbW = 600;\n protected readonly vbH = 300;\n protected readonly padding = { top: 16, right: 16, bottom: 28, left: 36 } as const;\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** Hovered point index (across all series) — null when no hover. */\n protected readonly hoveredIndex = signal<number | null>(null);\n\n protected readonly resolvedSeries = computed(() =>\n this.series().map((s, i) => ({\n label: s.label,\n // A non-finite point becomes a HOLE at its own index, not a missing element.\n // It cannot stay a number: `Math.min`/`Math.max` over the pooled data are both\n // NaN as soon as one datum is, so every coordinate in EVERY series came out\n // `NaN` — invalid path geometry, and the whole chart vanished rather than the\n // one bad point. But filtering it out closed the gap and slid every LATER point\n // one x-slot to the left, so each of them was drawn under, and reported in the\n // tooltip as, the wrong x label. A gap is kept as a gap and the line is broken\n // across it: interpolating would invent a reading the data never took.\n data: s.data.map(v => (Number.isFinite(v) ? v : null)),\n color: s.color ?? FALLBACK_COLORS[i % FALLBACK_COLORS.length],\n }))\n );\n\n protected readonly bounds = computed(() => {\n const all = this.resolvedSeries().flatMap(s => s.data.filter(v => v !== null));\n if (all.length === 0) return { min: 0, max: 1 };\n const min = Math.min(...all);\n const max = Math.max(...all);\n if (min === max) return { min: min - 1, max: max + 1 };\n // Pad upper bound by ~10% for breathing room.\n return { min: Math.min(0, min), max: max + (max - min) * 0.1 };\n });\n\n protected readonly pointCount = computed(() => {\n const maxLen = this.resolvedSeries().reduce((acc, s) => Math.max(acc, s.data.length), 0);\n return Math.max(maxLen, this.xLabels().length);\n });\n\n /** Y-axis tick marks (5 of them). */\n protected readonly yTicks = computed(() => {\n const { min, max } = this.bounds();\n const step = (max - min) / 4;\n return [0, 1, 2, 3, 4].map(i => {\n const value = max - i * step;\n return { value, y: this.padding.top + ((max - value) / (max - min)) * this.plotHeight() };\n });\n });\n\n protected readonly plotWidth = (): number => this.vbW - this.padding.left - this.padding.right;\n protected readonly plotHeight = (): number => this.vbH - this.padding.top - this.padding.bottom;\n\n /**\n * The SVG path for a series — one subpath per unbroken run, so a hole in the data\n * leaves a hole in the line rather than a straight segment across it.\n */\n protected pathFor(series: { data: readonly (number | null)[] }): string {\n const { min, max } = this.bounds();\n const count = this.pointCount();\n if (count <= 1) return '';\n const pw = this.plotWidth();\n const ph = this.plotHeight();\n\n const commands: string[] = [];\n let run = 0;\n let last = '';\n // A subpath of one `M` is not stroked at all, so a point with a gap on both sides\n // would simply vanish when `showDots` is off. Repeating it gives the round linecap\n // something to paint.\n const closeRun = (): void => {\n if (run === 1) commands.push(`L ${last}`);\n run = 0;\n };\n\n series.data.forEach((v, i) => {\n if (v === null) {\n closeRun();\n return;\n }\n const x = this.padding.left + (i / (count - 1)) * pw;\n const y = this.padding.top + ((max - v) / (max - min)) * ph;\n last = `${x.toFixed(2)} ${y.toFixed(2)}`;\n commands.push(`${run === 0 ? 'M' : 'L'} ${last}`);\n run++;\n });\n closeRun();\n\n return commands.join(' ');\n }\n\n protected pointX(index: number): number {\n const count = this.pointCount();\n if (count <= 1) return this.padding.left;\n return this.padding.left + (index / (count - 1)) * this.plotWidth();\n }\n\n protected pointY(value: number): number {\n const { min, max } = this.bounds();\n return this.padding.top + ((max - value) / (max - min)) * this.plotHeight();\n }\n\n /**\n * A point's x as a percentage of the host's width. The x-label strip and the SVG share\n * that width — the drawing stretches to it — so this is the same space the tooltip and\n * the labels are placed in, at any size.\n */\n protected xPercent(index: number): number {\n return (this.pointX(index) / this.vbW) * 100;\n }\n\n /**\n * How wide an x label may be, as a percentage of the host's width: its own slot — half\n * the distance to a neighbour on each side — cut back to what is left between its point\n * and the end of the strip. Centring a label on its point says nothing about its WIDTH,\n * and with no bound at all twelve month names printed over each other and the last one\n * hung outside the chart. Past this the stylesheet ellipsises.\n */\n protected xMaxPercent(index: number): number {\n const count = this.pointCount();\n // A single label has no neighbour to collide with and the whole strip to sit in.\n if (count <= 1) return 100;\n const slot = (this.plotWidth() / (count - 1) / this.vbW) * 100;\n const x = this.xPercent(index);\n return Math.min(slot, x + slot / 2, 100 - x + slot / 2);\n }\n\n protected readonly hoverPoints = computed(() => {\n const i = this.hoveredIndex();\n if (i === null) return [];\n return this.resolvedSeries().flatMap(s => {\n // Past the end of a short series, or on a hole in a longer one — either way there\n // is no reading at this x, so the series contributes neither a marker nor a row.\n const value = s.data[i];\n if (value === undefined || value === null) return [];\n return [{ label: s.label, value, color: s.color, x: this.pointX(i), y: this.pointY(value) }];\n });\n });\n\n protected readonly hoverLabel = computed(() => {\n const i = this.hoveredIndex();\n if (i === null) return '';\n return this.xLabels()[i] ?? String(i);\n });\n\n protected onPointerMove(event: PointerEvent): void {\n const svg = (event.currentTarget as SVGElement).getBoundingClientRect();\n const ratio = (event.clientX - svg.left) / svg.width;\n const vbX = ratio * this.vbW;\n const count = this.pointCount();\n if (count === 0) return;\n const i = Math.round(((vbX - this.padding.left) / this.plotWidth()) * (count - 1));\n if (i >= 0 && i < count) this.hoveredIndex.set(i);\n }\n\n protected onPointerLeave(): void {\n this.hoveredIndex.set(null);\n }\n\n protected formatTick(v: number): string {\n if (Math.abs(v) >= 1000) return `${(v / 1000).toFixed(v % 1000 === 0 ? 0 : 1)}k`;\n return v.toFixed(v % 1 === 0 ? 0 : 1);\n }\n\n protected readonly viewBox = computed(() => `0 0 ${this.vbW} ${this.vbH}`);\n\n // Convenience accessor so the host can be referenced from the template.\n protected readonly hostEl = this.host.nativeElement;\n}\n\nexport type { WrLineSeries } from './interfaces';\n","@let hovered = hoveredIndex();\n@if (showLegend() && resolvedSeries().length > 0) {\n <ul class=\"wr-line-chart__legend\">\n @for (s of resolvedSeries(); track s.label) {\n <li class=\"wr-line-chart__legend-item\">\n <span class=\"wr-line-chart__swatch\" [style.background]=\"s.color\"></span>\n <span>{{ s.label }}</span>\n </li>\n }\n </ul>\n}\n\n<div class=\"wr-line-chart__plot\" role=\"img\" [attr.aria-label]=\"resolvedAriaLabel()\" [style.height.px]=\"height()\">\n <svg\n [attr.viewBox]=\"viewBox()\"\n preserveAspectRatio=\"none\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerleave)=\"onPointerLeave()\"\n >\n @if (showGrid()) {\n @for (tick of yTicks(); track tick.value) {\n <line\n class=\"wr-line-chart__grid-line\"\n [attr.x1]=\"padding.left\"\n [attr.x2]=\"vbW - padding.right\"\n [attr.y1]=\"tick.y\"\n [attr.y2]=\"tick.y\"\n stroke=\"rgba(var(--wr-color-light-rgb), 0.7)\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n <text\n class=\"wr-line-chart__tick\"\n [attr.x]=\"padding.left - 6\"\n [attr.y]=\"tick.y + 4\"\n text-anchor=\"end\"\n fill=\"var(--wr-color-on-surface-muted)\"\n font-size=\"10\"\n font-family=\"var(--wr-font-family-base)\"\n >\n {{ formatTick(tick.value) }}\n </text>\n }\n }\n\n @for (s of resolvedSeries(); track s.label) {\n <path\n class=\"wr-line-chart__line\"\n [attr.d]=\"pathFor(s)\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n @if (showDots()) {\n @for (v of s.data; track $index; let i = $index) {\n <!-- A hole in the data gets no dot: the index still belongs to it, so the\n points after it stay on their own x. -->\n @if (v !== null) {\n <circle\n class=\"wr-line-chart__dot\"\n [attr.cx]=\"pointX(i)\"\n [attr.cy]=\"pointY(v)\"\n r=\"3\"\n [attr.fill]=\"s.color\"\n />\n }\n }\n }\n }\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <line\n class=\"wr-line-chart__crosshair\"\n [attr.x1]=\"pointX(hovered)\"\n [attr.x2]=\"pointX(hovered)\"\n [attr.y1]=\"padding.top\"\n [attr.y2]=\"vbH - padding.bottom\"\n stroke=\"var(--wr-color-medium)\"\n stroke-width=\"1\"\n stroke-dasharray=\"3 3\"\n vector-effect=\"non-scaling-stroke\"\n />\n @for (p of hoverPoints(); track p.label) {\n <circle\n [attr.cx]=\"p.x\"\n [attr.cy]=\"p.y\"\n r=\"5\"\n fill=\"var(--wr-color-white)\"\n [attr.stroke]=\"p.color\"\n stroke-width=\"2\"\n />\n }\n }\n </svg>\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <div class=\"wr-line-chart__tooltip\" [style.left.%]=\"(pointX(hovered) / vbW) * 100\" [style.top.px]=\"padding.top\">\n <div class=\"wr-line-chart__tooltip-label\">{{ hoverLabel() }}</div>\n @for (p of hoverPoints(); track p.label) {\n <div class=\"wr-line-chart__tooltip-row\">\n <span class=\"wr-line-chart__swatch\" [style.background]=\"p.color\"></span>\n <span class=\"wr-line-chart__tooltip-name\">{{ p.label }}</span>\n <span class=\"wr-line-chart__tooltip-value\">{{ p.value }}</span>\n </div>\n }\n </div>\n }\n</div>\n\n@if (xLabels().length > 0) {\n <div class=\"wr-line-chart__x-labels\">\n @for (label of xLabels(); track $index) {\n <!-- Each label hands the stylesheet two numbers, both percentages of the host's\n width — the space the stretching SVG is in, so they track the drawing at any\n size. The x of the point it names, which the stylesheet centres it on; and the\n widest it may be before it reaches a neighbour or the end of the strip, past\n which the stylesheet ellipsises it. Laying the labels out as equal centred flex\n slots instead is bar-chart geometry: only the middle label landed on its dot,\n and the outer ones sat up to half a column away. -->\n <span\n class=\"wr-line-chart__x-label\"\n [style.--wr-line-chart-x]=\"xPercent($index)\"\n [style.--wr-line-chart-x-max]=\"xMaxPercent($index)\"\n >{{ label }}</span\n >\n }\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-line-chart.mjs","sources":["../../../projects/lib/line-chart/line-chart.ts","../../../projects/lib/line-chart/line-chart.html","../../../projects/lib/line-chart/ngwr-line-chart.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, ElementRef, LOCALE_ID, ViewEncapsulation, computed, inject, input, signal } from '@angular/core';\n\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport type { WrLineSeries } from './interfaces';\n\nconst FALLBACK_COLORS = [\n 'var(--wr-color-primary)',\n 'var(--wr-color-secondary)',\n 'var(--wr-color-success)',\n 'var(--wr-color-warning)',\n 'var(--wr-color-danger)',\n];\n\n/**\n * Multi-series line chart with axes, gridlines, and a hover tooltip.\n * SVG-only — no external dependency.\n *\n * @example\n * ```html\n * <wr-line-chart\n * [series]=\"[\n * { label: 'Visits', data: [12, 18, 9, 22, 30, 27, 35] },\n * { label: 'Signups', data: [3, 5, 4, 8, 11, 9, 14], color: 'var(--wr-color-success)' }\n * ]\"\n * [xLabels]=\"['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']\"\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/line-chart\n */\n@Component({\n selector: 'wr-line-chart',\n templateUrl: './line-chart.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-line-chart' },\n})\nexport class WrLineChart {\n readonly series = input<readonly WrLineSeries[]>([]);\n\n /**\n * Accessible name of the chart. The legend carries the series NAMES only — the numbers\n * are nowhere in text — so without this the plot is nothing at all to a screen reader.\n * Falls back to `lineChart.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'lineChart.label', 'Line chart');\n\n private readonly locale = inject(LOCALE_ID);\n private readonly thousandsText = useI18nFormatter('lineChart.thousands', '{{value}}k');\n\n /** Labels for the X axis (one per data point). */\n readonly xLabels = input<readonly string[]>([]);\n\n /** Chart pixel height. @default 240 */\n readonly height = input(240, { transform: (v: unknown): number => Math.max(80, coerceNumberProperty(v, 240)) });\n\n /** Show gridlines + axis ticks. @default true */\n readonly showGrid = input(true, { transform: coerceBooleanProperty });\n\n /** Show the legend above the chart. @default true */\n readonly showLegend = input(true, { transform: coerceBooleanProperty });\n\n /** Show dots at each data point. @default true */\n readonly showDots = input(true, { transform: coerceBooleanProperty });\n\n // Drawn in a 600×300 viewBox with reserved space for axis labels.\n protected readonly vbW = 600;\n protected readonly vbH = 300;\n protected readonly padding = { top: 16, right: 16, bottom: 28, left: 36 } as const;\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** Hovered point index (across all series) — null when no hover. */\n protected readonly hoveredIndex = signal<number | null>(null);\n\n protected readonly resolvedSeries = computed(() =>\n this.series().map((s, i) => ({\n label: s.label,\n // A non-finite point becomes a HOLE at its own index, not a missing element.\n // It cannot stay a number: `Math.min`/`Math.max` over the pooled data are both\n // NaN as soon as one datum is, so every coordinate in EVERY series came out\n // `NaN` — invalid path geometry, and the whole chart vanished rather than the\n // one bad point. But filtering it out closed the gap and slid every LATER point\n // one x-slot to the left, so each of them was drawn under, and reported in the\n // tooltip as, the wrong x label. A gap is kept as a gap and the line is broken\n // across it: interpolating would invent a reading the data never took.\n data: s.data.map(v => (Number.isFinite(v) ? v : null)),\n color: s.color ?? FALLBACK_COLORS[i % FALLBACK_COLORS.length],\n }))\n );\n\n protected readonly bounds = computed(() => {\n const all = this.resolvedSeries().flatMap(s => s.data.filter(v => v !== null));\n if (all.length === 0) return { min: 0, max: 1 };\n const min = Math.min(...all);\n const max = Math.max(...all);\n if (min === max) return { min: min - 1, max: max + 1 };\n // Pad upper bound by ~10% for breathing room.\n return { min: Math.min(0, min), max: max + (max - min) * 0.1 };\n });\n\n protected readonly pointCount = computed(() => {\n const maxLen = this.resolvedSeries().reduce((acc, s) => Math.max(acc, s.data.length), 0);\n return Math.max(maxLen, this.xLabels().length);\n });\n\n /** Y-axis tick marks (5 of them). */\n protected readonly yTicks = computed(() => {\n const { min, max } = this.bounds();\n const step = (max - min) / 4;\n return [0, 1, 2, 3, 4].map(i => {\n const value = max - i * step;\n return { value, y: this.padding.top + ((max - value) / (max - min)) * this.plotHeight() };\n });\n });\n\n protected readonly plotWidth = (): number => this.vbW - this.padding.left - this.padding.right;\n protected readonly plotHeight = (): number => this.vbH - this.padding.top - this.padding.bottom;\n\n /**\n * The SVG path for a series — one subpath per unbroken run, so a hole in the data\n * leaves a hole in the line rather than a straight segment across it.\n */\n protected pathFor(series: { data: readonly (number | null)[] }): string {\n const { min, max } = this.bounds();\n const count = this.pointCount();\n if (count <= 1) return '';\n const pw = this.plotWidth();\n const ph = this.plotHeight();\n\n const commands: string[] = [];\n let run = 0;\n let last = '';\n // A subpath of one `M` is not stroked at all, so a point with a gap on both sides\n // would simply vanish when `showDots` is off. Repeating it gives the round linecap\n // something to paint.\n const closeRun = (): void => {\n if (run === 1) commands.push(`L ${last}`);\n run = 0;\n };\n\n series.data.forEach((v, i) => {\n if (v === null) {\n closeRun();\n return;\n }\n const x = this.padding.left + (i / (count - 1)) * pw;\n const y = this.padding.top + ((max - v) / (max - min)) * ph;\n last = `${x.toFixed(2)} ${y.toFixed(2)}`;\n commands.push(`${run === 0 ? 'M' : 'L'} ${last}`);\n run++;\n });\n closeRun();\n\n return commands.join(' ');\n }\n\n protected pointX(index: number): number {\n const count = this.pointCount();\n if (count <= 1) return this.padding.left;\n return this.padding.left + (index / (count - 1)) * this.plotWidth();\n }\n\n protected pointY(value: number): number {\n const { min, max } = this.bounds();\n return this.padding.top + ((max - value) / (max - min)) * this.plotHeight();\n }\n\n /**\n * A point's x as a percentage of the host's width. The x-label strip and the SVG share\n * that width — the drawing stretches to it — so this is the same space the tooltip and\n * the labels are placed in, at any size.\n */\n protected xPercent(index: number): number {\n return (this.pointX(index) / this.vbW) * 100;\n }\n\n /**\n * How wide an x label may be, as a percentage of the host's width: its own slot — half\n * the distance to a neighbour on each side — cut back to what is left between its point\n * and the end of the strip. Centring a label on its point says nothing about its WIDTH,\n * and with no bound at all twelve month names printed over each other and the last one\n * hung outside the chart. Past this the stylesheet ellipsises.\n */\n protected xMaxPercent(index: number): number {\n const count = this.pointCount();\n // A single label has no neighbour to collide with and the whole strip to sit in.\n if (count <= 1) return 100;\n const slot = (this.plotWidth() / (count - 1) / this.vbW) * 100;\n const x = this.xPercent(index);\n return Math.min(slot, x + slot / 2, 100 - x + slot / 2);\n }\n\n protected readonly hoverPoints = computed(() => {\n const i = this.hoveredIndex();\n if (i === null) return [];\n return this.resolvedSeries().flatMap(s => {\n // Past the end of a short series, or on a hole in a longer one — either way there\n // is no reading at this x, so the series contributes neither a marker nor a row.\n const value = s.data[i];\n if (value === undefined || value === null) return [];\n return [{ label: s.label, value, color: s.color, x: this.pointX(i), y: this.pointY(value) }];\n });\n });\n\n protected readonly hoverLabel = computed(() => {\n const i = this.hoveredIndex();\n if (i === null) return '';\n return this.xLabels()[i] ?? String(i);\n });\n\n protected onPointerMove(event: PointerEvent): void {\n const svg = (event.currentTarget as SVGElement).getBoundingClientRect();\n const ratio = (event.clientX - svg.left) / svg.width;\n const vbX = ratio * this.vbW;\n const count = this.pointCount();\n if (count === 0) return;\n const i = Math.round(((vbX - this.padding.left) / this.plotWidth()) * (count - 1));\n if (i >= 0 && i < count) this.hoveredIndex.set(i);\n }\n\n protected onPointerLeave(): void {\n this.hoveredIndex.set(null);\n }\n\n /**\n * A Y-axis tick, in the reader's own language.\n *\n * Two halves and both were English. The `k` was a hardcoded Latin\n * abbreviation — `тыс.` in Russian — so it goes through the catalog like every\n * other word the library paints. The digits went through `toFixed`, which\n * always writes a full stop, so a German axis read `1.5` where the rest of the\n * page read `1,5`; they go through `Intl` now, the way `wrNumber`, `wrDate`\n * and `wrPlural` already did.\n *\n * Grouping is OFF deliberately: a tick is a short axis label, and `5,000k`\n * would be both wider and a change to what every existing chart draws.\n */\n protected formatTick(v: number): string {\n const digits = (n: number, fraction: number): string =>\n new Intl.NumberFormat(this.locale, {\n useGrouping: false,\n minimumFractionDigits: fraction,\n maximumFractionDigits: fraction,\n }).format(n);\n\n if (Math.abs(v) >= 1000) return this.thousandsText({ value: digits(v / 1000, v % 1000 === 0 ? 0 : 1) });\n return digits(v, v % 1 === 0 ? 0 : 1);\n }\n\n protected readonly viewBox = computed(() => `0 0 ${this.vbW} ${this.vbH}`);\n\n // Convenience accessor so the host can be referenced from the template.\n protected readonly hostEl = this.host.nativeElement;\n}\n\nexport type { WrLineSeries } from './interfaces';\n","@let hovered = hoveredIndex();\n@if (showLegend() && resolvedSeries().length > 0) {\n <ul class=\"wr-line-chart__legend\">\n @for (s of resolvedSeries(); track s.label) {\n <li class=\"wr-line-chart__legend-item\">\n <span class=\"wr-line-chart__swatch\" [style.background]=\"s.color\"></span>\n <span>{{ s.label }}</span>\n </li>\n }\n </ul>\n}\n\n<div class=\"wr-line-chart__plot\" role=\"img\" [attr.aria-label]=\"resolvedAriaLabel()\" [style.height.px]=\"height()\">\n <svg\n [attr.viewBox]=\"viewBox()\"\n preserveAspectRatio=\"none\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerleave)=\"onPointerLeave()\"\n >\n @if (showGrid()) {\n @for (tick of yTicks(); track tick.value) {\n <line\n class=\"wr-line-chart__grid-line\"\n [attr.x1]=\"padding.left\"\n [attr.x2]=\"vbW - padding.right\"\n [attr.y1]=\"tick.y\"\n [attr.y2]=\"tick.y\"\n stroke=\"rgba(var(--wr-color-light-rgb), 0.7)\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n <text\n class=\"wr-line-chart__tick\"\n [attr.x]=\"padding.left - 6\"\n [attr.y]=\"tick.y + 4\"\n text-anchor=\"end\"\n fill=\"var(--wr-color-on-surface-muted)\"\n font-size=\"10\"\n font-family=\"var(--wr-font-family-base)\"\n >\n {{ formatTick(tick.value) }}\n </text>\n }\n }\n\n @for (s of resolvedSeries(); track s.label) {\n <path\n class=\"wr-line-chart__line\"\n [attr.d]=\"pathFor(s)\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n @if (showDots()) {\n @for (v of s.data; track $index; let i = $index) {\n <!-- A hole in the data gets no dot: the index still belongs to it, so the\n points after it stay on their own x. -->\n @if (v !== null) {\n <circle\n class=\"wr-line-chart__dot\"\n [attr.cx]=\"pointX(i)\"\n [attr.cy]=\"pointY(v)\"\n r=\"3\"\n [attr.fill]=\"s.color\"\n />\n }\n }\n }\n }\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <line\n class=\"wr-line-chart__crosshair\"\n [attr.x1]=\"pointX(hovered)\"\n [attr.x2]=\"pointX(hovered)\"\n [attr.y1]=\"padding.top\"\n [attr.y2]=\"vbH - padding.bottom\"\n stroke=\"var(--wr-color-medium)\"\n stroke-width=\"1\"\n stroke-dasharray=\"3 3\"\n vector-effect=\"non-scaling-stroke\"\n />\n @for (p of hoverPoints(); track p.label) {\n <circle\n [attr.cx]=\"p.x\"\n [attr.cy]=\"p.y\"\n r=\"5\"\n fill=\"var(--wr-color-white)\"\n [attr.stroke]=\"p.color\"\n stroke-width=\"2\"\n />\n }\n }\n </svg>\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <div class=\"wr-line-chart__tooltip\" [style.left.%]=\"(pointX(hovered) / vbW) * 100\" [style.top.px]=\"padding.top\">\n <div class=\"wr-line-chart__tooltip-label\">{{ hoverLabel() }}</div>\n @for (p of hoverPoints(); track p.label) {\n <div class=\"wr-line-chart__tooltip-row\">\n <span class=\"wr-line-chart__swatch\" [style.background]=\"p.color\"></span>\n <span class=\"wr-line-chart__tooltip-name\">{{ p.label }}</span>\n <span class=\"wr-line-chart__tooltip-value\">{{ p.value }}</span>\n </div>\n }\n </div>\n }\n</div>\n\n@if (xLabels().length > 0) {\n <div class=\"wr-line-chart__x-labels\">\n @for (label of xLabels(); track $index) {\n <!-- Each label hands the stylesheet two numbers, both percentages of the host's\n width — the space the stretching SVG is in, so they track the drawing at any\n size. The x of the point it names, which the stylesheet centres it on; and the\n widest it may be before it reaches a neighbour or the end of the strip, past\n which the stylesheet ellipsises it. Laying the labels out as equal centred flex\n slots instead is bar-chart geometry: only the middle label landed on its dot,\n and the outer ones sat up to half a column away. -->\n <span\n class=\"wr-line-chart__x-label\"\n [style.--wr-line-chart-x]=\"xPercent($index)\"\n [style.--wr-line-chart-x-max]=\"xMaxPercent($index)\"\n >{{ label }}</span\n >\n }\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}