@uoa-css-lab/duckscatter 1.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 (83) hide show
  1. package/.github/dependabot.yml +42 -0
  2. package/.github/workflows/ci.yaml +111 -0
  3. package/.github/workflows/release.yml +55 -0
  4. package/.prettierrc +11 -0
  5. package/LICENSE +22 -0
  6. package/README.md +250 -0
  7. package/dist/data/data-layer.d.ts +169 -0
  8. package/dist/data/data-layer.js +402 -0
  9. package/dist/data/index.d.ts +2 -0
  10. package/dist/data/index.js +2 -0
  11. package/dist/data/repository.d.ts +48 -0
  12. package/dist/data/repository.js +109 -0
  13. package/dist/diagnostics.d.ts +27 -0
  14. package/dist/diagnostics.js +71 -0
  15. package/dist/errors.d.ts +22 -0
  16. package/dist/errors.js +58 -0
  17. package/dist/event-emitter.d.ts +62 -0
  18. package/dist/event-emitter.js +82 -0
  19. package/dist/index.d.ts +12 -0
  20. package/dist/index.js +13 -0
  21. package/dist/renderer/gpu-layer.d.ts +204 -0
  22. package/dist/renderer/gpu-layer.js +611 -0
  23. package/dist/renderer/index.d.ts +3 -0
  24. package/dist/renderer/index.js +3 -0
  25. package/dist/renderer/shaders.d.ts +13 -0
  26. package/dist/renderer/shaders.js +216 -0
  27. package/dist/renderer/webgpu-context.d.ts +20 -0
  28. package/dist/renderer/webgpu-context.js +88 -0
  29. package/dist/scatter-plot.d.ts +210 -0
  30. package/dist/scatter-plot.js +450 -0
  31. package/dist/types.d.ts +171 -0
  32. package/dist/types.js +1 -0
  33. package/dist/ui/index.d.ts +1 -0
  34. package/dist/ui/index.js +1 -0
  35. package/dist/ui/label-layer.d.ts +176 -0
  36. package/dist/ui/label-layer.js +488 -0
  37. package/docs/image.png +0 -0
  38. package/eslint.config.js +72 -0
  39. package/examples/next/README.md +36 -0
  40. package/examples/next/app/components/ColorExpressionInput.tsx +41 -0
  41. package/examples/next/app/components/ControlPanel.tsx +30 -0
  42. package/examples/next/app/components/HoverControlPanel.tsx +69 -0
  43. package/examples/next/app/components/HoverInfoDisplay.tsx +40 -0
  44. package/examples/next/app/components/LabelFilterInput.tsx +46 -0
  45. package/examples/next/app/components/LabelList.tsx +106 -0
  46. package/examples/next/app/components/PointAlphaSlider.tsx +21 -0
  47. package/examples/next/app/components/PointLimitSlider.tsx +23 -0
  48. package/examples/next/app/components/PointList.tsx +105 -0
  49. package/examples/next/app/components/PointSizeScaleSlider.tsx +22 -0
  50. package/examples/next/app/components/ScatterPlotCanvas.tsx +150 -0
  51. package/examples/next/app/components/SearchBox.tsx +46 -0
  52. package/examples/next/app/components/Slider.tsx +76 -0
  53. package/examples/next/app/components/StatsDisplay.tsx +15 -0
  54. package/examples/next/app/components/TimeFilterSlider.tsx +169 -0
  55. package/examples/next/app/context/ScatterPlotContext.tsx +402 -0
  56. package/examples/next/app/favicon.ico +0 -0
  57. package/examples/next/app/globals.css +23 -0
  58. package/examples/next/app/layout.tsx +35 -0
  59. package/examples/next/app/page.tsx +15 -0
  60. package/examples/next/eslint.config.mjs +18 -0
  61. package/examples/next/next.config.ts +7 -0
  62. package/examples/next/package-lock.json +6572 -0
  63. package/examples/next/package.json +27 -0
  64. package/examples/next/postcss.config.mjs +7 -0
  65. package/examples/next/scripts/generate_labels.py +167 -0
  66. package/examples/next/tsconfig.json +34 -0
  67. package/package.json +43 -0
  68. package/src/data/data-layer.ts +515 -0
  69. package/src/data/index.ts +2 -0
  70. package/src/data/repository.ts +146 -0
  71. package/src/diagnostics.ts +108 -0
  72. package/src/errors.ts +69 -0
  73. package/src/event-emitter.ts +88 -0
  74. package/src/index.ts +40 -0
  75. package/src/renderer/gpu-layer.ts +757 -0
  76. package/src/renderer/index.ts +3 -0
  77. package/src/renderer/shaders.ts +219 -0
  78. package/src/renderer/webgpu-context.ts +98 -0
  79. package/src/scatter-plot.ts +533 -0
  80. package/src/types.ts +218 -0
  81. package/src/ui/index.ts +1 -0
  82. package/src/ui/label-layer.ts +648 -0
  83. package/tsconfig.json +19 -0
