chartai 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/chart-library.d.ts +33 -146
  2. package/dist/chart-library.d.ts.map +1 -1
  3. package/dist/chart-library.js +378 -321
  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 +132 -0
  18. package/dist/charts/candlestick.min.js +32 -0
  19. package/dist/charts/line.d.ts +12 -0
  20. package/dist/charts/line.d.ts.map +1 -0
  21. package/dist/charts/line.js +62 -0
  22. package/dist/charts/line.min.js +1 -0
  23. package/dist/charts/scatter.d.ts +11 -0
  24. package/dist/charts/scatter.d.ts.map +1 -0
  25. package/dist/charts/scatter.js +46 -0
  26. package/dist/charts/scatter.min.js +1 -0
  27. package/dist/chunk-0jepamv9.js +7 -0
  28. package/dist/chunk-1p45ex5n.min.js +2 -0
  29. package/dist/chunk-831dem4f.js +4 -0
  30. package/dist/chunk-93yrr7er.js +35 -0
  31. package/dist/chunk-94kc81rr.min.js +2 -0
  32. package/dist/chunk-a27be8p9.js +105 -0
  33. package/dist/chunk-bfyv7z27.min.js +2 -0
  34. package/dist/chunk-dmaxrg6s.min.js +2 -0
  35. package/dist/chunk-e7d3zgw5.min.js +2 -0
  36. package/dist/chunk-g6m56ptf.js +609 -0
  37. package/dist/chunk-m17t3vjq.js +9 -0
  38. package/dist/chunk-me3qaz3m.min.js +2 -0
  39. package/dist/chunk-qr6mweck.min.js +2 -0
  40. package/dist/chunk-yabjrff2.js +11 -0
  41. package/dist/gpu-worker.js +625 -686
  42. package/dist/gpu-worker.min.js +1 -1
  43. package/dist/msg.d.ts +33 -0
  44. package/dist/msg.d.ts.map +1 -0
  45. package/dist/plugins/coords.d.ts +18 -0
  46. package/dist/plugins/coords.d.ts.map +1 -0
  47. package/dist/plugins/hover.d.ts +15 -2
  48. package/dist/plugins/hover.d.ts.map +1 -1
  49. package/dist/plugins/hover.js +92 -13
  50. package/dist/plugins/hover.min.js +1 -1
  51. package/dist/plugins/labels-panel.d.ts +4 -0
  52. package/dist/plugins/labels-panel.d.ts.map +1 -0
  53. package/dist/plugins/labels-panel.js +122 -0
  54. package/dist/plugins/labels-panel.min.js +1 -0
  55. package/dist/plugins/labels.d.ts +17 -2
  56. package/dist/plugins/labels.d.ts.map +1 -1
  57. package/dist/plugins/labels.js +11 -99
  58. package/dist/plugins/labels.min.js +1 -1
  59. package/dist/plugins/legend.d.ts +16 -0
  60. package/dist/plugins/legend.d.ts.map +1 -0
  61. package/dist/plugins/legend.js +282 -0
  62. package/dist/plugins/legend.min.js +21 -0
  63. package/dist/plugins/shared.d.ts +7 -0
  64. package/dist/plugins/shared.d.ts.map +1 -0
  65. package/dist/plugins/zoom.d.ts +10 -2
  66. package/dist/plugins/zoom.d.ts.map +1 -1
  67. package/dist/plugins/zoom.js +63 -62
  68. package/dist/plugins/zoom.min.js +1 -1
  69. package/dist/types.d.ts +179 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +0 -0
  72. package/dist/types.min.js +0 -0
  73. package/dist/worker-inline.d.ts +1 -1
  74. package/dist/worker-inline.d.ts.map +1 -1
  75. package/package.json +11 -11
  76. package/readme.md +51 -42
  77. package/dist/chunk-bgfkgcmg.js +0 -25
  78. package/dist/chunk-cj3zanvs.min.js +0 -2
