chartai 0.1.0 → 1.1.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 (116) hide show
  1. package/dist/chart-library.d.ts +34 -146
  2. package/dist/chart-library.d.ts.map +1 -1
  3. package/dist/chart-library.js +411 -322
  4. package/dist/chart-library.min.js +1 -1
  5. package/dist/charts/area.d.ts +6 -0
  6. package/dist/charts/area.d.ts.map +1 -0
  7. package/dist/charts/area.js +65 -0
  8. package/dist/charts/area.min.js +1 -0
  9. package/dist/charts/bar.d.ts +11 -0
  10. package/dist/charts/bar.d.ts.map +1 -0
  11. package/dist/charts/bar.js +65 -0
  12. package/dist/charts/bar.min.js +1 -0
  13. package/dist/charts/boids.js +167 -0
  14. package/dist/charts/boids.min.js +18 -0
  15. package/dist/charts/candlestick.d.ts +21 -0
  16. package/dist/charts/candlestick.d.ts.map +1 -0
  17. package/dist/charts/candlestick.js +10 -0
  18. package/dist/charts/candlestick.min.js +1 -0
  19. package/dist/charts/experimental/baseline-area.js +70 -0
  20. package/dist/charts/experimental/baseline-area.min.js +1 -0
  21. package/dist/charts/experimental/bubble.js +48 -0
  22. package/dist/charts/experimental/bubble.min.js +1 -0
  23. package/dist/charts/experimental/error-band.js +111 -0
  24. package/dist/charts/experimental/error-band.min.js +1 -0
  25. package/dist/charts/experimental/heatmap.js +69 -0
  26. package/dist/charts/experimental/heatmap.min.js +1 -0
  27. package/dist/charts/experimental/histogram.js +139 -0
  28. package/dist/charts/experimental/histogram.min.js +7 -0
  29. package/dist/charts/experimental/ohlc.js +132 -0
  30. package/dist/charts/experimental/ohlc.min.js +32 -0
  31. package/dist/charts/experimental/step.js +67 -0
  32. package/dist/charts/experimental/step.min.js +1 -0
  33. package/dist/charts/experimental/waterfall.js +121 -0
  34. package/dist/charts/experimental/waterfall.min.js +7 -0
  35. package/dist/charts/line.d.ts +12 -0
  36. package/dist/charts/line.d.ts.map +1 -0
  37. package/dist/charts/line.js +62 -0
  38. package/dist/charts/line.min.js +1 -0
  39. package/dist/charts/scatter.d.ts +11 -0
  40. package/dist/charts/scatter.d.ts.map +1 -0
  41. package/dist/charts/scatter.js +46 -0
  42. package/dist/charts/scatter.min.js +1 -0
  43. package/dist/chunk-0eh4rzy9.min.js +2 -0
  44. package/dist/chunk-0jepamv9.js +7 -0
  45. package/dist/chunk-1ngxm8t2.js +129 -0
  46. package/dist/chunk-50bcv2hw.min.js +2 -0
  47. package/dist/chunk-5gtx3pza.js +9 -0
  48. package/dist/chunk-64q9a7nw.min.js +2 -0
  49. package/dist/chunk-831dem4f.js +4 -0
  50. package/dist/chunk-93yrr7er.js +35 -0
  51. package/dist/chunk-bbyt23tw.min.js +2 -0
  52. package/dist/chunk-cbydth3q.min.js +2 -0
  53. package/dist/chunk-cvtt04m6.min.js +2 -0
  54. package/dist/chunk-g2qmt43n.min.js +33 -0
  55. package/dist/chunk-gm0d4cgx.min.js +2 -0
  56. package/dist/chunk-mmsy3yqt.js +27 -0
  57. package/dist/chunk-n8ew0z0e.js +637 -0
  58. package/dist/chunk-t0kdz02m.js +129 -0
  59. package/dist/chunk-wdfq2fpx.min.js +2 -0
  60. package/dist/chunk-yabjrff2.js +11 -0
  61. package/dist/gpu-worker.js +630 -686
  62. package/dist/gpu-worker.min.js +1 -1
  63. package/dist/msg.d.ts +33 -0
  64. package/dist/msg.d.ts.map +1 -0
  65. package/dist/plugins/coords.d.ts +18 -0
  66. package/dist/plugins/coords.d.ts.map +1 -0
  67. package/dist/plugins/experimental/annotations.js +164 -0
  68. package/dist/plugins/experimental/annotations.min.js +1 -0
  69. package/dist/plugins/experimental/crosshair.js +82 -0
  70. package/dist/plugins/experimental/crosshair.min.js +1 -0
  71. package/dist/plugins/experimental/minimap.js +190 -0
  72. package/dist/plugins/experimental/minimap.min.js +1 -0
  73. package/dist/plugins/experimental/range-selector.js +220 -0
  74. package/dist/plugins/experimental/range-selector.min.js +1 -0
  75. package/dist/plugins/experimental/ruler.js +434 -0
  76. package/dist/plugins/experimental/ruler.min.js +59 -0
  77. package/dist/plugins/experimental/stats.js +229 -0
  78. package/dist/plugins/experimental/stats.min.js +8 -0
  79. package/dist/plugins/experimental/threshold.js +96 -0
  80. package/dist/plugins/experimental/threshold.min.js +1 -0
  81. package/dist/plugins/experimental/tooltip-pin.js +177 -0
  82. package/dist/plugins/experimental/tooltip-pin.min.js +1 -0
  83. package/dist/plugins/experimental/watermark.js +76 -0
  84. package/dist/plugins/experimental/watermark.min.js +1 -0
  85. package/dist/plugins/hover.d.ts +15 -2
  86. package/dist/plugins/hover.d.ts.map +1 -1
  87. package/dist/plugins/hover.js +75 -14
  88. package/dist/plugins/hover.min.js +1 -1
  89. package/dist/plugins/labels-panel.d.ts +4 -0
  90. package/dist/plugins/labels-panel.d.ts.map +1 -0
  91. package/dist/plugins/labels-panel.js +122 -0
  92. package/dist/plugins/labels-panel.min.js +1 -0
  93. package/dist/plugins/labels.d.ts +17 -2
  94. package/dist/plugins/labels.d.ts.map +1 -1
  95. package/dist/plugins/labels.js +11 -99
  96. package/dist/plugins/labels.min.js +1 -1
  97. package/dist/plugins/legend.d.ts +16 -0
  98. package/dist/plugins/legend.d.ts.map +1 -0
  99. package/dist/plugins/legend.js +353 -0
  100. package/dist/plugins/legend.min.js +37 -0
  101. package/dist/plugins/shared.d.ts +7 -0
  102. package/dist/plugins/shared.d.ts.map +1 -0
  103. package/dist/plugins/zoom.d.ts +10 -2
  104. package/dist/plugins/zoom.d.ts.map +1 -1
  105. package/dist/plugins/zoom.js +63 -62
  106. package/dist/plugins/zoom.min.js +1 -1
  107. package/dist/types.d.ts +187 -0
  108. package/dist/types.d.ts.map +1 -0
  109. package/dist/types.js +0 -0
  110. package/dist/types.min.js +0 -0
  111. package/dist/worker-inline.d.ts +1 -1
  112. package/dist/worker-inline.d.ts.map +1 -1
  113. package/package.json +11 -11
  114. package/readme.md +54 -42
  115. package/dist/chunk-bgfkgcmg.js +0 -25
  116. package/dist/chunk-cj3zanvs.min.js +0 -2