package/src/types.ts ADDED
@@ -0,0 +1,218 @@
1
+ /**
2
+ * duckscatterライブラリの型定義
3
+ */
4
+ export type LabelFilterLambda = (properties: Record<string, any>) => boolean;
5
+ export type PointHoverCallback = (data: { row: any[]; columns: string[] } | null) => void;
6
+
7
+ /** ポイント識別子の型(idColumnの値) */
8
+ export type PointId = string | number;
9
+
10
+ /** プログラムによるホバー制御用のラベル識別子 */
11
+ export interface LabelIdentifier {
12
+ /** テキストでラベルを識別 */
13
+ text?: string;
14
+ /** クラスター番号でラベルを識別 */
15
+ cluster?: number;
16
+ }
17
+
18
+ /** ラベルがホバーされた時に発火するコールバック */
19
+ export type LabelHoverCallback = (label: Label | null) => void;
20
+
21
+ export interface ColorRGBA {
22
+ r: number; // 0-1
23
+ g: number; // 0-1
24
+ b: number; // 0-1
25
+ a: number; // 0-1
26
+ }
27
+
28
+ export interface HoverOutlineOptions {
29
+ /** ホバーアウトラインを有効化(デフォルト: true) */
30
+ enabled?: boolean;
31
+ /** アウトラインの線色(デフォルト: 白) */
32
+ color?: string;
33
+ /** アウトラインの線幅(ピクセル単位、デフォルト: 2) */
34
+ width?: number;
35
+ minimumHoverSize?: number;
36
+ outlinedPointAddition?: number;
37
+ }
38
+
39
+ export interface Label {
40
+ /** 表示するラベルテキスト */
41
+ text: string;
42
+ /** データ空間でのX座標 */
43
+ x: number;
44
+ /** データ空間でのY座標 */
45
+ y: number;
46
+ /** オプションのラベルプロパティ */
47
+ cluster?: number;
48
+ count?: number;
49
+ /** 元のGeoJSONフィーチャーのプロパティ */
50
+ properties?: Record<string, any>;
51
+ }
52
+
53
+ /**
54
+ * データクエリ用のWHERE条件フィルター
55
+ */
56
+
57
+ /** 数値比較演算子 */
58
+ export type NumericOperator = '>=' | '>' | '<=' | '<';
59
+
60
+ /** 文字列比較演算子 */
61
+ export type StringOperator = 'contains' | 'equals' | 'startsWith' | 'endsWith';
62
+
63
+ /** 数値フィルター条件 */
64
+ export interface NumericFilter {
65
+ type: 'numeric';
66
+ column: string;
67
+ operator: NumericOperator;
68
+ value: number;
69
+ }
70
+
71
+ /** 文字列フィルター条件 */
72
+ export interface StringFilter {
73
+ type: 'string';
74
+ column: string;
75
+ operator: StringOperator;
76
+ value: string;
77
+ }
78
+
79
+ /** 生SQLフィルター条件 */
80
+ export interface RawSqlFilter {
81
+ type: 'raw';
82
+ sql: string;
83
+ }
84
+
85
+ /** すべてのWHERE条件の共用体型 */
86
+ export type WhereCondition = NumericFilter | StringFilter | RawSqlFilter;
87
+
88
+ /** GPUフィルター条件 (range only) */
89
+ export interface GpuWhereCondition {
90
+ /** フィルター対象のカラム名 (gpuFilterColumnsで指定した名前) */
91
+ column: string;
92
+ /** 最小値 (指定しない場合は -Infinity) */
93
+ min?: number;
94
+ /** 最大値 (指定しない場合は +Infinity) */
95
+ max?: number;
96
+ }
97
+
98
+ export interface DataOptions {
99
+ /** レンダリングする表示ポイントの最大数 */
100
+ visiblePointLimit?: number;
101
+
102
+ /** ポイントサイズ用のSQL式(例: "LOG(favorite_count + 1) * 2 + 2") */
103
+ sizeSql?: string;
104
+
105
+ /** ポイントカラー用のSQL式(ARGB 32bit整数、例: "0xFF0000FF") */
106
+ colorSql?: string;
107
+
108
+ /** データをフィルタリングするWHERE条件(ANDのみ) */
109
+ whereConditions?: WhereCondition[];
110
+
111
+ /** GPUでフィルタリングするカラム名 (最大4つ) */
112
+ gpuFilterColumns?: string[];
113
+
114
+ /** GPU側で実行するフィルター条件 */
115
+ gpuWhereConditions?: GpuWhereCondition[];
116
+
117
+ /** ポイントを識別するカラム名 */
118
+ idColumn: string;
119
+ }
120
+
121
+ export interface GpuOptions {
122
+ /** 背景色(デフォルト: 透明な黒) */
123
+ backgroundColor?: ColorRGBA;
124
+ /** グローバル透明度 (0.0-1.0, デフォルト: 1.0) */
125
+ pointAlpha?: number;
126
+ /** グローバルサイズスケール (デフォルト: 1.0) */
127
+ pointSizeScale?: number;
128
+ }
129
+
130
+ export interface LabelOptions {
131
+ /** ラベルGeoJSONデータを取得するURL(初期化時に自動ロード) */
132
+ url?: string;
133
+
134
+ /** ラベルのフォントサイズ(ピクセル単位、デフォルト: 12) */
135
+ fontSize?: number;
136
+
137
+ /** プロパティに基づいてラベルの表示を制御するフィルター関数 */
138
+ filterLambda?: LabelFilterLambda;
139
+
140
+ /** ラベルがクリックされた時に発火するコールバック */
141
+ onClick?: (label: Label) => void;
142
+
143
+ /** ポイントホバーアウトラインの外観オプション */
144
+ hoverOutlineOptions?: HoverOutlineOptions;
145
+ }
146
+
147
+ export interface InteractionOptions {
148
+ /** ポイントがホバーされた時に発火するコールバック */
149
+ onPointHover?: PointHoverCallback;
150
+ /** ラベルがホバーされた時に発火するコールバック */
151
+ onLabelHover?: LabelHoverCallback;
152
+ }
153
+
154
+ export interface ScatterPlotOptions {
155
+ /** レンダリング先のCanvas要素 */
156
+ canvas: HTMLCanvasElement;
157
+
158
+ /** Parquetデータを取得するURL */
159
+ dataUrl: string;
160
+
161
+ /** データレイヤーオプション */
162
+ data: DataOptions;
163
+
164
+ /** GPUレンダリングオプション */
165
+ gpu?: GpuOptions;
166
+
167
+ /** ラベルレイヤーオプション */
168
+ labels?: LabelOptions;
169
+
170
+ /** インタラクションコールバック */
171
+ interaction?: InteractionOptions;
172
+ }
173
+
174
+ /**
175
+ * エラーハンドリング型
176
+ */
177
+
178
+ /** エラー重大度レベル */
179
+ export type ErrorSeverity = 'fatal' | 'error' | 'warning';
180
+
181
+ /** エラーカテゴリ */
182
+ export type ErrorCategory = 'webgpu' | 'data' | 'label' | 'query' | 'network';
183
+
184
+ /** すべての可能なエラーのエラーコード */
185
+ export type ErrorCode =
186
+ | 'WEBGPU_NOT_SUPPORTED'
187
+ | 'GPU_ADAPTER_NOT_AVAILABLE'
188
+ | 'GPU_DEVICE_FAILED'
189
+ | 'WEBGPU_CONTEXT_FAILED'
190
+ | 'DATA_LAYER_NOT_INITIALIZED'
191
+ | 'PARQUET_LOAD_FAILED'
192
+ | 'QUERY_FAILED'
193
+ | 'LABEL_FETCH_FAILED'
194
+ | 'LABEL_PARSE_FAILED'
195
+ | 'NETWORK_ERROR';
196
+
197
+ /** エラーイベントペイロード */
198
+ export interface ScatterPlotError {
199
+ /** プログラムによるハンドリング用のエラーコード */
200
+ code: ErrorCode;
201
+ /** エラーカテゴリ */
202
+ category: ErrorCategory;
203
+ /** エラー重大度 */
204
+ severity: ErrorSeverity;
205
+ /** 人が読めるエラーメッセージ */
206
+ message: string;
207
+ /** 利用可能な場合、元のエラーオブジェクト */
208
+ cause?: Error;
209
+ /** 追加のコンテキスト情報 */
210
+ context?: Record<string, unknown>;
211
+ /** エラーが発生したタイムスタンプ */
212
+ timestamp: number;
213
+ }
214
+
215
+ /** ScatterPlot EventEmitter用のイベントマップ */
216
+ export interface ScatterPlotEventMap {
217
+ error: ScatterPlotError;
218
+ }
@@ -0,0 +1 @@
1
+ export { LabelLayer } from './label-layer.js';