@@ -0,0 +1,132 @@
1
+ import {
2
+ BINARY_SEARCH,
3
+ COMPUTE_WG,
4
+ UNIFORM_STRUCT
5
+ } from "../chunk-0jepamv9.js";
6
+ import"../chunk-m17t3vjq.js";
7
+
8
+ // src/shaders/candlestick.ts
9
+ var CANDLE_TYPES = `
10
+ struct CandleUniforms {
11
+ maxSamples: f32,
12
+ upColor: u32,
13
+ downColor: u32,
14
+ binSize: u32,
15
+ interval: f32,
16
+ _p0: u32, _p1: u32, _p2: u32,
17
+ };
18
+ struct CandleData {
19
+ screenX: f32,
20
+ barWidth: f32,
21
+ low: f32,
22
+ bodyBottom: f32,
23
+ bodyTop: f32,
24
+ high: f32,
25
+ isUp: f32,
26
+ };`;
27
+ var EFFECTIVE_INTERVAL = `
28
+ fn effectiveInterval() -> f32 {
29
+ if (cu.interval > 0.0) { return cu.interval; }
30
+ let raw = (u.viewMaxX - u.viewMinX) / u.width * f32(cu.binSize);
31
+ let steps = array<f32, 20>(
32
+ 1.0, 2.0, 5.0, 10.0, 15.0, 30.0,
33
+ 60.0, 120.0, 300.0, 600.0, 900.0, 1800.0,
34
+ 3600.0, 7200.0, 14400.0, 43200.0,
35
+ 86400.0, 259200.0, 604800.0, 2592000.0
36
+ );
37
+ for (var i = 0u; i < 20u; i++) {
38
+ if (steps[i] >= raw) { return steps[i]; }
39
+ }
40
+ return raw;
41
+ }`;
42
+ var CANDLESTICK_COMPUTE_SHADER = `${UNIFORM_STRUCT}${CANDLE_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> dataClose: array<f32>;@group(0)@binding(3)var<storage,read_write> candleData: array<CandleData>;@group(0)@binding(4)var<storage,read> allSeries: array<SeriesInfo>;@group(0)@binding(5)var<uniform> seriesIdx: SeriesIndex;@group(0)@binding(6)var<uniform> cu: CandleUniforms;@group(0)@binding(7)var<storage,read> dataOpen: array<f32>;@group(0)@binding(8)var<storage,read> dataHigh: array<f32>;@group(0)@binding(9)var<storage,read> dataLow: array<f32>;${BINARY_SEARCH}${EFFECTIVE_INTERVAL}@compute @workgroup_size(${COMPUTE_WG})fn main(@builtin(global_invocation_id)id: vec3u){let binIdx = id.x;let totalPixels = u32(u.width);let count = u.pointCount;if(count == 0u){if(binIdx < totalPixels){candleData[binIdx] = CandleData(0.0,0.0,0.0,0.0,0.0,0.0,0.0);}return;}let viewRangeX = u.viewMaxX - u.viewMinX;let viewRangeY = u.viewMaxY - u.viewMinY;if(viewRangeX < 0.0001 || viewRangeY < 0.0001){if(binIdx < totalPixels){candleData[binIdx] = CandleData(0.0,0.0,0.0,0.0,0.0,0.0,0.0);}return;}let interval = effectiveInterval();let alignedStart = floor(u.viewMinX / interval)* interval;let numBins = min(u32(ceil(viewRangeX / interval))+ 2u,totalPixels);if(binIdx >= numBins){return;}let binMinX = alignedStart + f32(binIdx)* interval;let binMaxX = binMinX + interval;if(binMinX >= u.viewMaxX){candleData[binIdx] = CandleData(0.0,0.0,0.0,0.0,0.0,0.0,0.0);return;}let binMidX = binMinX + interval * 0.5;let screenX =(binMidX - u.viewMinX)/ viewRangeX;let barWidth = interval / viewRangeX;let onePixel = 1.0 / u.width;let bw = max(barWidth * 0.95,onePixel);let startIdx = lowerBound(binMinX,count);var endIdx = lowerBound(binMaxX,count);endIdx = min(endIdx,count);if(startIdx >= endIdx){var bestIdx: u32 = 0u;var bestDist: f32 = 1e10;var hit = false;if(startIdx < count){let bx = dataX[startIdx];let hw = interval * 0.5;if(binMinX < bx + hw && binMaxX > bx - hw){bestIdx = startIdx;bestDist = abs(bx - binMidX);hit = true;}}if(startIdx > 0u){let prev = startIdx - 1u;let bx = dataX[prev];let hw = interval * 0.5;if(binMinX < bx + hw && binMaxX > bx - hw){let d = abs(bx - binMidX);if(!hit || d < bestDist){bestIdx = prev;}hit = true;}}if(!hit){candleData[binIdx] = CandleData(0.0,0.0,0.0,0.0,0.0,0.0,0.0);return;}let o = dataOpen[bestIdx];let h = dataHigh[bestIdx];let l = dataLow[bestIdx];let c = dataClose[bestIdx];candleData[binIdx] = CandleData(screenX,bw,l,min(o,c),max(o,c),h,select(0.0,1.0,c>=o));return;}let o = dataOpen[startIdx];var h = dataHigh[startIdx];var l = dataLow[startIdx];let c = dataClose[endIdx - 1u];let rangeCount = endIdx - startIdx;let maxSamples = u32(cu.maxSamples);if(maxSamples > 0u && rangeCount > maxSamples){let stride = f32(rangeCount - 1u)/ f32(maxSamples - 1u);for(var s = 0u;s < maxSamples;s++){let idx = startIdx + u32(f32(s)* stride);if(idx < endIdx){h = max(h,dataHigh[idx]);l = min(l,dataLow[idx]);}}h = max(h,dataHigh[endIdx - 1u]);l = min(l,dataLow[endIdx - 1u]);}else{for(var i = startIdx;i < endIdx;i++){h = max(h,dataHigh[i]);l = min(l,dataLow[i]);}}candleData[binIdx] = CandleData(screenX,bw,l,min(o,c),max(o,c),h,select(0.0,1.0,c>=o));}`;
43
+ var CANDLESTICK_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,@location(1)@interpolate(flat)isWick: 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 / 30u;let localVi = vi % 30u;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;out.isWick = 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;out.isWick = 0.0;return out;}out.isUp = cd.isUp;out.isWick = select(0.0,1.0,section > 0u);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;var sLeft: f32;var sRight: f32;var sTop: f32;var sBottom: f32;if(section == 0u){let nb =(cd.bodyBottom - u.viewMinY)/ safeRangeY;let nt =(cd.bodyTop - u.viewMinY)/ safeRangeY;sBottom = 1.0 - nb;sTop = 1.0 - nt;let hw = cd.barWidth * 0.5;sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}else if(section == 1u){let nb =(cd.bodyTop - u.viewMinY)/ safeRangeY;let nt =(cd.high - u.viewMinY)/ safeRangeY;sBottom = 1.0 - nb;sTop = 1.0 - nt;let hw = max(onePixelX,cd.barWidth * 0.08);sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}else if(section == 2u){let nb =(cd.low - u.viewMinY)/ safeRangeY;let nt =(cd.bodyBottom - u.viewMinY)/ safeRangeY;sBottom = 1.0 - nb;sTop = 1.0 - nt;let hw = max(onePixelX,cd.barWidth * 0.08);sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}else if(section == 3u){let sy = 1.0 -(cd.high - u.viewMinY)/ safeRangeY;let wickHW = max(onePixelX,cd.barWidth * 0.08);let capHH = wickHW * u.width / u.height;sTop = sy - capHH;sBottom = sy + capHH;let hw = max(onePixelX * 2.0,cd.barWidth * 0.28);sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}else{let sy = 1.0 -(cd.low - u.viewMinY)/ safeRangeY;let wickHW = max(onePixelX,cd.barWidth * 0.08);let capHH = wickHW * u.width / u.height;sTop = sy - capHH;sBottom = sy + capHH;let hw = max(onePixelX * 2.0,cd.barWidth * 0.28);sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}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 base = select(downRgb,upRgb,in.isUp > 0.5);let color = select(base,base * 0.65,in.isWick > 0.5);return vec4f(color,0.92);}`;
44
+
45
+ // src/charts/candlestick.ts
46
+ var packRGB = (r, g, b) => (Math.round(r * 255) & 255 | (Math.round(g * 255) & 255) << 8 | (Math.round(b * 255) & 255) << 16 | 255 << 24) >>> 0;
47
+ var BYTES_PER_CANDLE = 7 * 4;
48
+ var CandlestickChart = {
49
+ name: "candlestick",
50
+ shaders: {
51
+ compute: CANDLESTICK_COMPUTE_SHADER,
52
+ render: CANDLESTICK_RENDER_SHADER
53
+ },
54
+ uniforms: [
55
+ { name: "maxSamples", type: "f32", default: 1e4 },
56
+ { name: "upColor", type: "u32", default: packRGB(0.2, 0.7, 0.3) },
57
+ { name: "downColor", type: "u32", default: packRGB(0.9, 0.3, 0.3) },
58
+ { name: "binSize", type: "u32", default: 8 },
59
+ { name: "interval", type: "f32", default: 0 }
60
+ ],
61
+ buffers: [
62
+ {
63
+ name: "candleBuffer",
64
+ bytes: ({ width }) => Math.max(16, width * BYTES_PER_CANDLE),
65
+ usages: ["STORAGE"]
66
+ }
67
+ ],
68
+ passes: [
69
+ {
70
+ type: "compute",
71
+ shader: "compute",
72
+ perSeries: true,
73
+ dispatch: ({ width }) => ({ x: Math.ceil(Math.max(1, width) / COMPUTE_WG) }),
74
+ bindings: [
75
+ { binding: 0, source: "uniforms" },
76
+ { binding: 1, source: "x-data" },
77
+ { binding: 2, source: "y-data" },
78
+ { binding: 3, source: "candleBuffer", write: true },
79
+ { binding: 4, source: "series-info" },
80
+ { binding: 5, source: "series-index" },
81
+ { binding: 6, source: "custom-uniforms" },
82
+ { binding: 7, source: "open-data" },
83
+ { binding: 8, source: "high-data" },
84
+ { binding: 9, source: "low-data" }
85
+ ]
86
+ },
87
+ {
88
+ type: "render",
89
+ shader: "render",
90
+ topology: "triangle-list",
91
+ loadOp: "load",
92
+ blend: {
93
+ color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha" },
94
+ alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha" }
95
+ },
96
+ draw: ({ width }) => width * 30,
97
+ bindings: [
98
+ { binding: 0, source: "uniforms" },
99
+ { binding: 1, source: "candleBuffer" },
100
+ { binding: 2, source: "custom-uniforms" }
101
+ ]
102
+ }
103
+ ],
104
+ computeBounds(series) {
105
+ let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
106
+ for (const s of series) {
107
+ for (const x of s.rawX) {
108
+ if (x < minX)
109
+ minX = x;
110
+ if (x > maxX)
111
+ maxX = x;
112
+ }
113
+ for (const y of s.extra.high ?? []) {
114
+ if (y > maxY)
115
+ maxY = y;
116
+ }
117
+ for (const y of s.extra.low ?? []) {
118
+ if (y < minY)
119
+ minY = y;
120
+ }
121
+ }
122
+ if (!isFinite(minX))
123
+ return { minX: 0, maxX: 1, minY: 0, maxY: 1 };
124
+ const px = (maxX - minX) * 0.05 || 1;
125
+ const py = (maxY - minY) * 0.1 || 1;
126
+ return { minX: minX - px, maxX: maxX + px, minY: minY - py, maxY: maxY + py };
127
+ }
128
+ };
129
+ export {
130
+ packRGB,
131
+ CandlestickChart
132
+ };
@@ -0,0 +1,32 @@
1
+ import{c as v,d as K,e as H}from"../chunk-dmaxrg6s.js";import"../chunk-me3qaz3m.js";var b=`
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
+ }`,G=`${K}${b}@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> dataClose: array<f32>;@group(0)@binding(3)var<storage,read_write> candleData: array<CandleData>;@group(0)@binding(4)var<storage,read> allSeries: array<SeriesInfo>;@group(0)@binding(5)var<uniform> seriesIdx: SeriesIndex;@group(0)@binding(6)var<uniform> cu: CandleUniforms;@group(0)@binding(7)var<storage,read> dataOpen: array<f32>;@group(0)@binding(8)var<storage,read> dataHigh: array<f32>;@group(0)@binding(9)var<storage,read> dataLow: array<f32>;${H}${B}@compute @workgroup_size(${v})fn main(@builtin(global_invocation_id)id: vec3u){let binIdx = id.x;let totalPixels = u32(u.width);let count = u.pointCount;if(count == 0u){if(binIdx < totalPixels){candleData[binIdx] = CandleData(0.0,0.0,0.0,0.0,0.0,0.0,0.0);}return;}let viewRangeX = u.viewMaxX - u.viewMinX;let viewRangeY = u.viewMaxY - u.viewMinY;if(viewRangeX < 0.0001 || viewRangeY < 0.0001){if(binIdx < totalPixels){candleData[binIdx] = CandleData(0.0,0.0,0.0,0.0,0.0,0.0,0.0);}return;}let interval = effectiveInterval();let alignedStart = floor(u.viewMinX / interval)* interval;let numBins = min(u32(ceil(viewRangeX / interval))+ 2u,totalPixels);if(binIdx >= numBins){return;}let binMinX = alignedStart + f32(binIdx)* interval;let binMaxX = binMinX + interval;if(binMinX >= u.viewMaxX){candleData[binIdx] = CandleData(0.0,0.0,0.0,0.0,0.0,0.0,0.0);return;}let binMidX = binMinX + interval * 0.5;let screenX =(binMidX - u.viewMinX)/ viewRangeX;let barWidth = interval / viewRangeX;let onePixel = 1.0 / u.width;let bw = max(barWidth * 0.95,onePixel);let startIdx = lowerBound(binMinX,count);var endIdx = lowerBound(binMaxX,count);endIdx = min(endIdx,count);if(startIdx >= endIdx){var bestIdx: u32 = 0u;var bestDist: f32 = 1e10;var hit = false;if(startIdx < count){let bx = dataX[startIdx];let hw = interval * 0.5;if(binMinX < bx + hw && binMaxX > bx - hw){bestIdx = startIdx;bestDist = abs(bx - binMidX);hit = true;}}if(startIdx > 0u){let prev = startIdx - 1u;let bx = dataX[prev];let hw = interval * 0.5;if(binMinX < bx + hw && binMaxX > bx - hw){let d = abs(bx - binMidX);if(!hit || d < bestDist){bestIdx = prev;}hit = true;}}if(!hit){candleData[binIdx] = CandleData(0.0,0.0,0.0,0.0,0.0,0.0,0.0);return;}let o = dataOpen[bestIdx];let h = dataHigh[bestIdx];let l = dataLow[bestIdx];let c = dataClose[bestIdx];candleData[binIdx] = CandleData(screenX,bw,l,min(o,c),max(o,c),h,select(0.0,1.0,c>=o));return;}let o = dataOpen[startIdx];var h = dataHigh[startIdx];var l = dataLow[startIdx];let c = dataClose[endIdx - 1u];let rangeCount = endIdx - startIdx;let maxSamples = u32(cu.maxSamples);if(maxSamples > 0u && rangeCount > maxSamples){let stride = f32(rangeCount - 1u)/ f32(maxSamples - 1u);for(var s = 0u;s < maxSamples;s++){let idx = startIdx + u32(f32(s)* stride);if(idx < endIdx){h = max(h,dataHigh[idx]);l = min(l,dataLow[idx]);}}h = max(h,dataHigh[endIdx - 1u]);l = min(l,dataLow[endIdx - 1u]);}else{for(var i = startIdx;i < endIdx;i++){h = max(h,dataHigh[i]);l = min(l,dataLow[i]);}}candleData[binIdx] = CandleData(screenX,bw,l,min(o,c),max(o,c),h,select(0.0,1.0,c>=o));}`,V=`${K}${b}@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,@location(1)@interpolate(flat)isWick: 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 / 30u;let localVi = vi % 30u;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;out.isWick = 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;out.isWick = 0.0;return out;}out.isUp = cd.isUp;out.isWick = select(0.0,1.0,section > 0u);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;var sLeft: f32;var sRight: f32;var sTop: f32;var sBottom: f32;if(section == 0u){let nb =(cd.bodyBottom - u.viewMinY)/ safeRangeY;let nt =(cd.bodyTop - u.viewMinY)/ safeRangeY;sBottom = 1.0 - nb;sTop = 1.0 - nt;let hw = cd.barWidth * 0.5;sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}else if(section == 1u){let nb =(cd.bodyTop - u.viewMinY)/ safeRangeY;let nt =(cd.high - u.viewMinY)/ safeRangeY;sBottom = 1.0 - nb;sTop = 1.0 - nt;let hw = max(onePixelX,cd.barWidth * 0.08);sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}else if(section == 2u){let nb =(cd.low - u.viewMinY)/ safeRangeY;let nt =(cd.bodyBottom - u.viewMinY)/ safeRangeY;sBottom = 1.0 - nb;sTop = 1.0 - nt;let hw = max(onePixelX,cd.barWidth * 0.08);sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}else if(section == 3u){let sy = 1.0 -(cd.high - u.viewMinY)/ safeRangeY;let wickHW = max(onePixelX,cd.barWidth * 0.08);let capHH = wickHW * u.width / u.height;sTop = sy - capHH;sBottom = sy + capHH;let hw = max(onePixelX * 2.0,cd.barWidth * 0.28);sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}else{let sy = 1.0 -(cd.low - u.viewMinY)/ safeRangeY;let wickHW = max(onePixelX,cd.barWidth * 0.08);let capHH = wickHW * u.width / u.height;sTop = sy - capHH;sBottom = sy + capHH;let hw = max(onePixelX * 2.0,cd.barWidth * 0.28);sLeft = cd.screenX - hw;sRight = cd.screenX + hw;}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 base = select(downRgb,upRgb,in.isUp > 0.5);let color = select(base,base * 0.65,in.isWick > 0.5);return vec4f(color,0.92);}`;var M=(q,J,Q)=>(Math.round(q*255)&255|(Math.round(J*255)&255)<<8|(Math.round(Q*255)&255)<<16|-16777216)>>>0,O=28,y={name:"candlestick",shaders:{compute:G,render:V},uniforms:[{name:"maxSamples",type:"f32",default:1e4},{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:"binSize",type:"u32",default:8},{name:"interval",type:"f32",default:0}],buffers:[{name:"candleBuffer",bytes:({width:q})=>Math.max(16,q*O),usages:["STORAGE"]}],passes:[{type:"compute",shader:"compute",perSeries:!0,dispatch:({width:q})=>({x:Math.ceil(Math.max(1,q)/v)}),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:q})=>q*30,bindings:[{binding:0,source:"uniforms"},{binding:1,source:"candleBuffer"},{binding:2,source:"custom-uniforms"}]}],computeBounds(q){let J=1/0,Q=-1/0,Z=1/0,$=-1/0;for(let z of q){for(let j of z.rawX){if(j<J)J=j;if(j>Q)Q=j}for(let j of z.extra.high??[])if(j>$)$=j;for(let j of z.extra.low??[])if(j<Z)Z=j}if(!isFinite(J))return{minX:0,maxX:1,minY:0,maxY:1};let W=(Q-J)*0.05||1,k=($-Z)*0.1||1;return{minX:J-W,maxX:Q+W,minY:Z-k,maxY:$+k}}};export{M as packRGB,y as CandlestickChart};
@@ -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-m17t3vjq.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{a as k,b as q}from"../chunk-1p45ex5n.js";import{c as j}from"../chunk-dmaxrg6s.js";import"../chunk-me3qaz3m.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-m17t3vjq.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{c as e,d as t}from"../chunk-dmaxrg6s.js";import"../chunk-me3qaz3m.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,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 };
@@ -0,0 +1,2 @@
1
+ import{c as a,d as e,e as t}from"./chunk-dmaxrg6s.js";var n=`${e}struct LineUniforms{maxSamplesPerPixel: u32,_p1: u32,_p2: u32,_p3: u32};struct LineData{screenX: f32,minScreenY: f32,maxScreenY: f32,valid: 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<storage,read_write> lineData: array<LineData>;@group(0)@binding(4)var<storage,read> allSeries: array<SeriesInfo>;@group(0)@binding(5)var<uniform> lu: LineUniforms;${t}@compute @workgroup_size(${a})fn main(@builtin(global_invocation_id)id: vec3u){let outputIdx = id.x;let maxCols = u32(u.width);let count = u.pointCount;if(outputIdx >= maxCols || count == 0u){if(outputIdx < maxCols){lineData[outputIdx] = LineData(-1.0,-1.0,-1.0,0.0);}return;}let viewRangeX = u.viewMaxX - u.viewMinX;let viewRangeY = u.viewMaxY - u.viewMinY;if(viewRangeX < 0.0001 || viewRangeY < 0.0001){lineData[outputIdx] = LineData(-1.0,-1.0,-1.0,0.0);return;}let relPx = f32(outputIdx);let pixelMinX = u.viewMinX +(relPx / u.width)* viewRangeX;let pixelMaxX = u.viewMinX +((relPx + 1.0)/ u.width)* viewRangeX;if(pixelMaxX < u.dataMinX || pixelMinX > u.dataMaxX){lineData[outputIdx] = LineData(-1.0,-1.0,-1.0,0.0);return;}let startIdx = lowerBound(pixelMinX,count);var endIdx = lowerBound(pixelMaxX,count);endIdx = min(endIdx,count);let centerX =(pixelMinX + pixelMaxX)* 0.5;if(startIdx >= endIdx){var bestIdx = startIdx;if(startIdx > 0u && startIdx < count){let distPrev = abs(dataX[startIdx - 1u] - centerX);let distCurr = abs(dataX[startIdx] - centerX);if(distPrev < distCurr){bestIdx = startIdx - 1u;}}else if(startIdx >= count && count > 0u){bestIdx = count - 1u;}if(bestIdx >= count){lineData[outputIdx] = LineData(-1.0,-1.0,-1.0,0.0);return;}let y = dataY[bestIdx];let normY =(y - u.viewMinY)/ viewRangeY;let screenY = 1.0 - normY;let normX =(dataX[bestIdx] - u.viewMinX)/ viewRangeX;let screenX = normX;lineData[outputIdx] = LineData(screenX,screenY,screenY,1.0);return;}var dataMinY = dataY[startIdx];var dataMaxY = dataY[startIdx];let rangeCount = endIdx - startIdx;let maxSamples = lu.maxSamplesPerPixel;if(maxSamples > 1u && rangeCount > maxSamples){let stride = f32(rangeCount - 1u)/ f32(maxSamples - 1u);for(var s = 0u;s < maxSamples;s++){let idx = startIdx + u32(f32(s)* stride);if(idx < endIdx){let y = dataY[idx];dataMinY = min(dataMinY,y);dataMaxY = max(dataMaxY,y);}}let lastY = dataY[endIdx - 1u];dataMinY = min(dataMinY,lastY);dataMaxY = max(dataMaxY,lastY);}else{for(var i = startIdx + 1u;i < endIdx;i++){let y = dataY[i];dataMinY = min(dataMinY,y);dataMaxY = max(dataMaxY,y);}}let normX =(centerX - u.viewMinX)/ viewRangeX;let screenX = normX;let normMaxY =(dataMaxY - u.viewMinY)/ viewRangeY;let normMinY =(dataMinY - u.viewMinY)/ viewRangeY;let minScreenY = 1.0 - normMaxY;let maxScreenY = 1.0 - normMinY;lineData[outputIdx] = LineData(screenX,minScreenY,maxScreenY,1.0);}`,r=`${e}struct LineData{screenX: f32,minScreenY: f32,maxScreenY: f32,valid: f32,};@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>;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 segIdx = vi / 2u;let endpoint = vi % 2u;if(segIdx < maxCols){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 connIdx = segIdx - maxCols;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);if(endpoint == 0u){let midY =(d0.minScreenY + d0.maxScreenY)* 0.5;out.pos = vec4f(d0.screenX * 2.0 - 1.0,1.0 - midY * 2.0,0.0,segValid);}else{let midY =(d1.minScreenY + d1.maxScreenY)* 0.5;out.pos = vec4f(d1.screenX * 2.0 - 1.0,1.0 - midY * 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);}`;
2
+ export{n as a,r as b};
@@ -0,0 +1,4 @@
1
+ // src/plugins/shared.ts
2
+ var MARGIN = { left: 55, right: 10, top: 8, bottom: 45 };
3
+
4
+ export { MARGIN };
@@ -0,0 +1,35 @@
1
+ // src/msg.ts
2
+ var M = {
3
+ INIT: 0,
4
+ THEME: 1,
5
+ REGISTER_RENDERER: 2,
6
+ REGISTER_CHART: 3,
7
+ UNREGISTER_CHART: 4,
8
+ UPDATE_SERIES: 5,
9
+ RESIZE: 6,
10
+ VIEW_TRANSFORM: 7,
11
+ BATCH_VIEW_TRANSFORM: 8,
12
+ SET_VISIBILITY: 9,
13
+ SET_STYLE: 10,
14
+ SET_UNIFORMS: 11,
15
+ GPU_READY: 12,
16
+ ERROR: 13,
17
+ STATS: 14
18
+ };
19
+ var E = {
20
+ NO_GPU: "e1:no-gpu",
21
+ NO_ADAPTER: "e2:no-adapter",
22
+ DEVICE_LOST: "e3:device-lost",
23
+ NOT_READY: "e4:not-ready",
24
+ COMPILE: "e5:compile",
25
+ CTX_GET: "e6:ctx-get",
26
+ CTX_CFG: "e7:ctx-cfg",
27
+ TEX: "e8:tex",
28
+ BIND_S: "e9:bind-s",
29
+ BIND_C: "e10:bind-c",
30
+ UPDATE: "e11:update",
31
+ NO_RENDERER: "e12:no-renderer",
32
+ RESIZE: "e13:resize"
33
+ };
34
+
35
+ export { M, E };
@@ -0,0 +1,2 @@
1
+ import{m as B}from"./chunk-bfyv7z27.js";import{o as Y}from"./chunk-me3qaz3m.js";class X{id;_mgr;constructor(q,A){this.id=q,this._mgr=A}get _c(){return this._mgr.charts.get(this.id)}setData(q){this._mgr.updateSeries(this.id,q)}configure(q){let A=this._c;if(!A)return;Object.assign(A.config,q);let F=new Set((A.renderer.uniforms??[]).map((J)=>J.name)),G={};for(let J of Object.keys(q)){let T=q[J];if(typeof T==="number"&&F.has(J))G[J]=T}if(Object.keys(G).length>0)Object.assign(A.customUniforms,G),this._mgr.worker?.postMessage({type:B.SET_UNIFORMS,id:this.id,values:G});if("bgColor"in q&&q.bgColor!==void 0){let[J,T,I]=q.bgColor,N=A.el.querySelector("div");if(N)N.style.background=`rgb(${Math.round(J*255)},${Math.round(T*255)},${Math.round(I*255)})`;this._mgr.worker?.postMessage({type:B.SET_STYLE,id:this.id,bgColor:q.bgColor})}this._mgr.requestRender(this.id),this._mgr.drawChart(A)}addPlugin(q){let A=this._c;if(!A||A.plugins.some((G)=>G.name===q.name))return;let F=A.el.querySelector("div");q.install?.(A,F),A.plugins.push(q),this._mgr.drawChart(A)}removePlugin(q){let A=this._c;if(!A)return;let F=A.plugins.findIndex((G)=>G.name===q);if(F>=0)A.plugins[F].uninstall?.(A),A.plugins.splice(F,1),this._mgr.drawChart(A)}hasPlugin(q){return this._c?.plugins.some((A)=>A.name===q)??!1}resetView(){this._mgr.resetView(this.id)}destroy(){this._mgr.destroy(this.id)}}var H=null;function z(q){if(typeof q!=="string")return q;if(!H)H=document.createElement("i"),H.style.cssText="display:none",document.body.appendChild(H);H.style.color=q;let A=getComputedStyle(H).color.match(/\d+/g);return{r:+A[0]/255,g:+A[1]/255,b:+A[2]/255}}function W(q,A,F){let G=devicePixelRatio||1;if(q.width=Math.round(A*G),q.height=Math.round(F*G),q instanceof HTMLCanvasElement)q.style.width=`${A}px`,q.style.height=`${F}px`}class S{static instance=null;worker=null;charts=new Map;renderers=new Map;uiPlugins=[];pendingRenderers=[];chartIdCounter=0;_isDark=!1;_syncViews=!1;statsCallbacks=[];currentStats={fps:0,renderMs:0,total:0,active:0};visibilityObserver;resizeObserver;constructor(){this._isDark=document.documentElement.classList.contains("dark"),this.visibilityObserver=new IntersectionObserver((q)=>{for(let A of q){let F=A.target.dataset.chartId;if(!F)continue;let G=this.charts.get(F);if(!G)continue;if(G.visible=A.isIntersecting,this.worker?.postMessage({type:B.SET_VISIBILITY,id:F,visible:A.isIntersecting}),A.isIntersecting)this.drawChart(G)}},{threshold:0.01}),this.resizeObserver=new ResizeObserver((q)=>{for(let A of q){let F=A.target.dataset.chartId;if(!F)continue;let G=this.charts.get(F);if(!G)continue;let{width:J,height:T}=A.contentRect;if(J<=0||T<=0)continue;G.width=J,G.height=T;let I=devicePixelRatio||1;W(G.backCanvas,J,T),W(G.frontCanvas,J,T);let{bufferSizes:N,perSeriesPassMeta:Z}=this.computeRendererMeta(G.renderer,G);this.worker?.postMessage({type:B.RESIZE,id:F,width:Math.round(J*I),height:Math.round(T*I),bufferSizes:N,perSeriesPassMeta:Z}),this.drawChart(G)}})}static getInstance(){if(!S.instance)S.instance=new S;return S.instance}get isDark(){return this._isDark}get syncViews(){return this._syncViews}use(q){if("passes"in q){let A=q;if(this.renderers.set(A.name,A),this.worker)this.sendRendererRegistration(A);else this.pendingRenderers.push(A)}else{let A=q;if(!this.uiPlugins.some((F)=>F.name===A.name))this.uiPlugins.push(A)}}async init(){if(this.worker)return!0;return new Promise((q)=>{import("./worker-inline.js").then(({WORKER_CODE:A})=>{let F=new Blob([A],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(F),{type:"module"}),this.setupWorkerHandlers(q)}).catch(()=>{this.worker=new Worker(new URL("./gpu-worker.js",import.meta.url),{type:"module"}),this.setupWorkerHandlers(q)})})}setupWorkerHandlers(q){if(!this.worker)return;this.worker.onmessage=(A)=>{let{type:F,...G}=A.data;switch(F){case B.GPU_READY:for(let J of this.pendingRenderers)this.sendRendererRegistration(J);this.pendingRenderers=[],q(!0);break;case B.ERROR:console.error("chartai:",G.code),q(!1);break;case B.STATS:this.currentStats={fps:G.fps,renderMs:G.renderMs,total:G.totalCharts,active:G.activeCharts};for(let J of this.statsCallbacks)J(this.currentStats);break}},this.worker.onerror=(A)=>{console.error("chartai:",A),q(!1)},this.worker.postMessage({type:B.INIT,isDark:this._isDark})}sendRendererRegistration(q){let A=(q.buffers??[]).map((F)=>({name:F.name,usages:F.usages,perSeries:q.passes.some((G)=>G.perSeries!==!1&&G.bindings.some((J)=>J.source===F.name))}));this.worker?.postMessage({type:B.REGISTER_RENDERER,name:q.name,shaders:q.shaders,passes:q.passes.map((F)=>({type:F.type,shader:F.shader,bindings:F.bindings,perSeries:F.perSeries!==!1,topology:F.topology,loadOp:F.loadOp,blend:F.blend})),bufferDefs:A,uniformDefs:q.uniforms??[]})}computeRendererMeta(q,A){let F={},G=[],J=A.series.length>0?A.series:[{rawX:[],rawY:[],extra:{},label:"",color:{r:0,g:0,b:0}}],T=devicePixelRatio||1,I=Math.round(A.width*T),N=Math.round(A.height*T);for(let Z of J){let K={width:I,height:N,samples:Z.rawX.length,seriesCount:J.length,bounds:A.bounds,view:A.view};for(let V of q.buffers??[]){let D=V.bytes(K);F[V.name]=Math.max(F[V.name]??0,D)}G.push(q.passes.map((V)=>({dispatch:V.dispatch?.(K),draw:V.draw?.(K)})))}return{bufferSizes:F,perSeriesPassMeta:G}}create(q){if(!this.worker)throw Error("Call init() before create().");let A=this.renderers.get(q.type);if(!A)throw Error(`No renderer "${q.type}". Call manager.use() with a matching RendererPlugin first.`);let F=`chart-${++this.chartIdCounter}`,G=document.createElement("div");G.dataset.chartId=F,G.style.cssText="width:100%;height:100%;position:relative;";let J=document.createElement("div");J.dataset.chartId=F,J.style.cssText="width:100%;height:100%;position:relative;";let T=(Q,$)=>{let U=document.createElement("canvas");return U.style.cssText=`position:absolute;inset:0;width:100%;height:100%;pointer-events:${$};z-index:${Q};`,U},I=T(0,"none"),N=T(1,"auto"),Z=T(2,"none");J.append(I,N,Z),G.appendChild(J),q.container.appendChild(G);let K;try{K=N.transferControlToOffscreen()}catch(Q){throw Error(`Failed to acquire OffscreenCanvas: ${Q}`)}let V=J.getBoundingClientRect(),D=V.width||400,P=V.height||200;if(W(K,D,P),W(I,D,P),W(Z,D,P),q.bgColor){let[Q,$,U]=q.bgColor;J.style.background=`rgb(${Math.round(Q*255)},${Math.round($*255)},${Math.round(U*255)})`}let L={};for(let Q of A.uniforms??[]){let $=q[Q.name];L[Q.name]=typeof $==="number"?$:Q.default}let j={id:F,config:q,el:G,backCanvas:I,frontCanvas:Z,width:D,height:P,series:[],bounds:{minX:0,maxX:1,minY:0,maxY:1},view:{panX:0,panY:0,zoomX:1,zoomY:1},visible:!0,dragging:!1,plugins:[...this.uiPlugins],renderer:A,customUniforms:L};this.charts.set(F,j);let R=devicePixelRatio||1,{bufferSizes:O,perSeriesPassMeta:E}=this.computeRendererMeta(A,j);this.worker.postMessage({type:B.REGISTER_CHART,id:F,canvas:K,rendererName:q.type,bgColor:q.bgColor??null,bufferSizes:O,perSeriesPassMeta:E,customUniformValues:L,width:Math.round(D*R),height:Math.round(P*R)},[K]),this.visibilityObserver.observe(G),this.resizeObserver.observe(J);for(let Q of j.plugins)Q.install?.(j,J);return A.install?.(j,J),this.updateSeries(F,q.series),new X(F,this)}destroy(q){let A=this.charts.get(q);if(!A)return;A.renderer.uninstall?.(A);for(let G of A.plugins)G.uninstall?.(A);this.visibilityObserver.unobserve(A.el);let F=A.el.querySelector("div");if(F)this.resizeObserver.unobserve(F);A.el.remove(),this.worker?.postMessage({type:B.UNREGISTER_CHART,id:q}),this.charts.delete(q)}updateSeries(q,A){let F=this.charts.get(q);if(!F||!this.worker||A.length===0)return;F.series=A.map((L)=>{let j=L.x.length,R=z(L.color);if(j===0)return{label:L.label,color:R,rawX:[],rawY:[],extra:{}};let O=Array.from({length:j},(Q,$)=>$).sort((Q,$)=>L.x[Q]-L.x[$]),E={};for(let Q in L)if(Q!=="label"&&Q!=="color"&&Q!=="x"&&Q!=="y"&&Array.isArray(L[Q]))E[Q]=O.map(($)=>L[Q][$]);return{label:L.label,color:R,rawX:O.map((Q)=>L.x[Q]),rawY:O.map((Q)=>L.y[Q]),extra:E}});let G=F.renderer.computeBounds?.(F.series),{minX:J,maxX:T,minY:I,maxY:N}=G??(()=>{let L=1/0,j=-1/0,R=1/0,O=-1/0;for(let $ of F.series)for(let U=0;U<$.rawX.length;U++){if($.rawX[U]<L)L=$.rawX[U];if($.rawX[U]>j)j=$.rawX[U];if($.rawY[U]<R)R=$.rawY[U];if($.rawY[U]>O)O=$.rawY[U]}let E=(j-L)*0.05||1,Q=(O-R)*0.1||1;return{minX:L-E,maxX:j+E,minY:R-Q,maxY:O+Q}})(),Z=F.config.defaultBounds;if(Z){if(Z.minX!==void 0)J=Z.minX;if(Z.maxX!==void 0)T=Z.maxX;if(Z.minY!==void 0)I=Z.minY;if(Z.maxY!==void 0)N=Z.maxY}F.bounds={minX:J,maxX:T,minY:I,maxY:N};let{bufferSizes:K,perSeriesPassMeta:V}=this.computeRendererMeta(F.renderer,F),D=F.series.map((L)=>{let j={};for(let R in L.extra)j[R]=new Float32Array(L.extra[R]);return{label:L.label,colorR:L.color.r,colorG:L.color.g,colorB:L.color.b,dataX:new Float32Array(L.rawX),dataY:new Float32Array(L.rawY),extra:j}}),P=D.flatMap((L)=>[L.dataX.buffer,L.dataY.buffer,...Object.values(L.extra).map((j)=>j.buffer)]);this.worker.postMessage({type:B.UPDATE_SERIES,id:q,series:D,bounds:F.bounds,bufferSizes:K,perSeriesPassMeta:V},P),this.sendViewTransform(F),this.drawChart(F)}setSyncViews(q){this._syncViews=q}setTheme(q){this._isDark=q,this.worker?.postMessage({type:B.THEME,isDark:q});for(let A of this.charts.values())this.drawChart(A)}onStats(q){return this.statsCallbacks.push(q),()=>{let A=this.statsCallbacks.indexOf(q);if(A>=0)this.statsCallbacks.splice(A,1)}}getStats(){return{...this.currentStats}}resetView(q){let A=this.charts.get(q);if(!A)return;for(let Z of A.plugins)Z.resetView?.(A);let{panX:F,panY:G,zoomX:J,zoomY:T}=A.view,I=performance.now(),N=()=>{let Z=Math.min(1,(performance.now()-I)/300),K=1-Math.pow(1-Z,3);if(A.view.panX=F*(1-K),A.view.panY=G*(1-K),A.view.zoomX=J+(1-J)*K,A.view.zoomY=T+(1-T)*K,this.sendViewTransform(A),this.drawChart(A),this._syncViews)this.syncAllViews(A);if(Z<1)requestAnimationFrame(N)};requestAnimationFrame(N)}requestRender(q){let A=this.charts.get(q);if(A)this.sendViewTransform(A)}sendViewTransform(q){this.worker?.postMessage({type:B.VIEW_TRANSFORM,id:q.id,panX:q.view.panX,panY:q.view.panY,zoomX:q.view.zoomX,zoomY:q.view.zoomY})}syncAllViews(q){let A=[];for(let F of this.charts.values())if(F.id!==q.id)F.view={...q.view},A.push({id:F.id}),this.drawChart(F);if(A.length>0)this.worker?.postMessage({type:B.BATCH_VIEW_TRANSFORM,panX:q.view.panX,panY:q.view.panY,zoomX:q.view.zoomX,zoomY:q.view.zoomY,transforms:A})}drawChart(q){if(!q.visible)return;let A=devicePixelRatio||1,F=q.backCanvas.getContext("2d");if(F){F.clearRect(0,0,q.backCanvas.width,q.backCanvas.height),F.save(),F.scale(A,A);for(let J of q.plugins)J.beforeDraw?.(F,q);F.restore()}let G=q.frontCanvas.getContext("2d");if(G){G.clearRect(0,0,q.frontCanvas.width,q.frontCanvas.height),G.save(),G.scale(A,A);for(let J of q.plugins)J.afterDraw?.(G,q);G.restore()}}}var y=S.getInstance();
2
+ export{X as k,y as l};
@@ -0,0 +1,105 @@
1
+ import {
2
+ MARGIN
3
+ } from "./chunk-831dem4f.js";
4
+ import {
5
+ ChartManager
6
+ } from "./chunk-g6m56ptf.js";
7
+
8
+ // src/plugins/labels.ts
9
+ var DEFAULT_FONT = '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';
10
+ var DEFAULT_LABEL_SIZE = 12;
11
+ var niceTicks = (min, max, count) => {
12
+ const range = max - min;
13
+ if (range <= 0)
14
+ return [min];
15
+ const rough = range / count, mag = 10 ** Math.floor(Math.log10(rough)), res = rough / mag;
16
+ const step = mag * (res <= 1.5 ? 1 : res <= 3 ? 2 : res <= 7 ? 5 : 10);
17
+ const ticks = [];
18
+ for (let v = Math.ceil(min / step) * step;v <= max; v += step)
19
+ ticks.push(v);
20
+ return ticks;
21
+ };
22
+ var getViewState = (chart) => {
23
+ const { width: w, height: h } = chart, m = MARGIN;
24
+ const { bounds: b, view: v } = chart, fullX = b.maxX - b.minX, fullY = b.maxY - b.minY;
25
+ const rx = fullX / v.zoomX, ry = fullY / v.zoomY;
26
+ const mx = b.minX + v.panX * fullX, my = b.minY + v.panY * fullY;
27
+ const bgc = chart.config.bgColor ?? (ChartManager.isDark ? [0.11, 0.11, 0.12] : [0.98, 0.98, 0.98]);
28
+ return {
29
+ w,
30
+ h,
31
+ m,
32
+ rx,
33
+ ry,
34
+ mx,
35
+ my,
36
+ bg: `${Math.round(bgc[0] * 255)},${Math.round(bgc[1] * 255)},${Math.round(bgc[2] * 255)}`,
37
+ font: chart.config.fontFamily ?? DEFAULT_FONT,
38
+ text: chart.config.textColor ?? (ChartManager.isDark ? "#c0c0c0" : "#333333"),
39
+ grid: chart.config.gridColor ?? (ChartManager.isDark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.06)")
40
+ };
41
+ };
42
+ var labelsPlugin = {
43
+ name: "labels",
44
+ beforeDraw(ctx, chart) {
45
+ const { w, h, m, rx, ry, mx, my, grid } = getViewState(chart);
46
+ ctx.strokeStyle = grid;
47
+ ctx.lineWidth = 1;
48
+ ctx.beginPath();
49
+ niceTicks(my, my + ry, 7).forEach((v) => {
50
+ const y = h * (1 - (v - my) / ry);
51
+ if (y > 5 && y < h - m.bottom - 5) {
52
+ ctx.moveTo(m.left, y);
53
+ ctx.lineTo(w, y);
54
+ }
55
+ });
56
+ niceTicks(mx, mx + rx, 8).forEach((v) => {
57
+ const x = w * ((v - mx) / rx);
58
+ if (x > m.left && x < w) {
59
+ ctx.moveTo(x, 0);
60
+ ctx.lineTo(x, h - m.bottom);
61
+ }
62
+ });
63
+ ctx.stroke();
64
+ },
65
+ afterDraw(ctx, chart) {
66
+ const { w, h, m, rx, ry, mx, my, bg, font, text } = getViewState(chart);
67
+ const {
68
+ formatX = String,
69
+ formatY = String,
70
+ labelSize = DEFAULT_LABEL_SIZE
71
+ } = chart.config;
72
+ const drawFade = (dir, x, y, fw, fh) => {
73
+ const g = dir === "left" ? ctx.createLinearGradient(x, 0, x + fw, 0) : ctx.createLinearGradient(0, y, 0, y + fh);
74
+ const alphas = dir === "left" ? [1, 0.7, 0.2, 0.05, 0] : [0, 0.05, 0.2, 0.7, 1];
75
+ [0, 0.35, 0.55, 0.7, 1].forEach((s, i) => g.addColorStop(s, `rgba(${bg},${alphas[i]})`));
76
+ ctx.fillStyle = g;
77
+ ctx.fillRect(x, y, fw, fh);
78
+ };
79
+ drawFade("left", 0, 0, m.left + 20, h);
80
+ drawFade("bottom", 0, h - m.bottom - 20, w, m.bottom + 20);
81
+ ctx.font = `${labelSize}px ${font}`;
82
+ ctx.fillStyle = text;
83
+ ctx.textAlign = "right";
84
+ ctx.textBaseline = "middle";
85
+ niceTicks(my, my + ry, 7).forEach((v) => {
86
+ const y = h * (1 - (v - my) / ry);
87
+ if (y > 5 && y < h - m.bottom - 5)
88
+ ctx.fillText(formatY(v), m.left - 5, y);
89
+ });
90
+ ctx.textAlign = "right";
91
+ ctx.textBaseline = "top";
92
+ niceTicks(mx, mx + rx, 8).forEach((v) => {
93
+ const x = w * ((v - mx) / rx);
94
+ if (x < m.left - 10 || x > w + 30)
95
+ return;
96
+ ctx.save();
97
+ ctx.translate(x, h - m.bottom + 5);
98
+ ctx.rotate(-Math.PI / 14);
99
+ ctx.fillText(formatX(v), 0, 0);
100
+ ctx.restore();
101
+ });
102
+ }
103
+ };
104
+
105
+ export { DEFAULT_FONT, DEFAULT_LABEL_SIZE, labelsPlugin };
@@ -0,0 +1,2 @@
1
+ var a={INIT:0,THEME:1,REGISTER_RENDERER:2,REGISTER_CHART:3,UNREGISTER_CHART:4,UPDATE_SERIES:5,RESIZE:6,VIEW_TRANSFORM:7,BATCH_VIEW_TRANSFORM:8,SET_VISIBILITY:9,SET_STYLE:10,SET_UNIFORMS:11,GPU_READY:12,ERROR:13,STATS:14},g={NO_GPU:"e1:no-gpu",NO_ADAPTER:"e2:no-adapter",DEVICE_LOST:"e3:device-lost",NOT_READY:"e4:not-ready",COMPILE:"e5:compile",CTX_GET:"e6:ctx-get",CTX_CFG:"e7:ctx-cfg",TEX:"e8:tex",BIND_S:"e9:bind-s",BIND_C:"e10:bind-c",UPDATE:"e11:update",NO_RENDERER:"e12:no-renderer",RESIZE:"e13:resize"};
2
+ export{a as m,g as n};
@@ -0,0 +1,2 @@
1
+ var e=256,t="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,};",a="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;}",l="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);}";
2
+ export{e as c,t as d,a as e,l as f};
@@ -0,0 +1,2 @@
1
+ var t={left:55,right:10,top:8,bottom:45};
2
+ export{t as j};