@@ -0,0 +1,132 @@
1
+ import {
2
+ CANDLESTICK_COMPUTE_SHADER,
3
+ packRGB
4
+ } from "../../chunk-t0kdz02m.js";
5
+ import {
6
+ COMPUTE_WG,
7
+ UNIFORM_STRUCT
8
+ } from "../../chunk-0jepamv9.js";
9
+ import"../../chunk-5gtx3pza.js";
10
+
11
+ // src/shaders/experimental/ohlc.ts
12
+ var CANDLE_TYPES = `
13
+ struct CandleUniforms {
14
+ maxSamples: f32,
15
+ upColor: u32,
16
+ downColor: u32,
17
+ binSize: u32,
18
+ interval: f32,
19
+ _p0: u32, _p1: u32, _p2: u32,
20
+ };
21
+ struct CandleData {
22
+ screenX: f32,
23
+ barWidth: f32,
24
+ low: f32,
25
+ bodyBottom: f32,
26
+ bodyTop: f32,
27
+ high: f32,
28
+ isUp: f32,
29
+ };`;
30
+ var EFFECTIVE_INTERVAL = `
31
+ fn effectiveInterval() -> f32 {
32
+ if (cu.interval > 0.0) { return cu.interval; }
33
+ let raw = (u.viewMaxX - u.viewMinX) / u.width * f32(cu.binSize);
34
+ let steps = array<f32, 20>(
35
+ 1.0, 2.0, 5.0, 10.0, 15.0, 30.0,
36
+ 60.0, 120.0, 300.0, 600.0, 900.0, 1800.0,
37
+ 3600.0, 7200.0, 14400.0, 43200.0,
38
+ 86400.0, 259200.0, 604800.0, 2592000.0
39
+ );
40
+ for (var i = 0u; i < 20u; i++) {
41
+ if (steps[i] >= raw) { return steps[i]; }
42
+ }
43
+ return raw;
44
+ }`;
45
+ var OHLC_RENDER_SHADER = `${UNIFORM_STRUCT}${CANDLE_TYPES}@group(0)@binding(0)var<uniform> u: Uniforms;@group(0)@binding(1)var<storage,read> candleData: array<CandleData>;@group(0)@binding(2)var<uniform> cu: CandleUniforms;${EFFECTIVE_INTERVAL}struct VertexOutput{@builtin(position)pos: vec4f,@location(0)@interpolate(flat)isUp: f32,};@vertex fn vs(@builtin(vertex_index)vi: u32)-> VertexOutput{var out: VertexOutput;let viewRangeX = u.viewMaxX - u.viewMinX;let interval = effectiveInterval();let numBins = min(u32(ceil(viewRangeX / interval))+ 2u,u32(u.width));let colIdx = vi / 18u;let localVi = vi % 18u;let section = localVi / 6u;let vertexType = localVi % 6u;if(colIdx >= numBins){out.pos = vec4f(0.0,0.0,0.0,0.0);out.isUp = 0.0;return out;}let cd = candleData[colIdx];if(cd.barWidth <= 0.0){out.pos = vec4f(0.0,0.0,0.0,0.0);out.isUp = 0.0;return out;}out.isUp = cd.isUp;let viewRangeY = u.viewMaxY - u.viewMinY;let safeRangeY = select(viewRangeY,1.0,viewRangeY < 0.0001);let onePixelX = 1.0 / u.width;let onePixelY = 1.0 / u.height;let wickWidth = max(onePixelX,cd.barWidth * 0.07);let tickHalfH = max(onePixelY,wickWidth * u.width / u.height);let openPrice = select(cd.bodyTop,cd.bodyBottom,cd.isUp > 0.5);let closePrice = select(cd.bodyBottom,cd.bodyTop,cd.isUp > 0.5);var sLeft: f32;var sRight: f32;var sTop: f32;var sBottom: f32;if(section == 0u){let nb =(cd.low - u.viewMinY)/ safeRangeY;let nt =(cd.high - u.viewMinY)/ safeRangeY;sBottom = 1.0 - nb;sTop = 1.0 - nt;sLeft = cd.screenX - wickWidth;sRight = cd.screenX + wickWidth;}else if(section == 1u){let ny =(openPrice - u.viewMinY)/ safeRangeY;let sy = 1.0 - ny;sTop = sy - tickHalfH;sBottom = sy + tickHalfH;sLeft = cd.screenX - cd.barWidth * 0.45;sRight = cd.screenX;}else{let ny =(closePrice - u.viewMinY)/ safeRangeY;let sy = 1.0 - ny;sTop = sy - tickHalfH;sBottom = sy + tickHalfH;sLeft = cd.screenX;sRight = cd.screenX + cd.barWidth * 0.45;}var positions = array<vec2f,6>(vec2f(sLeft,sBottom),vec2f(sRight,sBottom),vec2f(sLeft,sTop),vec2f(sLeft,sTop),vec2f(sRight,sBottom),vec2f(sRight,sTop));let sp = positions[vertexType];out.pos = vec4f(sp.x * 2.0 - 1.0,1.0 - sp.y * 2.0,0.0,1.0);return out;}@fragment fn fs(in: VertexOutput)-> @location(0)vec4f{let upRgb = unpack4x8unorm(cu.upColor).rgb;let downRgb = unpack4x8unorm(cu.downColor).rgb;let color = select(downRgb,upRgb,in.isUp > 0.5);return vec4f(color,0.92);}`;
46
+
47
+ // src/charts/experimental/ohlc.ts
48
+ var BYTES_PER_CANDLE = 7 * 4;
49
+ var OhlcChart = {
50
+ name: "ohlc",
51
+ shaders: {
52
+ compute: CANDLESTICK_COMPUTE_SHADER,
53
+ render: OHLC_RENDER_SHADER
54
+ },
55
+ uniforms: [
56
+ { name: "maxSamples", type: "f32", default: 1e4 },
57
+ { name: "upColor", type: "u32", default: packRGB(0.2, 0.7, 0.3) },
58
+ { name: "downColor", type: "u32", default: packRGB(0.9, 0.3, 0.3) },
59
+ { name: "binSize", type: "u32", default: 8 },
60
+ { name: "interval", type: "f32", default: 0 }
61
+ ],
62
+ buffers: [
63
+ {
64
+ name: "candleBuffer",
65
+ bytes: ({ width }) => Math.max(16, width * BYTES_PER_CANDLE),
66
+ usages: ["STORAGE"]
67
+ }
68
+ ],
69
+ passes: [
70
+ {
71
+ type: "compute",
72
+ shader: "compute",
73
+ perSeries: true,
74
+ dispatch: ({ width }) => ({ x: Math.ceil(Math.max(1, width) / COMPUTE_WG) }),
75
+ bindings: [
76
+ { binding: 0, source: "uniforms" },
77
+ { binding: 1, source: "x-data" },
78
+ { binding: 2, source: "y-data" },
79
+ { binding: 3, source: "candleBuffer", write: true },
80
+ { binding: 4, source: "series-info" },
81
+ { binding: 5, source: "series-index" },
82
+ { binding: 6, source: "custom-uniforms" },
83
+ { binding: 7, source: "open-data" },
84
+ { binding: 8, source: "high-data" },
85
+ { binding: 9, source: "low-data" }
86
+ ]
87
+ },
88
+ {
89
+ type: "render",
90
+ shader: "render",
91
+ topology: "triangle-list",
92
+ loadOp: "load",
93
+ blend: {
94
+ color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha" },
95
+ alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha" }
96
+ },
97
+ draw: ({ width }) => width * 18,
98
+ bindings: [
99
+ { binding: 0, source: "uniforms" },
100
+ { binding: 1, source: "candleBuffer" },
101
+ { binding: 2, source: "custom-uniforms" }
102
+ ]
103
+ }
104
+ ],
105
+ computeBounds(series) {
106
+ let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
107
+ for (const s of series) {
108
+ for (const x of s.rawX) {
109
+ if (x < minX)
110
+ minX = x;
111
+ if (x > maxX)
112
+ maxX = x;
113
+ }
114
+ for (const y of s.extra.high ?? []) {
115
+ if (y > maxY)
116
+ maxY = y;
117
+ }
118
+ for (const y of s.extra.low ?? []) {
119
+ if (y < minY)
120
+ minY = y;
121
+ }
122
+ }
123
+ if (!isFinite(minX))
124
+ return { minX: 0, maxX: 1, minY: 0, maxY: 1 };
125
+ const px = (maxX - minX) * 0.05 || 1;
126
+ const py = (maxY - minY) * 0.1 || 1;
127
+ return { minX: minX - px, maxX: maxX + px, minY: minY - py, maxY: maxY + py };
128
+ }
129
+ };
130
+ export {
131
+ OhlcChart
132
+ };
@@ -0,0 +1,32 @@
1
+ import{a as Q,b as Z}from"../../chunk-g2qmt43n.js";import{f as g,g as z}from"../../chunk-64q9a7nw.js";import"../../chunk-bbyt23tw.js";var V=`
2
+ struct CandleUniforms {
3
+ maxSamples: f32,
4
+ upColor: u32,
5
+ downColor: u32,
6
+ binSize: u32,
7
+ interval: f32,
8
+ _p0: u32, _p1: u32, _p2: u32,
9
+ };
10
+ struct CandleData {
11
+ screenX: f32,
12
+ barWidth: f32,
13
+ low: f32,
14
+ bodyBottom: f32,
15
+ bodyTop: f32,
16
+ high: f32,
17
+ isUp: f32,
18
+ };`,B=`
19
+ fn effectiveInterval() -> f32 {
20
+ if (cu.interval > 0.0) { return cu.interval; }
21
+ let raw = (u.viewMaxX - u.viewMinX) / u.width * f32(cu.binSize);
22
+ let steps = array<f32, 20>(
23
+ 1.0, 2.0, 5.0, 10.0, 15.0, 30.0,
24
+ 60.0, 120.0, 300.0, 600.0, 900.0, 1800.0,
25
+ 3600.0, 7200.0, 14400.0, 43200.0,
26
+ 86400.0, 259200.0, 604800.0, 2592000.0
27
+ );
28
+ for (var i = 0u; i < 20u; i++) {
29
+ if (steps[i] >= raw) { return steps[i]; }
30
+ }
31
+ return raw;
32
+ }`,W=`${z}${V}@group(0)@binding(0)var<uniform> u: Uniforms;@group(0)@binding(1)var<storage,read> candleData: array<CandleData>;@group(0)@binding(2)var<uniform> cu: CandleUniforms;${B}struct VertexOutput{@builtin(position)pos: vec4f,@location(0)@interpolate(flat)isUp: f32,};@vertex fn vs(@builtin(vertex_index)vi: u32)-> VertexOutput{var out: VertexOutput;let viewRangeX = u.viewMaxX - u.viewMinX;let interval = effectiveInterval();let numBins = min(u32(ceil(viewRangeX / interval))+ 2u,u32(u.width));let colIdx = vi / 18u;let localVi = vi % 18u;let section = localVi / 6u;let vertexType = localVi % 6u;if(colIdx >= numBins){out.pos = vec4f(0.0,0.0,0.0,0.0);out.isUp = 0.0;return out;}let cd = candleData[colIdx];if(cd.barWidth <= 0.0){out.pos = vec4f(0.0,0.0,0.0,0.0);out.isUp = 0.0;return out;}out.isUp = cd.isUp;let viewRangeY = u.viewMaxY - u.viewMinY;let safeRangeY = select(viewRangeY,1.0,viewRangeY < 0.0001);let onePixelX = 1.0 / u.width;let onePixelY = 1.0 / u.height;let wickWidth = max(onePixelX,cd.barWidth * 0.07);let tickHalfH = max(onePixelY,wickWidth * u.width / u.height);let openPrice = select(cd.bodyTop,cd.bodyBottom,cd.isUp > 0.5);let closePrice = select(cd.bodyBottom,cd.bodyTop,cd.isUp > 0.5);var sLeft: f32;var sRight: f32;var sTop: f32;var sBottom: f32;if(section == 0u){let nb =(cd.low - u.viewMinY)/ safeRangeY;let nt =(cd.high - u.viewMinY)/ safeRangeY;sBottom = 1.0 - nb;sTop = 1.0 - nt;sLeft = cd.screenX - wickWidth;sRight = cd.screenX + wickWidth;}else if(section == 1u){let ny =(openPrice - u.viewMinY)/ safeRangeY;let sy = 1.0 - ny;sTop = sy - tickHalfH;sBottom = sy + tickHalfH;sLeft = cd.screenX - cd.barWidth * 0.45;sRight = cd.screenX;}else{let ny =(closePrice - u.viewMinY)/ safeRangeY;let sy = 1.0 - ny;sTop = sy - tickHalfH;sBottom = sy + tickHalfH;sLeft = cd.screenX;sRight = cd.screenX + cd.barWidth * 0.45;}var positions = array<vec2f,6>(vec2f(sLeft,sBottom),vec2f(sRight,sBottom),vec2f(sLeft,sTop),vec2f(sLeft,sTop),vec2f(sRight,sBottom),vec2f(sRight,sTop));let sp = positions[vertexType];out.pos = vec4f(sp.x * 2.0 - 1.0,1.0 - sp.y * 2.0,0.0,1.0);return out;}@fragment fn fs(in: VertexOutput)-> @location(0)vec4f{let upRgb = unpack4x8unorm(cu.upColor).rgb;let downRgb = unpack4x8unorm(cu.downColor).rgb;let color = select(downRgb,upRgb,in.isUp > 0.5);return vec4f(color,0.92);}`;var F=28,k={name:"ohlc",shaders:{compute:Q,render:W},uniforms:[{name:"maxSamples",type:"f32",default:1e4},{name:"upColor",type:"u32",default:Z(0.2,0.7,0.3)},{name:"downColor",type:"u32",default:Z(0.9,0.3,0.3)},{name:"binSize",type:"u32",default:8},{name:"interval",type:"f32",default:0}],buffers:[{name:"candleBuffer",bytes:({width:j})=>Math.max(16,j*F),usages:["STORAGE"]}],passes:[{type:"compute",shader:"compute",perSeries:!0,dispatch:({width:j})=>({x:Math.ceil(Math.max(1,j)/g)}),bindings:[{binding:0,source:"uniforms"},{binding:1,source:"x-data"},{binding:2,source:"y-data"},{binding:3,source:"candleBuffer",write:!0},{binding:4,source:"series-info"},{binding:5,source:"series-index"},{binding:6,source:"custom-uniforms"},{binding:7,source:"open-data"},{binding:8,source:"high-data"},{binding:9,source:"low-data"}]},{type:"render",shader:"render",topology:"triangle-list",loadOp:"load",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha"}},draw:({width:j})=>j*18,bindings:[{binding:0,source:"uniforms"},{binding:1,source:"candleBuffer"},{binding:2,source:"custom-uniforms"}]}],computeBounds(j){let q=1/0,u=-1/0,v=1/0,J=-1/0;for(let K of j){for(let b of K.rawX){if(b<q)q=b;if(b>u)u=b}for(let b of K.extra.high??[])if(b>J)J=b;for(let b of K.extra.low??[])if(b<v)v=b}if(!isFinite(q))return{minX:0,maxX:1,minY:0,maxY:1};let $=(u-q)*0.05||1,f=(J-v)*0.1||1;return{minX:q-$,maxX:u+$,minY:v-f,maxY:J+f}}};export{k as OhlcChart};
@@ -0,0 +1,67 @@
1
+ import {
2
+ LINE_COMPUTE_SHADER
3
+ } from "../../chunk-yabjrff2.js";
4
+ import {
5
+ COMPUTE_WG,
6
+ UNIFORM_STRUCT
7
+ } from "../../chunk-0jepamv9.js";
8
+ import"../../chunk-5gtx3pza.js";
9
+
10
+ // src/shaders/experimental/step.ts
11
+ var STEP_RENDER_SHADER = `${UNIFORM_STRUCT}struct LineData{screenX: f32,minScreenY: f32,maxScreenY: f32,valid: f32,};struct StepUniforms{maxSamplesPerPixel: u32,stepMode: u32,_p2: u32,_p3: u32,};@group(0)@binding(0)var<uniform> u: Uniforms;@group(0)@binding(1)var<storage,read> lineData: array<LineData>;@group(0)@binding(2)var<storage,read> allSeries: array<SeriesInfo>;@group(0)@binding(3)var<uniform> su: StepUniforms;struct VertexOutput{@builtin(position)pos: vec4f,@location(0)alpha: f32,@location(1)@interpolate(flat)seriesIdx: u32,};@vertex fn vs(@builtin(vertex_index)vi: u32,@builtin(instance_index)series_idx: u32)-> VertexOutput{var out: VertexOutput;out.seriesIdx = series_idx;let maxCols = u32(u.width);let spanVerts = maxCols * 2u;if(vi < spanVerts){let segIdx = vi / 2u;let endpoint = vi % 2u;let d = lineData[segIdx];let y = select(d.maxScreenY,d.minScreenY,endpoint == 0u);out.pos = vec4f(d.screenX * 2.0 - 1.0,1.0 - y * 2.0,0.0,d.valid);out.alpha = d.valid;}else{let connOffset = vi - spanVerts;let connIdx = connOffset / 4u;let localVert = connOffset % 4u;let segInConn = localVert / 2u;let endpoint = localVert % 2u;if(connIdx + 1u >= maxCols){out.pos = vec4f(0.0,0.0,0.0,0.0);out.alpha = 0.0;return out;}let d0 = lineData[connIdx];let d1 = lineData[connIdx + 1u];let segValid = min(d0.valid,d1.valid);let midY0 =(d0.minScreenY + d0.maxScreenY)* 0.5;let midY1 =(d1.minScreenY + d1.maxScreenY)* 0.5;let midX =(d0.screenX + d1.screenX)* 0.5;var px: f32;var py: f32;if(su.stepMode == 0u){if(segInConn == 0u){px = select(d0.screenX,d1.screenX,endpoint == 1u);py = midY0;}else{px = d1.screenX;py = select(midY0,midY1,endpoint == 1u);}}else if(su.stepMode == 1u){if(segInConn == 0u){px = d0.screenX;py = select(midY0,midY1,endpoint == 1u);}else{px = select(d0.screenX,d1.screenX,endpoint == 1u);py = midY1;}}else{if(segInConn == 0u){px = select(d0.screenX,midX,endpoint == 1u);py = midY0;}else{px = midX;py = select(midY0,midY1,endpoint == 1u);}}out.pos = vec4f(px * 2.0 - 1.0,1.0 - py * 2.0,0.0,segValid);out.alpha = segValid;}return out;}@fragment fn fs(in: VertexOutput)-> @location(0)vec4f{if(in.alpha < 0.1){discard;}let series = allSeries[in.seriesIdx];return vec4f(series.color.rgb,1.0);}`;
12
+
13
+ // src/charts/experimental/step.ts
14
+ var StepChart = {
15
+ name: "step",
16
+ shaders: {
17
+ compute: LINE_COMPUTE_SHADER,
18
+ render: STEP_RENDER_SHADER
19
+ },
20
+ uniforms: [
21
+ { name: "maxSamplesPerPixel", type: "u32", default: 1e4 },
22
+ { name: "stepMode", type: "u32", default: 0 }
23
+ ],
24
+ buffers: [
25
+ {
26
+ name: "lineBuffer",
27
+ bytes: ({ width }) => Math.max(16, width * 4 * 4),
28
+ usages: ["STORAGE"]
29
+ }
30
+ ],
31
+ passes: [
32
+ {
33
+ type: "compute",
34
+ shader: "compute",
35
+ perSeries: true,
36
+ dispatch: ({ width }) => ({ x: Math.ceil(Math.max(1, width) / COMPUTE_WG) }),
37
+ bindings: [
38
+ { binding: 0, source: "uniforms" },
39
+ { binding: 1, source: "x-data" },
40
+ { binding: 2, source: "y-data" },
41
+ { binding: 3, source: "lineBuffer", write: true },
42
+ { binding: 4, source: "series-info" },
43
+ { binding: 5, source: "custom-uniforms" }
44
+ ]
45
+ },
46
+ {
47
+ type: "render",
48
+ shader: "render",
49
+ topology: "line-list",
50
+ loadOp: "load",
51
+ blend: {
52
+ color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha" },
53
+ alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha" }
54
+ },
55
+ draw: ({ width }) => Math.max(0, width * 2 + (width - 1) * 4),
56
+ bindings: [
57
+ { binding: 0, source: "uniforms" },
58
+ { binding: 1, source: "lineBuffer" },
59
+ { binding: 2, source: "series-info" },
60
+ { binding: 3, source: "custom-uniforms" }
61
+ ]
62
+ }
63
+ ]
64
+ };
65
+ export {
66
+ StepChart
67
+ };
@@ -0,0 +1 @@
1
+ import{d as n}from"../../chunk-gm0d4cgx.js";import{f as r,g as t}from"../../chunk-64q9a7nw.js";import"../../chunk-bbyt23tw.js";var i=`${t}struct LineData{screenX: f32,minScreenY: f32,maxScreenY: f32,valid: f32,};struct StepUniforms{maxSamplesPerPixel: u32,stepMode: u32,_p2: u32,_p3: u32,};@group(0)@binding(0)var<uniform> u: Uniforms;@group(0)@binding(1)var<storage,read> lineData: array<LineData>;@group(0)@binding(2)var<storage,read> allSeries: array<SeriesInfo>;@group(0)@binding(3)var<uniform> su: StepUniforms;struct VertexOutput{@builtin(position)pos: vec4f,@location(0)alpha: f32,@location(1)@interpolate(flat)seriesIdx: u32,};@vertex fn vs(@builtin(vertex_index)vi: u32,@builtin(instance_index)series_idx: u32)-> VertexOutput{var out: VertexOutput;out.seriesIdx = series_idx;let maxCols = u32(u.width);let spanVerts = maxCols * 2u;if(vi < spanVerts){let segIdx = vi / 2u;let endpoint = vi % 2u;let d = lineData[segIdx];let y = select(d.maxScreenY,d.minScreenY,endpoint == 0u);out.pos = vec4f(d.screenX * 2.0 - 1.0,1.0 - y * 2.0,0.0,d.valid);out.alpha = d.valid;}else{let connOffset = vi - spanVerts;let connIdx = connOffset / 4u;let localVert = connOffset % 4u;let segInConn = localVert / 2u;let endpoint = localVert % 2u;if(connIdx + 1u >= maxCols){out.pos = vec4f(0.0,0.0,0.0,0.0);out.alpha = 0.0;return out;}let d0 = lineData[connIdx];let d1 = lineData[connIdx + 1u];let segValid = min(d0.valid,d1.valid);let midY0 =(d0.minScreenY + d0.maxScreenY)* 0.5;let midY1 =(d1.minScreenY + d1.maxScreenY)* 0.5;let midX =(d0.screenX + d1.screenX)* 0.5;var px: f32;var py: f32;if(su.stepMode == 0u){if(segInConn == 0u){px = select(d0.screenX,d1.screenX,endpoint == 1u);py = midY0;}else{px = d1.screenX;py = select(midY0,midY1,endpoint == 1u);}}else if(su.stepMode == 1u){if(segInConn == 0u){px = d0.screenX;py = select(midY0,midY1,endpoint == 1u);}else{px = select(d0.screenX,d1.screenX,endpoint == 1u);py = midY1;}}else{if(segInConn == 0u){px = select(d0.screenX,midX,endpoint == 1u);py = midY0;}else{px = midX;py = select(midY0,midY1,endpoint == 1u);}}out.pos = vec4f(px * 2.0 - 1.0,1.0 - py * 2.0,0.0,segValid);out.alpha = segValid;}return out;}@fragment fn fs(in: VertexOutput)-> @location(0)vec4f{if(in.alpha < 0.1){discard;}let series = allSeries[in.seriesIdx];return vec4f(series.color.rgb,1.0);}`;var u={name:"step",shaders:{compute:n,render:i},uniforms:[{name:"maxSamplesPerPixel",type:"u32",default:1e4},{name:"stepMode",type:"u32",default:0}],buffers:[{name:"lineBuffer",bytes:({width:e})=>Math.max(16,e*4*4),usages:["STORAGE"]}],passes:[{type:"compute",shader:"compute",perSeries:!0,dispatch:({width:e})=>({x:Math.ceil(Math.max(1,e)/r)}),bindings:[{binding:0,source:"uniforms"},{binding:1,source:"x-data"},{binding:2,source:"y-data"},{binding:3,source:"lineBuffer",write:!0},{binding:4,source:"series-info"},{binding:5,source:"custom-uniforms"}]},{type:"render",shader:"render",topology:"line-list",loadOp:"load",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha"}},draw:({width:e})=>Math.max(0,e*2+(e-1)*4),bindings:[{binding:0,source:"uniforms"},{binding:1,source:"lineBuffer"},{binding:2,source:"series-info"},{binding:3,source:"custom-uniforms"}]}]};export{u as StepChart};
@@ -0,0 +1,121 @@
1
+ import {
2
+ packRGB
3
+ } from "../../chunk-t0kdz02m.js";
4
+ import {
5
+ UNIFORM_STRUCT
6
+ } from "../../chunk-0jepamv9.js";
7
+ import"../../chunk-5gtx3pza.js";
8
+
9
+ // src/shaders/experimental/waterfall.ts
10
+ var WATERFALL_TYPES = `
11
+ struct WaterfallUniforms {
12
+ upColor: u32,
13
+ downColor: u32,
14
+ totalColor: u32,
15
+ _pad: u32,
16
+ };`;
17
+ var WATERFALL_RENDER_SHADER = `${UNIFORM_STRUCT}${WATERFALL_TYPES}@group(0)@binding(0)var<uniform> u: Uniforms;@group(0)@binding(1)var<storage,read> dataX: array<f32>;@group(0)@binding(2)var<storage,read> dataY: array<f32>;@group(0)@binding(3)var<uniform> wu: WaterfallUniforms;@group(0)@binding(4)var<storage,read> dataH: array<f32>;@group(0)@binding(5)var<storage,read> dataT: array<f32>;@group(0)@binding(6)var<storage,read> dataBW: array<f32>;struct VertexOutput{@builtin(position)pos: vec4f,@location(0)@interpolate(flat)colorType: f32,};@vertex fn vs(@builtin(vertex_index)vi: u32)-> VertexOutput{var out: VertexOutput;let barIdx = vi / 6u;let vertexType = vi % 6u;let count = u.pointCount;if(barIdx >= count){out.pos = vec4f(0.0,0.0,0.0,1.0);out.colorType = 0.0;return out;}let x = dataX[barIdx];let barBottom = dataY[barIdx];let barHeight = max(dataH[barIdx],0.0);let barTop = barBottom + barHeight;let barWidth = dataBW[barIdx];let viewRangeX = u.viewMaxX - u.viewMinX;let viewRangeY = u.viewMaxY - u.viewMinY;let safeRangeX = select(viewRangeX,1.0,viewRangeX < 0.0001);let safeRangeY = select(viewRangeY,1.0,viewRangeY < 0.0001);let screenX =(x - u.viewMinX)/ safeRangeX;let halfW =(barWidth * 0.5)/ safeRangeX;let left = screenX - halfW;let right = screenX + halfW;let normBottom =(barBottom - u.viewMinY)/ safeRangeY;let normTop =(barTop - u.viewMinY)/ safeRangeY;let sBottom = max(1.0 - normBottom,1.0 - normTop);let sTop = min(1.0 - normBottom,1.0 - normTop);var positions = array<vec2f,6>(vec2f(left,sBottom),vec2f(right,sBottom),vec2f(left,sTop),vec2f(left,sTop),vec2f(right,sBottom),vec2f(right,sTop));let sp = positions[vertexType];out.pos = vec4f(sp.x * 2.0 - 1.0,1.0 - sp.y * 2.0,0.0,1.0);out.colorType = dataT[barIdx];return out;}@fragment fn fs(in: VertexOutput)-> @location(0)vec4f{let upRgb = unpack4x8unorm(wu.upColor).rgb;let downRgb = unpack4x8unorm(wu.downColor).rgb;let totalRgb = unpack4x8unorm(wu.totalColor).rgb;var color: vec3f;if(in.colorType < 0.5){color = upRgb;}else if(in.colorType < 1.5){color = downRgb;}else{color = totalRgb;}return vec4f(color,0.9);}`;
18
+
19
+ // src/charts/experimental/waterfall.ts
20
+ function prepareWaterfall(positions, deltas, totals) {
21
+ const n = deltas.length;
22
+ const y = new Array(n);
23
+ const h = new Array(n);
24
+ const t = new Array(n);
25
+ const bw = new Array(n);
26
+ let running = 0;
27
+ for (let i = 0;i < n; i++) {
28
+ const isTotal = (totals?.[i] ?? 0) > 0.5;
29
+ const delta = deltas[i];
30
+ if (isTotal) {
31
+ y[i] = Math.min(0, running);
32
+ h[i] = Math.abs(running);
33
+ t[i] = 2;
34
+ } else {
35
+ if (delta >= 0) {
36
+ y[i] = running;
37
+ h[i] = delta;
38
+ t[i] = 0;
39
+ } else {
40
+ y[i] = running + delta;
41
+ h[i] = Math.abs(delta);
42
+ t[i] = 1;
43
+ }
44
+ running += delta;
45
+ }
46
+ }
47
+ for (let i = 0;i < n; i++) {
48
+ let spacing;
49
+ if (n <= 1) {
50
+ spacing = 1;
51
+ } else if (i === 0) {
52
+ spacing = positions[1] - positions[0];
53
+ } else if (i === n - 1) {
54
+ spacing = positions[n - 1] - positions[n - 2];
55
+ } else {
56
+ spacing = Math.min(positions[i + 1] - positions[i], positions[i] - positions[i - 1]);
57
+ }
58
+ bw[i] = spacing * 0.8;
59
+ }
60
+ return { x: positions, y, h, t, bw };
61
+ }
62
+ var WaterfallChart = {
63
+ name: "waterfall",
64
+ shaders: { render: WATERFALL_RENDER_SHADER },
65
+ uniforms: [
66
+ { name: "upColor", type: "u32", default: packRGB(0.2, 0.7, 0.3) },
67
+ { name: "downColor", type: "u32", default: packRGB(0.9, 0.3, 0.3) },
68
+ { name: "totalColor", type: "u32", default: packRGB(0.5, 0.5, 0.6) }
69
+ ],
70
+ passes: [
71
+ {
72
+ type: "render",
73
+ shader: "render",
74
+ topology: "triangle-list",
75
+ loadOp: "load",
76
+ perSeries: true,
77
+ blend: {
78
+ color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha" },
79
+ alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha" }
80
+ },
81
+ draw: ({ samples }) => Math.max(0, samples * 6),
82
+ bindings: [
83
+ { binding: 0, source: "uniforms" },
84
+ { binding: 1, source: "x-data" },
85
+ { binding: 2, source: "y-data" },
86
+ { binding: 3, source: "custom-uniforms" },
87
+ { binding: 4, source: "h-data" },
88
+ { binding: 5, source: "t-data" },
89
+ { binding: 6, source: "bw-data" }
90
+ ]
91
+ }
92
+ ],
93
+ computeBounds(series) {
94
+ let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
95
+ for (const s of series) {
96
+ for (let i = 0;i < s.rawX.length; i++) {
97
+ const x = s.rawX[i];
98
+ const barBottom = s.rawY[i];
99
+ const barHeight = s.extra["h"]?.[i] ?? 0;
100
+ const barTop = barBottom + barHeight;
101
+ if (x < minX)
102
+ minX = x;
103
+ if (x > maxX)
104
+ maxX = x;
105
+ if (barBottom < minY)
106
+ minY = barBottom;
107
+ if (barTop > maxY)
108
+ maxY = barTop;
109
+ }
110
+ }
111
+ if (!isFinite(minX))
112
+ return { minX: 0, maxX: 1, minY: 0, maxY: 1 };
113
+ const px = (maxX - minX) * 0.05 || 1;
114
+ const py = (maxY - minY) * 0.1 || 0.1;
115
+ return { minX: minX - px, maxX: maxX + px, minY: minY - py, maxY: maxY + py };
116
+ }
117
+ };
118
+ export {
119
+ prepareWaterfall,
120
+ WaterfallChart
121
+ };
@@ -0,0 +1,7 @@
1
+ import{b as M}from"../../chunk-g2qmt43n.js";import{g as P}from"../../chunk-64q9a7nw.js";import"../../chunk-bbyt23tw.js";var D=`
2
+ struct WaterfallUniforms {
3
+ upColor: u32,
4
+ downColor: u32,
5
+ totalColor: u32,
6
+ _pad: u32,
7
+ };`,f=`${P}${D}@group(0)@binding(0)var<uniform> u: Uniforms;@group(0)@binding(1)var<storage,read> dataX: array<f32>;@group(0)@binding(2)var<storage,read> dataY: array<f32>;@group(0)@binding(3)var<uniform> wu: WaterfallUniforms;@group(0)@binding(4)var<storage,read> dataH: array<f32>;@group(0)@binding(5)var<storage,read> dataT: array<f32>;@group(0)@binding(6)var<storage,read> dataBW: array<f32>;struct VertexOutput{@builtin(position)pos: vec4f,@location(0)@interpolate(flat)colorType: f32,};@vertex fn vs(@builtin(vertex_index)vi: u32)-> VertexOutput{var out: VertexOutput;let barIdx = vi / 6u;let vertexType = vi % 6u;let count = u.pointCount;if(barIdx >= count){out.pos = vec4f(0.0,0.0,0.0,1.0);out.colorType = 0.0;return out;}let x = dataX[barIdx];let barBottom = dataY[barIdx];let barHeight = max(dataH[barIdx],0.0);let barTop = barBottom + barHeight;let barWidth = dataBW[barIdx];let viewRangeX = u.viewMaxX - u.viewMinX;let viewRangeY = u.viewMaxY - u.viewMinY;let safeRangeX = select(viewRangeX,1.0,viewRangeX < 0.0001);let safeRangeY = select(viewRangeY,1.0,viewRangeY < 0.0001);let screenX =(x - u.viewMinX)/ safeRangeX;let halfW =(barWidth * 0.5)/ safeRangeX;let left = screenX - halfW;let right = screenX + halfW;let normBottom =(barBottom - u.viewMinY)/ safeRangeY;let normTop =(barTop - u.viewMinY)/ safeRangeY;let sBottom = max(1.0 - normBottom,1.0 - normTop);let sTop = min(1.0 - normBottom,1.0 - normTop);var positions = array<vec2f,6>(vec2f(left,sBottom),vec2f(right,sBottom),vec2f(left,sTop),vec2f(left,sTop),vec2f(right,sBottom),vec2f(right,sTop));let sp = positions[vertexType];out.pos = vec4f(sp.x * 2.0 - 1.0,1.0 - sp.y * 2.0,0.0,1.0);out.colorType = dataT[barIdx];return out;}@fragment fn fs(in: VertexOutput)-> @location(0)vec4f{let upRgb = unpack4x8unorm(wu.upColor).rgb;let downRgb = unpack4x8unorm(wu.downColor).rgb;let totalRgb = unpack4x8unorm(wu.totalColor).rgb;var color: vec3f;if(in.colorType < 0.5){color = upRgb;}else if(in.colorType < 1.5){color = downRgb;}else{color = totalRgb;}return vec4f(color,0.9);}`;function F(v,Q,I){let q=Q.length,K=Array(q),V=Array(q),Z=Array(q),$=Array(q),z=0;for(let j=0;j<q;j++){let J=(I?.[j]??0)>0.5,C=Q[j];if(J)K[j]=Math.min(0,z),V[j]=Math.abs(z),Z[j]=2;else{if(C>=0)K[j]=z,V[j]=C,Z[j]=0;else K[j]=z+C,V[j]=Math.abs(C),Z[j]=1;z+=C}}for(let j=0;j<q;j++){let J;if(q<=1)J=1;else if(j===0)J=v[1]-v[0];else if(j===q-1)J=v[q-1]-v[q-2];else J=Math.min(v[j+1]-v[j],v[j]-v[j-1]);$[j]=J*0.8}return{x:v,y:K,h:V,t:Z,bw:$}}var G={name:"waterfall",shaders:{render:f},uniforms:[{name:"upColor",type:"u32",default:M(0.2,0.7,0.3)},{name:"downColor",type:"u32",default:M(0.9,0.3,0.3)},{name:"totalColor",type:"u32",default:M(0.5,0.5,0.6)}],passes:[{type:"render",shader:"render",topology:"triangle-list",loadOp:"load",perSeries:!0,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha"}},draw:({samples:v})=>Math.max(0,v*6),bindings:[{binding:0,source:"uniforms"},{binding:1,source:"x-data"},{binding:2,source:"y-data"},{binding:3,source:"custom-uniforms"},{binding:4,source:"h-data"},{binding:5,source:"t-data"},{binding:6,source:"bw-data"}]}],computeBounds(v){let Q=1/0,I=-1/0,q=1/0,K=-1/0;for(let $ of v)for(let z=0;z<$.rawX.length;z++){let j=$.rawX[z],J=$.rawY[z],C=$.extra.h?.[z]??0,O=J+C;if(j<Q)Q=j;if(j>I)I=j;if(J<q)q=J;if(O>K)K=O}if(!isFinite(Q))return{minX:0,maxX:1,minY:0,maxY:1};let V=(I-Q)*0.05||1,Z=(K-q)*0.1||0.1;return{minX:Q-V,maxX:I+V,minY:q-Z,maxY:K+Z}}};export{F as prepareWaterfall,G as WaterfallChart};
@@ -0,0 +1,12 @@
1
+ import type { RendererPlugin } from "../types.ts";
2
+ export interface LineConfig {
3
+ pointSize?: number;
4
+ maxSamplesPerPixel?: number;
5
+ }
6
+ declare module "../types.ts" {
7
+ interface ChartTypeRegistry {
8
+ line: LineConfig;
9
+ }
10
+ }
11
+ export declare const LineChart: RendererPlugin;
12
+ //# sourceMappingURL=line.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line.d.ts","sourceRoot":"","sources":["../../src/charts/line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,iBAAiB;QACzB,IAAI,EAAE,UAAU,CAAC;KAClB;CACF;AAED,eAAO,MAAM,SAAS,EAAE,cAiDvB,CAAC"}
@@ -0,0 +1,62 @@
1
+ import {
2
+ LINE_COMPUTE_SHADER,
3
+ LINE_RENDER_SHADER
4
+ } from "../chunk-yabjrff2.js";
5
+ import {
6
+ COMPUTE_WG
7
+ } from "../chunk-0jepamv9.js";
8
+ import"../chunk-5gtx3pza.js";
9
+
10
+ // src/charts/line.ts
11
+ var LineChart = {
12
+ name: "line",
13
+ shaders: {
14
+ compute: LINE_COMPUTE_SHADER,
15
+ render: LINE_RENDER_SHADER
16
+ },
17
+ uniforms: [
18
+ { name: "maxSamplesPerPixel", type: "u32", default: 1e4 }
19
+ ],
20
+ buffers: [
21
+ {
22
+ name: "lineBuffer",
23
+ bytes: ({ width }) => Math.max(16, width * 4 * 4),
24
+ usages: ["STORAGE"]
25
+ }
26
+ ],
27
+ passes: [
28
+ {
29
+ type: "compute",
30
+ shader: "compute",
31
+ perSeries: true,
32
+ dispatch: ({ width }) => ({ x: Math.ceil(Math.max(1, width) / COMPUTE_WG) }),
33
+ bindings: [
34
+ { binding: 0, source: "uniforms" },
35
+ { binding: 1, source: "x-data" },
36
+ { binding: 2, source: "y-data" },
37
+ { binding: 3, source: "lineBuffer", write: true },
38
+ { binding: 4, source: "series-info" },
39
+ { binding: 5, source: "custom-uniforms" }
40
+ ]
41
+ },
42
+ {
43
+ type: "render",
44
+ shader: "render",
45
+ topology: "line-list",
46
+ loadOp: "load",
47
+ blend: {
48
+ color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha" },
49
+ alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha" }
50
+ },
51
+ draw: ({ width }) => Math.max(0, width * 4 - 2),
52
+ bindings: [
53
+ { binding: 0, source: "uniforms" },
54
+ { binding: 1, source: "lineBuffer" },
55
+ { binding: 2, source: "series-info" }
56
+ ]
57
+ }
58
+ ]
59
+ };
60
+ export {
61
+ LineChart
62
+ };
@@ -0,0 +1 @@
1
+ import{d as k,e as q}from"../chunk-gm0d4cgx.js";import{f as j}from"../chunk-64q9a7nw.js";import"../chunk-bbyt23tw.js";var F={name:"line",shaders:{compute:k,render:q},uniforms:[{name:"maxSamplesPerPixel",type:"u32",default:1e4}],buffers:[{name:"lineBuffer",bytes:({width:b})=>Math.max(16,b*4*4),usages:["STORAGE"]}],passes:[{type:"compute",shader:"compute",perSeries:!0,dispatch:({width:b})=>({x:Math.ceil(Math.max(1,b)/j)}),bindings:[{binding:0,source:"uniforms"},{binding:1,source:"x-data"},{binding:2,source:"y-data"},{binding:3,source:"lineBuffer",write:!0},{binding:4,source:"series-info"},{binding:5,source:"custom-uniforms"}]},{type:"render",shader:"render",topology:"line-list",loadOp:"load",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha"}},draw:({width:b})=>Math.max(0,b*4-2),bindings:[{binding:0,source:"uniforms"},{binding:1,source:"lineBuffer"},{binding:2,source:"series-info"}]}]};export{F as LineChart};
@@ -0,0 +1,11 @@
1
+ import type { RendererPlugin } from "../types.ts";
2
+ export interface ScatterConfig {
3
+ pointSize?: number;
4
+ }
5
+ declare module "../types.ts" {
6
+ interface ChartTypeRegistry {
7
+ scatter: ScatterConfig;
8
+ }
9
+ }
10
+ export declare const ScatterChart: RendererPlugin;
11
+ //# sourceMappingURL=scatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scatter.d.ts","sourceRoot":"","sources":["../../src/charts/scatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,iBAAiB;QACzB,OAAO,EAAE,aAAa,CAAC;KACxB;CACF;AAID,eAAO,MAAM,YAAY,EAAE,cA+B1B,CAAC"}
@@ -0,0 +1,46 @@
1
+ import {
2
+ COMPUTE_WG,
3
+ UNIFORM_STRUCT
4
+ } from "../chunk-0jepamv9.js";
5
+ import"../chunk-5gtx3pza.js";
6
+
7
+ // src/shaders/scatter.ts
8
+ var SCATTER_COMPUTE_SHADER = `${UNIFORM_STRUCT}struct ScatterUniforms{dispatchXCount: u32,pointSize: f32};@group(0)@binding(0)var<uniform> u: Uniforms;@group(0)@binding(1)var<storage,read> dataX: array<f32>;@group(0)@binding(2)var<storage,read> dataY: array<f32>;@group(0)@binding(3)var outputTex: texture_storage_2d<rgba8unorm,write>;@group(0)@binding(4)var<storage,read> allSeries: array<SeriesInfo>;@group(0)@binding(5)var<uniform> seriesIdx: SeriesIndex;@group(0)@binding(6)var<uniform> su: ScatterUniforms;@compute @workgroup_size(${COMPUTE_WG})fn main(@builtin(global_invocation_id)id: vec3u){let series = allSeries[seriesIdx.index];let visStart = series.visibleRange.x;let visCount = series.visibleRange.y;let localIdx = id.y * su.dispatchXCount + id.x;if(localIdx >= visCount){return;}let idx = visStart + localIdx;let count = u.pointCount;if(idx >= count){return;}let x = dataX[idx];let y = dataY[idx];if(y < u.viewMinY || y > u.viewMaxY){return;}let width = u32(u.width);let height = u32(u.height);let rangeX = u.viewMaxX - u.viewMinX;let rangeY = u.viewMaxY - u.viewMinY;if(rangeX < 0.0001 || rangeY < 0.0001){return;}let normX =(x - u.viewMinX)/ rangeX;let normY =(y - u.viewMinY)/ rangeY;let screenX = normX;let screenY = 1.0 - normY;let pixelX = i32(screenX * f32(width));let pixelY = i32(screenY * f32(height));if(idx > visStart){let prevX = dataX[idx - 1u];let prevY = dataY[idx - 1u];let prevNormX =(prevX - u.viewMinX)/ rangeX;let prevNormY =(prevY - u.viewMinY)/ rangeY;let prevPx = i32(prevNormX * f32(width));let prevPy = i32((1.0 - prevNormY)* f32(height));if(pixelX == prevPx && pixelY == prevPy){return;}}let iWidth = i32(width);let iHeight = i32(height);if(pixelX < 0 || pixelX >= iWidth){return;}if(pixelY < 0 || pixelY >= iHeight){return;}let color = series.color;let radius = i32(su.pointSize);for(var dy = -radius;dy <= radius;dy++){for(var dx = -radius;dx <= radius;dx++){if(dx * dx + dy * dy > radius * radius){continue;}let px = pixelX + dx;let py = pixelY + dy;if(px >= 0 && px < iWidth && py >= 0 && py < iHeight){textureStore(outputTex,vec2i(px,py),color);}}}}`;
9
+
10
+ // src/charts/scatter.ts
11
+ var MAX_WG_DIM = 65535;
12
+ var ScatterChart = {
13
+ name: "scatter",
14
+ shaders: {
15
+ compute: SCATTER_COMPUTE_SHADER
16
+ },
17
+ uniforms: [
18
+ { name: "dispatchXCount", type: "u32", default: 1 },
19
+ { name: "pointSize", type: "f32", default: 3 }
20
+ ],
21
+ passes: [
22
+ {
23
+ type: "compute",
24
+ shader: "compute",
25
+ perSeries: true,
26
+ dispatch: ({ samples }) => {
27
+ const totalWG = Math.ceil(Math.max(1, samples) / COMPUTE_WG);
28
+ const wgX = Math.min(totalWG, MAX_WG_DIM);
29
+ const wgY = Math.ceil(totalWG / MAX_WG_DIM);
30
+ return { x: wgX, y: wgY, xCount: wgX * COMPUTE_WG };
31
+ },
32
+ bindings: [
33
+ { binding: 0, source: "uniforms" },
34
+ { binding: 1, source: "x-data" },
35
+ { binding: 2, source: "y-data" },
36
+ { binding: 3, source: "render-target", write: true },
37
+ { binding: 4, source: "series-info" },
38
+ { binding: 5, source: "series-index" },
39
+ { binding: 6, source: "custom-uniforms" }
40
+ ]
41
+ }
42
+ ]
43
+ };
44
+ export {
45
+ ScatterChart
46
+ };
@@ -0,0 +1 @@
1
+ import{f as e,g as t}from"../chunk-64q9a7nw.js";import"../chunk-bbyt23tw.js";var n=`${t}struct ScatterUniforms{dispatchXCount: u32,pointSize: f32};@group(0)@binding(0)var<uniform> u: Uniforms;@group(0)@binding(1)var<storage,read> dataX: array<f32>;@group(0)@binding(2)var<storage,read> dataY: array<f32>;@group(0)@binding(3)var outputTex: texture_storage_2d<rgba8unorm,write>;@group(0)@binding(4)var<storage,read> allSeries: array<SeriesInfo>;@group(0)@binding(5)var<uniform> seriesIdx: SeriesIndex;@group(0)@binding(6)var<uniform> su: ScatterUniforms;@compute @workgroup_size(${e})fn main(@builtin(global_invocation_id)id: vec3u){let series = allSeries[seriesIdx.index];let visStart = series.visibleRange.x;let visCount = series.visibleRange.y;let localIdx = id.y * su.dispatchXCount + id.x;if(localIdx >= visCount){return;}let idx = visStart + localIdx;let count = u.pointCount;if(idx >= count){return;}let x = dataX[idx];let y = dataY[idx];if(y < u.viewMinY || y > u.viewMaxY){return;}let width = u32(u.width);let height = u32(u.height);let rangeX = u.viewMaxX - u.viewMinX;let rangeY = u.viewMaxY - u.viewMinY;if(rangeX < 0.0001 || rangeY < 0.0001){return;}let normX =(x - u.viewMinX)/ rangeX;let normY =(y - u.viewMinY)/ rangeY;let screenX = normX;let screenY = 1.0 - normY;let pixelX = i32(screenX * f32(width));let pixelY = i32(screenY * f32(height));if(idx > visStart){let prevX = dataX[idx - 1u];let prevY = dataY[idx - 1u];let prevNormX =(prevX - u.viewMinX)/ rangeX;let prevNormY =(prevY - u.viewMinY)/ rangeY;let prevPx = i32(prevNormX * f32(width));let prevPy = i32((1.0 - prevNormY)* f32(height));if(pixelX == prevPx && pixelY == prevPy){return;}}let iWidth = i32(width);let iHeight = i32(height);if(pixelX < 0 || pixelX >= iWidth){return;}if(pixelY < 0 || pixelY >= iHeight){return;}let color = series.color;let radius = i32(su.pointSize);for(var dy = -radius;dy <= radius;dy++){for(var dx = -radius;dx <= radius;dx++){if(dx * dx + dy * dy > radius * radius){continue;}let px = pixelX + dx;let py = pixelY + dy;if(px >= 0 && px < iWidth && py >= 0 && py < iHeight){textureStore(outputTex,vec2i(px,py),color);}}}}`;var a=65535,g={name:"scatter",shaders:{compute:n},uniforms:[{name:"dispatchXCount",type:"u32",default:1},{name:"pointSize",type:"f32",default:3}],passes:[{type:"compute",shader:"compute",perSeries:!0,dispatch:({samples:o})=>{let i=Math.ceil(Math.max(1,o)/e),r=Math.min(i,a),u=Math.ceil(i/a);return{x:r,y:u,xCount:r*e}},bindings:[{binding:0,source:"uniforms"},{binding:1,source:"x-data"},{binding:2,source:"y-data"},{binding:3,source:"render-target",write:!0},{binding:4,source:"series-info"},{binding:5,source:"series-index"},{binding:6,source:"custom-uniforms"}]}]};export{g as ScatterChart};
@@ -0,0 +1,2 @@
1
+ var t={left:55,right:10,top:8,bottom:45};
2
+ export{t as o};
@@ -0,0 +1,7 @@
1
+ // src/shaders/shared.ts
2
+ var COMPUTE_WG = 256;
3
+ var UNIFORM_STRUCT = `struct Uniforms{width: f32,height: f32,viewMinX: f32,viewMaxX: f32,viewMinY: f32,viewMaxY: f32,pointCount: u32,seriesCount: u32,isDark: u32,bgR: f32,bgG: f32,bgB: f32,dataMinX: f32,dataMaxX: f32,dataMinY: f32,dataMaxY: f32,};struct SeriesInfo{color: vec4f,visibleRange: vec2u,_pad0: f32,_pad1: f32,};struct SeriesIndex{index: u32,_pad0: u32,_pad1: u32,_pad2: u32,};`;
4
+ var BINARY_SEARCH = `fn lowerBound(val: f32,count: u32)-> u32{var lo = 0u;var hi = count;while(lo < hi){let mid =(lo + hi)/ 2u;if(dataX[mid] < val){lo = mid + 1u;}else{hi = mid;}}return lo;}`;
5
+ var BLIT_SHADER = `fn luma(c:vec4f)->f32{return dot(c.rgb,vec3f(.299,.587,.114));}fn laaa(uv:vec2f,t:texture_2d<f32>,s:sampler)->vec4f{let r=1./vec2f(textureDimensions(t));let m=textureSample(t,s,uv);let n=textureSample(t,s,uv+vec2f(0.,-r.y));let e=textureSample(t,s,uv+vec2f(r.x,0.));let w=textureSample(t,s,uv+vec2f(-r.x,0.));let sv=textureSample(t,s,uv+vec2f(0.,r.y));let lm=luma(m);let ln=luma(n);let le=luma(e);let lw=luma(w);let ls=luma(sv);let lo=min(lm,min(min(ln,ls),min(le,lw)));let hi=max(lm,max(max(ln,ls),max(le,lw)));let rng=hi-lo;if(rng<max(.0833,hi*.166)){return m;}return mix(m,(m+n+e+w+sv)*.2,min(rng*3.,1.));}struct BV{@builtin(position)p:vec4f,@location(0)uv:vec2f}@group(0)@binding(0)var inputTex:texture_2d<f32>;@group(0)@binding(1)var samp:sampler;@vertex fn vs(@builtin(vertex_index)i:u32)->BV{var p=array<vec2f,4>(vec2f(-1,-1),vec2f(1,-1),vec2f(-1,1),vec2f(1,1));var u=array<vec2f,4>(vec2f(0,1),vec2f(1,1),vec2f(0,0),vec2f(1,0));return BV(vec4f(p[i],0,1),u[i]);}@fragment fn fs(v:BV)->@location(0)vec4f{return laaa(v.uv,inputTex,samp);}`;
6
+
7
+ export { COMPUTE_WG, UNIFORM_STRUCT, BINARY_SEARCH, BLIT_SHADER };