@canplot/react 0.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.
- package/LICENSE +21 -0
- package/README.md +239 -0
- package/dist/canplot.cjs +5 -0
- package/dist/canplot.cjs.map +1 -0
- package/dist/canplot.mjs +1361 -0
- package/dist/canplot.mjs.map +1 -0
- package/package.json +91 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 jedzej
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# CanPlot
|
|
2
|
+
|
|
3
|
+
A high-performance React charting library built on Canvas.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **High Performance**: Built on Canvas for smooth rendering of large datasets
|
|
8
|
+
- 📊 **Multiple Chart Types**: Line, Bar, Scatter, Area, and Sparkline plots
|
|
9
|
+
- 🎨 **Customizable**: Flexible styling and configuration options
|
|
10
|
+
- 📈 **Interactive**: Built-in tooltips, crosshairs, and selection tools
|
|
11
|
+
- ⏱️ **Time Series**: First-class support for time-based data
|
|
12
|
+
- 📱 **Responsive**: Adapts to container size
|
|
13
|
+
- 🎯 **Type Safe**: Written in TypeScript with full type definitions
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install canplot
|
|
19
|
+
# or
|
|
20
|
+
yarn add canplot
|
|
21
|
+
# or
|
|
22
|
+
pnpm add canplot
|
|
23
|
+
# or
|
|
24
|
+
bun add canplot
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { CanPlot, LinePlot } from 'canplot';
|
|
31
|
+
|
|
32
|
+
function MyChart() {
|
|
33
|
+
const data = [
|
|
34
|
+
{ x: 1, y: 30 },
|
|
35
|
+
{ x: 2, y: 45 },
|
|
36
|
+
{ x: 3, y: 60 },
|
|
37
|
+
{ x: 4, y: 35 },
|
|
38
|
+
{ x: 5, y: 70 },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const scales = [
|
|
42
|
+
{
|
|
43
|
+
id: 'x',
|
|
44
|
+
type: 'linear' as const,
|
|
45
|
+
axis: { position: 'bottom' as const, size: 40 },
|
|
46
|
+
origin: 'x' as const,
|
|
47
|
+
min: 0,
|
|
48
|
+
max: 10,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'y',
|
|
52
|
+
type: 'linear' as const,
|
|
53
|
+
axis: { position: 'left' as const, size: 40 },
|
|
54
|
+
origin: 'y' as const,
|
|
55
|
+
min: 0,
|
|
56
|
+
max: 100,
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<CanPlot
|
|
62
|
+
style={{ width: '100%', height: '400px' }}
|
|
63
|
+
configuration={{
|
|
64
|
+
padding: { bottom: 20, left: 20, right: 20, top: 20 },
|
|
65
|
+
scales,
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<LinePlot
|
|
69
|
+
data={data}
|
|
70
|
+
xScaleId="x"
|
|
71
|
+
yScaleId="y"
|
|
72
|
+
style={{
|
|
73
|
+
strokeStyle: '#4c6ef5',
|
|
74
|
+
lineWidth: 2,
|
|
75
|
+
}}
|
|
76
|
+
/>
|
|
77
|
+
</CanPlot>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Chart Types
|
|
83
|
+
|
|
84
|
+
### Line Plot
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
<LinePlot
|
|
88
|
+
data={data}
|
|
89
|
+
xScaleId="x"
|
|
90
|
+
yScaleId="y"
|
|
91
|
+
style={{ strokeStyle: '#4c6ef5', lineWidth: 2 }}
|
|
92
|
+
/>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Bar Plot
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<BarPlot
|
|
99
|
+
data={data}
|
|
100
|
+
xScaleId="x"
|
|
101
|
+
yScaleId="y"
|
|
102
|
+
barWidth={0.6}
|
|
103
|
+
xPositionOffset={0}
|
|
104
|
+
style={{ fillStyle: '#ff6b6b' }}
|
|
105
|
+
/>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Scatter Plot
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
<ScatterPlot
|
|
112
|
+
data={data}
|
|
113
|
+
xScaleId="x"
|
|
114
|
+
yScaleId="y"
|
|
115
|
+
style={{
|
|
116
|
+
fillStyle: '#51cf66',
|
|
117
|
+
strokeStyle: '#37b24d',
|
|
118
|
+
lineWidth: 2,
|
|
119
|
+
}}
|
|
120
|
+
/>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Area Plot
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
<AreaPlot
|
|
127
|
+
data={data}
|
|
128
|
+
xScaleId="x"
|
|
129
|
+
yScaleId="y"
|
|
130
|
+
style={{
|
|
131
|
+
fillStyle: 'rgba(76, 110, 245, 0.2)',
|
|
132
|
+
strokeStyle: '#4c6ef5',
|
|
133
|
+
lineWidth: 2,
|
|
134
|
+
}}
|
|
135
|
+
/>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Interactions
|
|
139
|
+
|
|
140
|
+
### Tooltips
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
<ChartAreaInteractions>
|
|
144
|
+
<TooltipsX
|
|
145
|
+
xScaleId="x"
|
|
146
|
+
data={[
|
|
147
|
+
{
|
|
148
|
+
seriesId: 'series1',
|
|
149
|
+
yScaleId: 'y',
|
|
150
|
+
points: data,
|
|
151
|
+
},
|
|
152
|
+
]}
|
|
153
|
+
renderTooltip={(state) => {
|
|
154
|
+
if (!state || state.points[0].y === null) return null;
|
|
155
|
+
return (
|
|
156
|
+
<div style={{ /* tooltip styles */ }}>
|
|
157
|
+
X: {state.x.toFixed(1)}, Y: {state.points[0].y?.toFixed(1)}
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
}}
|
|
161
|
+
/>
|
|
162
|
+
</ChartAreaInteractions>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Crosshair
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<ChartAreaInteractions>
|
|
169
|
+
<Crosshair color="rgba(0, 0, 0, 0.3)" />
|
|
170
|
+
</ChartAreaInteractions>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Selection Box
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
<ChartAreaInteractions>
|
|
177
|
+
<SelectBox
|
|
178
|
+
onSelect={(selection) => {
|
|
179
|
+
console.log('Selected area:', selection);
|
|
180
|
+
}}
|
|
181
|
+
/>
|
|
182
|
+
</ChartAreaInteractions>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Time Series
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
const startDate = new Date('2024-01-01T00:00:00Z');
|
|
189
|
+
|
|
190
|
+
const scales = [
|
|
191
|
+
{
|
|
192
|
+
id: 'x',
|
|
193
|
+
type: 'time' as const,
|
|
194
|
+
axis: { position: 'bottom' as const, size: 40 },
|
|
195
|
+
origin: 'x' as const,
|
|
196
|
+
min: startDate.getTime(),
|
|
197
|
+
max: startDate.getTime() + 30 * 24 * 60 * 60 * 1000,
|
|
198
|
+
timeZone: 'UTC',
|
|
199
|
+
},
|
|
200
|
+
// ... y scale
|
|
201
|
+
];
|
|
202
|
+
|
|
203
|
+
const data = Array.from({ length: 30 }, (_, i) => ({
|
|
204
|
+
x: startDate.getTime() + i * 24 * 60 * 60 * 1000,
|
|
205
|
+
y: Math.random() * 100,
|
|
206
|
+
}));
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## API Reference
|
|
210
|
+
|
|
211
|
+
### Components
|
|
212
|
+
|
|
213
|
+
- **CanPlot**: Main container component
|
|
214
|
+
- **LinePlot**: Renders line charts
|
|
215
|
+
- **BarPlot**: Renders bar charts
|
|
216
|
+
- **ScatterPlot**: Renders scatter plots
|
|
217
|
+
- **AreaPlot**: Renders area charts
|
|
218
|
+
- **SparklinePlot**: Renders compact sparkline charts
|
|
219
|
+
- **ChartAreaInteractions**: Container for interactive features
|
|
220
|
+
- **TooltipsX**: Adds tooltips based on X-axis position
|
|
221
|
+
- **Crosshair**: Adds crosshair cursor
|
|
222
|
+
- **SelectBox**: Adds box selection
|
|
223
|
+
- **AxisOverlay**: Custom axis rendering
|
|
224
|
+
|
|
225
|
+
### Types
|
|
226
|
+
|
|
227
|
+
Full TypeScript type definitions are included.
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
MIT
|
|
232
|
+
|
|
233
|
+
## Contributing
|
|
234
|
+
|
|
235
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
236
|
+
|
|
237
|
+
## Repository
|
|
238
|
+
|
|
239
|
+
https://github.com/jedzej/canplot
|
package/dist/canplot.cjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("react/jsx-runtime"),S=require("react"),it=require("zustand"),xt=5,St=10,gt=60,kt=30,vt="UTC",Et="en-GB",W=(t,s,e)=>Math.min(Math.max(t,s),e),wt=(t,s,e,o)=>{const{min:c,max:n}=R(t,e),r=o==="canvas"?t.chartAreaCanvasPX:t.chartAreaCSS,a=(B(t,e)?r.width:r.height)/(n-c);return s/a},R=(t,s)=>{const e=t.scales.find(o=>o.id===s);if(!e)throw new Error(`Scale ${s} not found`);return e},B=(t,s)=>t.scales.find(e=>e.id===s)?.origin==="x",Pt=(t,s)=>t.scales.find(e=>e.id===s)?.origin==="y",U=(t,s)=>{const e=window.devicePixelRatio||1;t.lineCap=s?.lineCap??"butt",t.lineDashOffset=e*(s?.lineDashOffset??0),t.lineJoin=s?.lineJoin??"miter",t.lineWidth=e*(s?.lineWidth??1),t.miterLimit=e*(s?.miterLimit??10),t.strokeStyle=s?.strokeStyle??"black",t.fillStyle=s?.fillStyle??t.strokeStyle,t.font=s?.font??`${10*e}px sans-serif`,t.textAlign=s?.textAlign??"start",t.direction=s?.direction??"inherit",t.textBaseline=s?.textBaseline??"alphabetic",t.fontKerning=s?.fontKerning??"auto"},J=(t,s,e,o)=>{const c=o==="canvas"?t.chartAreaCanvasPX:t.chartAreaCSS,{min:n,max:r}=R(t,e),a=(B(t,e)?c.width:c.height)/(r-n);return s*a},D=(t,s,e,o)=>{const{min:c}=R(t,e),n=o==="canvas"?t.chartAreaCanvasPX:t.chartAreaCSS,r=J(t,s-c,e,o);return B(t,e)?W(n.x+r,n.x-10*n.width,n.x+11*n.width):W(n.y+n.height-r,n.y-10*n.height,n.y+11*n.height)},Y=(t,s,e)=>{const o=e==="canvas"?t.chartAreaCanvasPX:t.chartAreaCSS;return W(s,o.x,o.x+o.width)},j=(t,s,e)=>{const o=e==="canvas"?t.chartAreaCanvasPX:t.chartAreaCSS;return W(s,o.y,o.y+o.height)},G=(t,s,e)=>{const{min:o,max:c}=R(t,e);return s>=o&&s<=c},L=(t,s,e,o)=>{const{min:c,max:n}=R(t,e),r=o==="canvas"?t.chartAreaCanvasPX:t.chartAreaCSS,a=B(t,e)?(s-r.x)/r.width:(r.height-s+r.y)/r.height;return c+a*(n-c)},Mt=1,Ct=1e3*Mt,rt=60*Ct,q=60*rt,Q=24*q,At=30*Q,Rt=365*Q,_t=[[1,"milliseconds"],[2,"milliseconds"],[5,"milliseconds"],[10,"milliseconds"],[20,"milliseconds"],[50,"milliseconds"],[100,"milliseconds"],[200,"milliseconds"],[500,"milliseconds"],[1,"seconds"],[5,"seconds"],[10,"seconds"],[15,"seconds"],[30,"seconds"],[1,"minutes"],[5,"minutes"],[10,"minutes"],[15,"minutes"],[30,"minutes"],[1,"hours"],[2,"hours"],[3,"hours"],[4,"hours"],[6,"hours"],[8,"hours"],[12,"hours"],[1,"days"],[3,"days"],[5,"days"],[7,"days"],[10,"days"],[15,"days"],[1,"months"],[2,"months"],[3,"months"],[4,"months"],[6,"months"],[1,"years"],[2,"years"],[5,"years"],[10,"years"],[25,"years"],[50,"years"],[100,"years"]],V=t=>{const[s,e]=t;switch(e){case"milliseconds":return s;case"seconds":return s*Ct;case"minutes":return s*rt;case"hours":return s*q;case"days":return s*Q;case"months":return s*At;case"years":return s*Rt}},Lt=(t,s)=>{const e=new Date(t);return e.setUTCMilliseconds(e.getUTCMilliseconds()+s),e.getTime()},Ut=(t,s)=>{const e=new Date(t);return e.setUTCSeconds(e.getUTCSeconds()+s),e.getTime()},Dt=(t,s)=>{const e=new Date(t);return e.setUTCMinutes(e.getUTCMinutes()+s),e.getTime()},Xt=(t,s)=>{const e=new Date(t);return e.setUTCHours(e.getUTCHours()+s),e.getTime()},Kt=(t,s)=>{const e=new Date(t);return e.setUTCDate(e.getUTCDate()+s),e.getTime()},ft=(t,s)=>{const e=new Date(t);return e.setUTCMonth(e.getUTCMonth()+s),e.getTime()},z=(t,s)=>{const[e,o]=s;switch(o){case"milliseconds":return Lt(t,e);case"seconds":return Ut(t,e);case"minutes":return Dt(t,e);case"hours":return Xt(t,e);case"days":return Kt(t,e);case"months":return ft(t,e);case"years":return ft(t,e*12)}};function H(t,s){const e=new Date(t),o=new Date(e.toLocaleString("en-US",{timeZone:s})),c=new Date(e.toLocaleString("en-US",{timeZone:"UTC"}));return(o.getTime()-c.getTime())/(3600*1e3)}const It=(t,s,e="UTC")=>{const[o,c]=s;let n=new Date(t);const r=()=>{n.setUTCHours(-H(n,e),0,0,0)};switch(c){case"milliseconds":n.setUTCMilliseconds(Math.ceil(n.getUTCMilliseconds()/o)*o);break;case"seconds":n.setUTCSeconds(Math.ceil(n.getUTCSeconds()/o)*o,0);break;case"minutes":n.setUTCMinutes(Math.ceil(n.getTime()%q/rt/o)*o,0,0);break;case"hours":n.setUTCHours(Math.ceil(n.getTime()%Q/q/o)*o,0,0,0);break;case"days":case"months":case"years":c==="months"?n.setUTCDate(1):c==="years"&&n.setUTCMonth(0,1),r(),n.getTime()<t&&(n=new Date(z(n,[1,c])));break}return n.getTime()},zt=({timeZone:t=vt,space:s=gt})=>({frame:e,scaleId:o})=>{const{min:c,max:n}=R(e,o),r=Math.floor(e.chartAreaCanvasPX.width/s)+1,u=(n-c)/r,[l,d]=_t.find(f=>V(f)>=u)??[1,"milliseconds"],m=It(c,[l,d],t),p=H(m,t),h=[m];let i;for(;;){switch(d){case"milliseconds":case"seconds":case"minutes":case"hours":{i=z(m,[h.length*l,d]);break}case"days":{const f=z(m,[h.length*l,d]);i=z(f,[p-H(f,t),"hours"]);break}case"months":case"years":{const f=z(z(z(m,[p,"hours"]),[h.length*l,d]),[-p,"hours"]);i=z(f,[p-H(f,t),"hours"]);break}}if(i>n)break;h.push(i)}return h},I=(t,s,e)=>t.find(o=>o.type===e)?.value!==s.find(o=>o.type===e)?.value,Ft=({timeZone:t=vt,locale:s=Et,showTimezone:e=!0})=>{const o=new Intl.DateTimeFormat(s,{year:"numeric",day:"numeric",month:"short",hour:"numeric",hourCycle:"h23",minute:"numeric",second:"numeric",fractionalSecondDigits:3,timeZoneName:"short",timeZone:t});return({ticks:c})=>{const n=c[1]-c[0],r=n<V([1,"days"]),a=n<V([1,"minutes"]),u=n<V([1,"seconds"]);return c.map(l=>o.formatToParts(new Date(l))).map((l,d,m)=>{const p=m[d-1],h=d===0||I(l,p,"year"),i=d===0||I(l,p,"day"),f=d===0||I(l,p,"month"),y=d===0||I(l,p,"hour"),x=d===0||I(l,p,"timeZoneName"),T=d===0||I(l,p,"minute"),g=d===0||I(l,p,"second"),v=d===0||I(l,p,"fractionalSecond"),E=[];if(r&&(y||T||x||g||v)){const C=l.find(_=>_.type==="hour")?.value,P=l.find(_=>_.type==="minute")?.value,M=l.find(_=>_.type==="timeZoneName")?.value;let X="";if(a){const _=l.find(F=>F.type==="second")?.value,$=l.find(F=>F.type==="fractionalSecond")?.value;X=`:${_}`+(u?`.${$}`:"")}E.push(`${C}:${P}${X}`+(e&&x?` ${M}`:""))}return(i||f)&&E.push([l.find(C=>C.type==="month")?.value,i&&l.find(C=>C.type==="day")?.value].filter(Boolean).join(" ")),h&&E.push(l.find(C=>C.type==="year")?.value),E.filter(C=>C).join(`
|
|
2
|
+
`)})}},Z=[];for(let t=-12;t<=12;t++)Z.push(1*10**t),Z.push(2*10**t),Z.push(5*10**t);const Yt=t=>{const{ctx:s,scales:e}=t;s.save(),s.strokeStyle="black",s.fillStyle="black",s.lineWidth=1,s.font="12px Arial",s.textAlign="center",s.textBaseline="middle";for(const o of e){if(!o.axis)continue;const c=o.type==="time"?zt({space:o.axis.tickSpace,timeZone:o.timeZone}):jt({space:o.axis.tickSpace}),n=o.type==="time"?Ft({timeZone:o.timeZone,showTimezone:o.axis.showTimezone,locale:o.locale}):Ot,r=o.axis.canvasRect;if(o.origin==="x"){if(o.axis.position==="bottom")s.beginPath(),s.moveTo(r.x,r.y),s.lineTo(r.x+r.width,r.y),s.stroke(),mt(t,o.id,r.y,c,n);else if(o.axis.position==="top"){const a=r.y+r.height;s.beginPath(),s.moveTo(r.x,a),s.lineTo(r.x+r.width,a),s.stroke(),mt(t,o.id,a,c,n)}}else if(o.axis.position==="left"){const a=r.x+r.width;s.beginPath(),s.moveTo(a,r.y),s.lineTo(a,r.y+r.height),s.stroke(),pt(t,o.id,a,c,n)}else o.axis.position==="right"&&(s.beginPath(),s.moveTo(r.x,r.y),s.lineTo(r.x,r.y+r.height),s.stroke(),pt(t,o.id,r.x,c,n))}s.restore()},pt=(t,s,e,o,c)=>{const{ctx:n}=t,r=t.scales.find(i=>i.id===s)?.axis;if(!r)return;const a=window.devicePixelRatio||1,u=xt,l=e,d=r.position==="left"?e-u:e+u,m=St*a,p=o({frame:t,scaleId:s})??[],h=c({frame:t,scaleId:s,ticks:p});n.save(),n.fontKerning="auto",U(n,{}),n.beginPath();for(let i=0;i<p.length;i++){const f=D(t,p[i],s,"canvas");n.moveTo(l,f),n.lineTo(d,f)}n.stroke(),n.restore(),n.save(),U(n,{textBaseline:"middle",textAlign:r.position==="left"?"right":"left"});for(let i=0;i<p.length;i++){const f=D(t,p[i],s,"canvas"),y=h[i].split(`
|
|
3
|
+
`);for(let x=0;x<y.length;x++)n.fillText(` ${y[x]} `,d,f+x*m)}n.restore()},mt=(t,s,e,o,c)=>{const{ctx:n}=t,r=t.scales.find(i=>i.id===s)?.axis;if(!r)return;const a=window.devicePixelRatio||1,u=xt,l=e,d=r.position==="top"?e-u:e+u,m=St*a,p=o({frame:t,scaleId:s})??[],h=c({frame:t,scaleId:s,ticks:p});n.save(),n.fontKerning="auto",U(n,{}),n.beginPath();for(let i=0;i<p.length;i++){const f=D(t,p[i],s,"canvas");n.moveTo(f,l),n.lineTo(f,d)}n.stroke(),n.restore(),n.save(),U(n,{textBaseline:r.position==="top"?"bottom":"top",textAlign:"center"});for(let i=0;i<p.length;i++){const f=D(t,p[i],s,"canvas"),y=h[i].split(`
|
|
4
|
+
`);for(let x=0;x<y.length;x++)n.fillText(y[x],f,d+a*2+x*m)}n.restore()},jt=({space:t}={})=>({frame:s,scaleId:e})=>{const{min:o,max:c}=R(s,e),n=[],r=window.devicePixelRatio||1,a=(t??(B(s,e)?gt:kt))*r,u=wt(s,a,e,"canvas"),l=Z.find(m=>m>u)??1;let d=o%l<Number.EPSILON?o:o+l-o%l;for(;d<=c;)n.push(d),d+=l;return n},Ot=({ticks:t})=>{const s=Math.max(0,Math.ceil(-Math.log10(t[1]-t[0])));return t.map(e=>e.toFixed(s))},Bt=()=>it.createStore((t,s)=>{const e=()=>{const o=s()._frame;if(!o)throw new Error("No frame set in frame store");return o};return{_frame:null,getFrame:e,getCtx:()=>e().ctx,clampXPosToChartArea:(o,c)=>Y(e(),o,c??"canvas"),clampYPosToChartArea:(o,c)=>j(e(),o,c??"canvas"),valToPos:(o,c,n)=>D(e(),o,c,n??"canvas"),valToPxDistance:(o,c,n)=>J(e(),o,c,n??"canvas"),valFits:(o,c)=>G(e(),o,c),getScale:o=>R(e(),o)}}),at=S.createContext(null),N=(t,s)=>{const e=S.useContext(at);if(!e)throw new Error("useFrame must be used within a CanPlot component");const o=S.useRef(t);o.current=t,S.useLayoutEffect(()=>{o.current(e.getState()),e.subscribe(c=>{c._frame&&o.current(c)})},[e,...s])},lt=t=>{const s=S.useContext(at);if(!s)throw new Error("useFrame must be used within a CanPlot component");return it.useStore(s,t??(e=>e.getFrame()))};function $t(t){return s=>{for(const e of t)ct(e,s)}}function Nt(t){return s=>{const e=[];for(const o of t){const c=ct(o,s),n=typeof c=="function";e.push(n?c:()=>ct(o,null))}return()=>{for(const o of e)o()}}}function ct(t,s){if(typeof t=="function")return t(s);t&&(t.current=s)}var Vt=parseInt(S.version.split(".")[0],10)>=19?Nt:$t;const Ht=S.forwardRef(({configuration:t,children:s,style:e,className:o},c)=>{const n=S.useRef(null),r=S.useRef(null),a=Wt(r),u=S.useMemo(Bt,[]);S.useLayoutEffect(()=>{u.setState({_frame:Gt(t,a,n.current)})},[t,a,n,u]),S.useLayoutEffect(()=>u.subscribe(d=>{d._frame&&qt(d._frame)}),[u]);const l=window.devicePixelRatio||1;return A.jsxs("div",{ref:Vt([c,r]),className:o,style:{position:"relative",overflow:"hidden",...e},"data-canplotroot":!0,children:[A.jsx("canvas",{ref:n,width:a.width*l,height:a.height*l,style:{inset:0,position:"absolute",width:`${a.width}px`,height:`${a.height}px`}}),A.jsx(Zt,{frameStore:u,children:s})]})}),Zt=({frameStore:t,children:s})=>it.useStore(t,o=>!!o._frame)?A.jsx(at.Provider,{value:t,children:s}):null,Wt=t=>{const[s,e]=S.useState({width:0,height:0}),[o]=S.useState(()=>new ResizeObserver(c=>{for(const n of c){const r=Math.round(n.contentRect.width),a=Math.round(n.contentRect.height);e(u=>u.width!==r||u.height!==a?{...u,width:r,height:a}:u)}}));return S.useLayoutEffect(()=>{if(!t.current)return;const c=t.current.clientWidth,n=t.current.clientHeight;return e(r=>r.width!==c||r.height!==n?{...r,width:c,height:n}:r),o.observe(t.current,{box:"border-box"}),()=>o.disconnect()},[o,t]),s},Gt=(t,s,e)=>{const o=e?.getContext("2d");if(!o)return null;const c=window.devicePixelRatio||1;if(s.width===0||s.height===0)return null;const n={x:t.padding.left,y:t.padding.top,width:s.width-t.padding.left-t.padding.right,height:s.height-t.padding.top-t.padding.bottom};for(const h of t.scales)h.axis&&(h.origin==="x"?(h.axis.position==="bottom"||h.axis.position==="top")&&(n.height=Math.max(0,n.height-h.axis.size),h.axis.position==="top"&&(n.y+=h.axis.size)):(h.axis.position==="left"||h.axis.position==="right")&&(n.width=Math.max(0,n.width-h.axis.size),h.axis.position==="left"&&(n.x+=h.axis.size)));const r={x:n.x*c,y:n.y*c,width:n.width*c,height:n.height*c},a=[];let u=t.padding.left*c,l=o.canvas.width-t.padding.right*c,d=o.canvas.height-t.padding.bottom*c,m=t.padding.top*c;for(const h of t.scales){if(!h.axis){a.push({...h,axis:null});continue}let i;if(h.origin==="x")switch(h.axis.position){case"bottom":d-=h.axis.size*c,i={x:n.x,y:d/c,width:n.width,height:h.axis.size};break;case"top":m+=h.axis.size*c,i={x:n.x,y:m/c-h.axis.size,width:n.width,height:h.axis.size};break;case"left":case"right":throw new Error("Invalid axis position for x origin")}else switch(h.axis.position){case"left":u+=h.axis.size*c,i={x:u/c-h.axis.size,y:n.y,width:h.axis.size,height:n.height};break;case"right":l-=h.axis.size*c,i={x:l/c,y:n.y,width:h.axis.size,height:n.height};break;case"top":case"bottom":throw new Error("Invalid axis position for y origin")}const f={x:i.x*c,y:i.y*c,width:i.width*c,height:i.height*c};a.push({...h,axis:{...h.axis,cssRect:i,canvasRect:f}})}return{ctx:o,dpr:c,padding:t.padding,scales:a,chartAreaCSS:n,chartAreaCanvasPX:r}},qt=t=>{t.ctx.clearRect(0,0,t.ctx.canvas.width,t.ctx.canvas.height),Yt(t)},Jt=({data:t,xScaleId:s,yScaleId:e,style:o})=>(N(({getCtx:c,clampXPosToChartArea:n,clampYPosToChartArea:r,valToPos:a})=>{const u=c();u.save(),u.beginPath(),U(u,o);for(const l of t){const d=n(a(l.x,s)),m=r(a(l.y,e));u.lineTo(d,m)}u.stroke(),u.restore()},[t,s,e,o]),null),Qt=({data:t,xScaleId:s,yScaleId:e,radius:o=5,style:c})=>(N(({getCtx:n,valToPos:r,valFits:a})=>{const u=n();u.save(),u.beginPath(),U(u,c);for(const l of t){if(!a(l.x,s)||!a(l.y,e))continue;const d=r(l.x,s),m=r(l.y,e);u.moveTo(d+o,m),u.arc(d,m,o,0,Math.PI*2)}u.stroke(),u.fill(),u.restore()},[t,s,e,o,c]),null),te=({data:t,xScaleId:s,yScaleId:e,style:o,barWidth:c,xPositionOffset:n,radius:r})=>(N(({getCtx:a,valToPxDistance:u,valToPos:l,clampXPosToChartArea:d,clampYPosToChartArea:m})=>{if(t.length===0)return;const p=a();p.save(),U(p,o);const h=u(c,s);p.beginPath();for(const i of t){const y=l(i.x,s)-h/2+n*h,x=m(l(0,e)),T=m(l(i.y,e)),g=x-T,v=d(y),E=d(y+h)-v;r?p.roundRect(v,T,E,g,r):p.rect(v,T,E,g)}p.closePath(),p.fill(),o?.strokeStyle&&p.stroke(),p.restore()},[t,s,e,o,c,n,r]),null),ee=({data:t,xScaleId:s,yScaleId:e,style:o})=>(N(({getCtx:c,clampXPosToChartArea:n,clampYPosToChartArea:r,valToPos:a})=>{const u=[];for(const d of t){const m=n(a(d.x,s)),p=r(a(d.y[0],e)),h=r(a(d.y[1],e));u.push({x:m,y:p}),u.unshift({x:m,y:h})}const l=c();if(u.length>0){l.save(),l.beginPath(),U(l,o),l.moveTo(u[0].x,u[0].y);for(const d of u)l.lineTo(d.x,d.y);l.closePath(),l.fill(),l.restore()}},[t,s,e,o]),null),se=({data:t,stroked:s,xScaleId:e,yScaleId:o,style:c})=>(N(({getCtx:n,clampXPosToChartArea:r,clampYPosToChartArea:a,valToPos:u})=>{const l=[],d=n();for(const i of t){const f=r(u(i.x,e)),y=a(u(i.y,o));l.push({x:f,y})}const m=l.at(0),p=l.at(-1);if(!m||!p)return;const h=a(u(0,o));d.save(),d.beginPath(),U(d,c),d.moveTo(m.x,h);for(const i of l)d.lineTo(i.x,i.y);if(d.lineTo(p.x,h),d.closePath(),d.fill(),s){d.beginPath(),d.moveTo(m.x,m.y);for(const i of l)d.lineTo(i.x,i.y);d.stroke()}d.restore()},[t,s,e,o,c]),null),ne=(t,s)=>lt(({clampXPosToChartArea:e,clampYPosToChartArea:o,getScale:c,valToPos:n,valFits:r})=>{const a={};for(const u in t){const l=t[u];switch(l.exceeding){case"discard":{if(r(l.value,l.scaleId)){const d=n(l.value,l.scaleId,s);a[u]=d}break}case"clamp":{const d=n(l.value,l.scaleId,s);a[u]=c(l.scaleId)?.origin==="x"?e(d,s):o(d,s);break}}}return a}),b=()=>{const t=[];return{addEventListener:(s,e)=>(t.push({syncKey:s,callback:e}),()=>{const o=t.findIndex(c=>c.callback===e);o!==-1&&t.splice(o,1)}),dispatchEvent:(s,e)=>{for(const o of t)o.syncKey===s&&o.callback(s,e)}}},w={dblclick:b(),click:b(),move:b(),mousedown:b(),mouseup:b(),spanselect:b(),documentmouseup:b(),pressandwheel:b(),sync_dblclick:b(),sync_click:b(),sync_move:b(),sync_mousedown:b(),sync_mouseup:b(),sync_spanselect:b(),sync_pressandwheel:b()},k=(t,s,e)=>{const o=S.useRef(e);o.current=e,S.useEffect(()=>w[t].addEventListener(s,(n,r)=>{o.current(r,n)}),[s,t,o])},ut=S.createContext(""),dt=(t,s)=>{const e=S.useContext(ut);return k(t,e,s)},oe=(t,s,e,o,c)=>{if(!s)return;const n=o??e.scales.find(m=>m.origin==="x")?.id,r=c??e.scales.find(m=>m.origin==="y")?.id;if(!n||!r)return;const a=t.clientX-s.left,u={scaleId:n,value:L(e,a,n,"css")},l=t.clientY-s.top,d={scaleId:r,value:L(e,l,r,"css")};return{pointerSyncPosition:{x:u,y:d},cssX:a,cssY:l}},O=(t,s)=>{const e=t.x?D(s,t.x.value,t.x.scaleId,"css"):0,o=t.y?D(s,t.y.value,t.y.scaleId,"css"):0;return{cssX:e,cssY:o,scaled:Object.fromEntries(s.scales.map(c=>{const n=c.origin==="y"?o:e;return[c.id,L(s,n,c.id,"css")]}))}},yt=(t,s,e)=>{if(!s){const r=t==="x"?e.chartAreaCSS.x:e.chartAreaCSS.y,a=t==="x"?e.chartAreaCSS.x+e.chartAreaCSS.width:e.chartAreaCSS.y+e.chartAreaCSS.height;return{fromCSS:r,toCSS:a,scaled:e.scales.flatMap(u=>{if(u.origin!==t)return[];const{min:l,max:d}=R(e,u.id);return[{scaleId:u.id,from:l,to:d}]})}}const o=D(e,s.from,s.scaleId,"css"),c=D(e,s.to,s.scaleId,"css"),n=e.scales.flatMap(r=>{if(r.origin!==t)return[];const a=L(e,o,r.id,"css"),u=L(e,c,r.id,"css");return[{scaleId:r.id,from:a,to:u}]});return{fromCSS:o,toCSS:c,scaled:n}},ce=({id:t,onClick:s,onDblClick:e,onMouseMove:o,onMouseDown:c,onMouseUp:n,onDocumentMouseUp:r,onSpanSelect:a,className:u,style:l,sync:d,children:m})=>{const p=S.useId(),h=t||p;return k("dblclick",h,i=>{e?.(i)}),k("click",h,i=>{s?.(i)}),k("move",h,i=>{o?.(i)}),k("mousedown",h,i=>{c?.(i)}),k("mouseup",h,i=>{n?.(i)}),k("documentmouseup",h,i=>{r?.(i)}),k("spanselect",h,i=>{a?.(i)}),A.jsxs(ut,{value:h,children:[A.jsx(ie,{className:u,style:l,sync:d}),m]})},ie=({className:t,style:s,sync:e})=>{const o=S.useRef(null),c=lt(),n=S.useRef(c);n.current=c;const r=S.useContext(ut),a=e?.key||r,u=S.useRef(null),l=S.useRef(null),d=S.useRef(null),m=()=>{const i=o.current?.parentElement;if(i){if(i.dataset.canplotroot===void 0)throw new Error("ChartAreaInteractions must be used within a CanPlot component");return i.getBoundingClientRect()}},p=(i,f)=>{const y=oe(i,m(),n.current,e?.xViaScaleId,e?.yViaScaleId);y&&f(y.pointerSyncPosition,{cssX:y.cssX,cssY:y.cssY},{ctrlKey:i.ctrlKey,altKey:i.altKey,shiftKey:i.shiftKey,metaKey:i.metaKey})},h=S.useRef(p);return h.current=p,S.useEffect(()=>{const i=g=>{const v=l.current;v&&w.sync_spanselect.dispatchEvent(a,{...v,completed:!0}),w.documentmouseup.dispatchEvent(a,{frame:n.current,keys:{ctrlKey:g.ctrlKey,altKey:g.altKey,shiftKey:g.shiftKey,metaKey:g.metaKey}})},f=g=>{const v={ctrlKey:g.ctrlKey,altKey:g.altKey,shiftKey:g.shiftKey,metaKey:g.metaKey},E=d.current;if(E&&Object.entries(v).some(([P,M])=>E.keys[P]!==M)){const P={...E,keys:v};d.current=P,w.sync_move.dispatchEvent(a,P)}const C=l.current;if(C&&Object.entries(v).some(([P,M])=>C.keys[P]!==M)){g.stopPropagation(),g.preventDefault();const P={...C,keys:v};l.current=P,w.sync_spanselect.dispatchEvent(a,P)}},y=g=>{h.current(g,(v,{cssX:E,cssY:C},P)=>{const M=u.current;if(!M||!v.x||!v.y)return;const X=n.current,_=M.xRangeCss.start,$=E,F=M.yRangeCss.start,tt=C,et=R(X,v.x.scaleId),st=R(X,v.y.scaleId);u.current={xRangeCss:{start:_,end:$},yRangeCss:{start:F,end:tt}};let K="none";const nt=Math.abs(F-tt),ot=Math.abs(_-$);nt<10&&ot<10?K="none":nt>30&&ot>30?K="box":nt>ot?K="y":K="x";const Tt=K==="x"||K==="box"?{scaleId:et.id,from:L(X,Y(n.current,_,"css"),et.id,"css"),to:L(X,Y(n.current,$,"css"),et.id,"css")}:void 0,bt=K==="y"||K==="box"?{scaleId:st.id,from:L(X,j(n.current,F,"css"),st.id,"css"),to:L(X,j(n.current,tt,"css"),st.id,"css")}:void 0,ht={mode:K,xRange:Tt,yRange:bt,completed:!1,keys:P};l.current=ht,w.sync_spanselect.dispatchEvent(a,ht)})},x=g=>{h.current(g,(v,E,C)=>{if(Object.values(C).some(M=>M)){g.preventDefault();const M=Math.abs(g.deltaY)>Math.abs(g.deltaX)?g.deltaY:g.deltaX;w.sync_pressandwheel.dispatchEvent(a,{positions:v,keys:C,deltaX:g.deltaX,deltaY:g.deltaY,deltaAbs:M})}})};document.addEventListener("mouseup",i),document.addEventListener("keydown",f),document.addEventListener("keyup",f),document.addEventListener("mousemove",y);const T=o.current;return T?.addEventListener("wheel",x,{passive:!1}),()=>{document.removeEventListener("mouseup",i),document.removeEventListener("keydown",f),document.removeEventListener("keyup",f),document.removeEventListener("mousemove",y),T?.removeEventListener("wheel",x)}},[n,a,h]),k("sync_dblclick",a,i=>{const f=O(i.positions,n.current);f&&w.dblclick.dispatchEvent(r,{frame:n.current,pointer:f,keys:i.keys})}),k("sync_click",a,i=>{const f=O(i.positions,n.current);f&&w.click.dispatchEvent(r,{frame:n.current,pointer:f,keys:i.keys})}),k("sync_move",a,i=>{const f=i.positions?O(i.positions,n.current):null;d.current=i,w.move.dispatchEvent(r,{frame:n.current,pointer:f??null,keys:i.keys})}),k("sync_mousedown",a,i=>{const f=O(i.positions,n.current);f&&w.mousedown.dispatchEvent(r,{frame:n.current,pointer:f,keys:i.keys})}),k("sync_mouseup",a,i=>{const f=O(i.positions,n.current);f&&w.mouseup.dispatchEvent(r,{frame:n.current,pointer:f,keys:i.keys})}),k("sync_pressandwheel",a,i=>{const f=O(i.positions,n.current);f&&w.pressandwheel.dispatchEvent(r,{frame:n.current,pointer:f,keys:i.keys,deltaX:i.deltaX,deltaY:i.deltaY,deltaAbs:i.deltaAbs})}),k("sync_spanselect",a,i=>{const f=yt("x",i.xRange,n.current),y=yt("y",i.yRange,n.current),x=f.scaled,T=y.scaled;i.completed&&(u.current=null),w.spanselect.dispatchEvent(r,{mode:i.mode,frame:n.current,xRanges:x,yRanges:T,completed:i.completed,x:{fromCSS:f.fromCSS,toCSS:f.toCSS},y:{fromCSS:y.fromCSS,toCSS:y.toCSS},keys:i.keys})}),A.jsx("div",{ref:o,id:"interactions",className:t,style:{position:"absolute",left:c.chartAreaCSS.x,top:c.chartAreaCSS.y,width:c.chartAreaCSS.width,height:c.chartAreaCSS.height,zIndex:25,...s},onClick:i=>{p(i,(f,y,x)=>{w.sync_click.dispatchEvent(a,{positions:f,keys:x})})},onMouseLeave:i=>{p(i,(f,y,x)=>{w.sync_move.dispatchEvent(a,{positions:null,keys:x})})},onMouseMove:i=>{p(i,(f,y,x)=>{w.sync_move.dispatchEvent(a,{positions:f,keys:x})})},onMouseDown:i=>{p(i,(f,{cssX:y,cssY:x},T)=>{w.sync_mousedown.dispatchEvent(a,{positions:f,keys:T}),l.current=null,u.current={xRangeCss:{start:y,end:y},yRangeCss:{start:x,end:x}}})},onMouseUp:i=>{p(i,(f,y,x)=>{w.sync_mouseup.dispatchEvent(a,{positions:f,keys:x});const T=l.current;l.current=null;const g=u.current;if(u.current=null,g&&T){const v={...T,keys:x,completed:!0};w.sync_spanselect.dispatchEvent(a,v)}})},onDoubleClick:i=>{p(i,(f,y,x)=>{w.sync_dblclick.dispatchEvent(a,{positions:f,keys:x})})}})},re=({data:t,renderTooltip:s,xScaleId:e})=>{const[o,c]=S.useState(null);dt("move",r=>{c(r)});const n=S.useMemo(()=>{if(!o)return null;const{frame:r,pointer:a}=o,u=a?.scaled[e];if(u===void 0)return null;const l=[];let d=u;for(const m of t){let p=null,h=1/0;for(const[f,y]of m.points.entries()){if(!G(r,y.x,e)||!G(r,y.y,m.yScaleId))continue;const x=Math.abs(y.x-u);x<h&&(h=x,p=f)}const i=m.points[p??-1];if(!i||J(r,h,e,"css")>30){l.push({seriesId:m.seriesId,y:null});continue}d=i.x,l.push({seriesId:m.seriesId,y:i.y})}return{frame:r,x:d,points:l}},[t,o,e]);return s(n)},ae=({makeXStyle:t,makeXClassName:s,makeYStyle:e,makeYClassName:o})=>{const[c,n]=S.useState(null);if(dt("move",d=>{n(d)}),!c)return null;const{frame:r,pointer:a}=c,u=Y(r,a?.cssX??0,"css"),l=j(r,a?.cssY??0,"css");return A.jsxs(A.Fragment,{children:[A.jsx("div",{"data-show":!!a,className:s?.(c),style:{position:"absolute",left:0,top:r.chartAreaCSS.y,height:r.chartAreaCSS.height,borderColor:"red",borderLeftWidth:"1px",borderLeftStyle:"solid",pointerEvents:"none",opacity:a?1:0,transform:`translateX(${u}px)`,...t?.(c)}}),A.jsx("div",{className:o?.(c),"data-show":!!a,style:{position:"absolute",top:0,height:0,borderTop:"solid 1px red",left:r.chartAreaCSS.x,width:r.chartAreaCSS.width,pointerEvents:"none",opacity:a?1:0,transform:`translateY(${l}px)`,...e?.(c)}})]})},le=({makeClassName:t,makeStyle:s})=>{const[e,o]=S.useState(null);if(dt("spanselect",p=>{o(p.mode==="none"||p.completed?null:p)}),!e)return null;const c=Y(e.frame,e.x.fromCSS,"css"),n=Y(e.frame,e.x.toCSS,"css"),r=j(e.frame,e.y.fromCSS,"css"),a=j(e.frame,e.y.toCSS,"css"),u=Math.min(c,n),l=Math.min(r,a),d=Math.abs(n-c),m=Math.abs(a-r);return A.jsx("div",{className:t?.(e),style:{position:"absolute",backgroundColor:"#0000ff22",left:`${u}px`,top:`${l}px`,width:`${d}px`,height:`${m}px`,pointerEvents:"none",...s?.(e)}})},ue=({style:t,children:s,scaleId:e,...o})=>{const c=lt(n=>n.getScale(e)?.axis);return c?A.jsx("div",{style:{position:"absolute",backgroundColor:"#0000ff11",left:c.cssRect.x,top:c.cssRect.y,height:c.cssRect.height,width:c.cssRect.width,...t},...o,children:s}):null};exports.AreaPlot=ee;exports.AxisOverlay=ue;exports.BarPlot=te;exports.CanPlot=Ht;exports.ChartAreaInteractions=ce;exports.Crosshair=ae;exports.LinePlot=Jt;exports.ScatterPlot=Qt;exports.SelectBox=le;exports.SparklinePlot=se;exports.TooltipsX=re;exports.applyStyles=U;exports.clampXPosToChartArea=Y;exports.clampYPosToChartArea=j;exports.getScale=R;exports.isXScale=B;exports.isYScale=Pt;exports.posToVal=L;exports.pxToValDistance=wt;exports.usePositioned=ne;exports.valFits=G;exports.valToPos=D;exports.valToPxDistance=J;
|
|
5
|
+
//# sourceMappingURL=canplot.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canplot.cjs","sources":["../src/lib/defaults.ts","../src/lib/utils.ts","../src/lib/helpers.ts","../src/lib/time.ts","../src/lib/axes.ts","../src/lib/frameContext.ts","../node_modules/react-merge-refs/dist/index.js","../src/lib/CanPlot.tsx","../src/lib/plot/LinePlot.tsx","../src/lib/plot/ScatterPlot.tsx","../src/lib/plot/BarPlot.tsx","../src/lib/plot/AreaPlot.tsx","../src/lib/plot/SparklinePlot.tsx","../src/lib/plot/AnnotationX.tsx","../src/lib/interactions/interactionsBus.ts","../src/lib/interactions/positioning.ts","../src/lib/interactions/ChartAreaInteractions.tsx","../src/lib/interactions/TooltipsX.tsx","../src/lib/interactions/CrossHair.tsx","../src/lib/interactions/SelectBox.tsx","../src/lib/interactions/AxisOverlay.tsx"],"sourcesContent":["export const DEFAULT_AXIS_SIZE = 50;\nexport const DEFAULT_POSITION = \"primary\";\nexport const DEFAULT_LABEL_ALIGN = \"center\";\nexport const DEFAULT_TICK_SIZE = 5;\nexport const DEFAULT_MULTILINE_GAP = 10;\nexport const DEFAULT_X_SPLIT_SPACE = 60;\nexport const DEFAULT_Y_SPLIT_SPACE = 30;\nexport const DEFAULT_TIMEZONE = \"UTC\";\nexport const DEFAULT_LOCALE = \"en-GB\";\nexport const DEFAULT_LABEL_OFFSET = 25;\nexport const DEFAULT_PADDING = 10;\n","export const clamp = (val: number, min: number, max: number) => {\n return Math.min(Math.max(val, min), max);\n};\n\nexport type DeepPartial<T> = {\n [P in keyof T]?: T[P] extends (infer U)[]\n ? DeepPartial<U>[]\n : T[P] extends Readonly<infer U>[]\n ? Readonly<DeepPartial<U>>[]\n : DeepPartial<T[P]>;\n};\n\nexport const sum = (input: (number | undefined)[]): number => {\n return input.reduce<number>((a, b) => a + (b ?? 0), 0);\n};\n\nexport const findClosestIndex = (arr: number[], val: number) => {\n let closestIndex = 0;\n\n for (let i = 0; i < arr.length; i++) {\n if (Math.abs(arr[i] - val) < Math.abs(arr[closestIndex] - val)) {\n closestIndex = i;\n }\n }\n return closestIndex;\n};\n","import type { PlotDrawFrame, Style } from \"./types\";\nimport { clamp } from \"./utils\";\n\nexport const pxToValDistance = (\n frame: PlotDrawFrame,\n pxDistance: number,\n scaleId: string,\n space: \"css\" | \"canvas\"\n) => {\n const { min, max } = getScale(frame, scaleId);\n const chartArea =\n space === \"canvas\" ? frame.chartAreaCanvasPX : frame.chartAreaCSS;\n const factor =\n (isXScale(frame, scaleId) ? chartArea.width : chartArea.height) /\n (max - min);\n return pxDistance / factor;\n};\n\nexport const getScale = (frame: PlotDrawFrame, scaleId: string) => {\n const scale = frame.scales.find((a) => a.id === scaleId);\n if (!scale) {\n throw new Error(`Scale ${scaleId} not found`);\n }\n return scale;\n};\n\nexport const isXScale = (frame: PlotDrawFrame, scaleId: string) =>\n frame.scales.find((s) => s.id === scaleId)?.origin === \"x\";\n\nexport const isYScale = (frame: PlotDrawFrame, scaleId: string) =>\n frame.scales.find((s) => s.id === scaleId)?.origin === \"y\";\n\nexport const applyStyles = (ctx: CanvasRenderingContext2D, style?: Style) => {\n const dpr = window.devicePixelRatio || 1;\n ctx.lineCap = style?.lineCap ?? \"butt\";\n ctx.lineDashOffset = dpr * (style?.lineDashOffset ?? 0);\n ctx.lineJoin = style?.lineJoin ?? \"miter\";\n ctx.lineWidth = dpr * (style?.lineWidth ?? 1);\n ctx.miterLimit = dpr * (style?.miterLimit ?? 10);\n ctx.strokeStyle = style?.strokeStyle ?? \"black\";\n ctx.fillStyle = style?.fillStyle ?? ctx.strokeStyle;\n ctx.font = style?.font ?? `${10 * dpr}px sans-serif`;\n ctx.textAlign = style?.textAlign ?? \"start\";\n ctx.direction = style?.direction ?? \"inherit\";\n ctx.textBaseline = style?.textBaseline ?? \"alphabetic\";\n ctx.fontKerning = style?.fontKerning ?? \"auto\";\n};\n\nexport const valToPxDistance = (\n frame: PlotDrawFrame,\n val: number,\n scaleId: string,\n space: \"css\" | \"canvas\"\n) => {\n const chartArea =\n space === \"canvas\" ? frame.chartAreaCanvasPX : frame.chartAreaCSS;\n const { min, max } = getScale(frame, scaleId);\n const factor =\n (isXScale(frame, scaleId) ? chartArea.width : chartArea.height) /\n (max - min);\n return val * factor;\n};\n\nexport const valToPos = (\n frame: PlotDrawFrame,\n val: number,\n scaleId: string,\n space: \"css\" | \"canvas\"\n) => {\n const { min } = getScale(frame, scaleId);\n const chartArea =\n space === \"canvas\" ? frame.chartAreaCanvasPX : frame.chartAreaCSS;\n const relativePosition = valToPxDistance(frame, val - min, scaleId, space);\n const result = isXScale(frame, scaleId)\n ? clamp(\n chartArea.x + relativePosition,\n chartArea.x - 10 * chartArea.width,\n chartArea.x + 11 * chartArea.width\n )\n : clamp(\n chartArea.y + chartArea.height - relativePosition,\n chartArea.y - 10 * chartArea.height,\n chartArea.y + 11 * chartArea.height\n );\n return result;\n};\n\nexport const clampUnfit = (\n frame: PlotDrawFrame,\n value: number,\n scaleId: string\n) => {\n const { min, max } = getScale(frame, scaleId);\n return clamp(value, min, max);\n};\n\nexport const clampXPosToChartArea = (\n frame: PlotDrawFrame,\n value: number,\n space: \"css\" | \"canvas\"\n) => {\n const chartArea =\n space === \"canvas\" ? frame.chartAreaCanvasPX : frame.chartAreaCSS;\n\n return clamp(value, chartArea.x, chartArea.x + chartArea.width);\n};\n\nexport const clampYPosToChartArea = (\n frame: PlotDrawFrame,\n value: number,\n space: \"css\" | \"canvas\"\n) => {\n const chartArea =\n space === \"canvas\" ? frame.chartAreaCanvasPX : frame.chartAreaCSS;\n return clamp(value, chartArea.y, chartArea.y + chartArea.height);\n};\n\nexport const valFits = (\n frame: PlotDrawFrame,\n value: number,\n scaleId: string\n): boolean => {\n const { min, max } = getScale(frame, scaleId);\n return value >= min && value <= max;\n};\n\nexport const posToVal = (\n frame: PlotDrawFrame,\n pos: number,\n scaleId: string,\n space: \"css\" | \"canvas\"\n) => {\n const { min, max } = getScale(frame, scaleId);\n const chartArea =\n space === \"canvas\" ? frame.chartAreaCanvasPX : frame.chartAreaCSS;\n\n const relativePosition = isXScale(frame, scaleId)\n ? (pos - chartArea.x) / chartArea.width\n : (chartArea.height - pos + chartArea.y) / chartArea.height;\n return min + relativePosition * (max - min);\n};\n","import type { PlotAxisGenTicks, PlotAxisTickFormat } from \"./axes\";\nimport {\n DEFAULT_LOCALE,\n DEFAULT_X_SPLIT_SPACE,\n DEFAULT_TIMEZONE,\n} from \"./defaults\";\nimport { getScale } from \"./helpers\";\n\nconst millisecond = 1;\nconst second = 1000 * millisecond;\nconst minute = 60 * second;\nconst hour = 60 * minute;\nconst day = 24 * hour;\nconst month = 30 * day;\nconst year = 365 * day;\n\ntype TimeUnit =\n | \"milliseconds\"\n | \"seconds\"\n | \"minutes\"\n | \"hours\"\n | \"days\"\n | \"months\"\n | \"years\";\n\ntype Duration = [number, TimeUnit];\n\nconst TIME_INCRS: Duration[] = [\n // second divisors\n [1, \"milliseconds\"],\n [2, \"milliseconds\"],\n [5, \"milliseconds\"],\n [10, \"milliseconds\"],\n [20, \"milliseconds\"],\n [50, \"milliseconds\"],\n [100, \"milliseconds\"],\n [200, \"milliseconds\"],\n [500, \"milliseconds\"],\n // minute divisors\n [1, \"seconds\"],\n [5, \"seconds\"],\n [10, \"seconds\"],\n [15, \"seconds\"],\n [30, \"seconds\"],\n // hour divisors\n [1, \"minutes\"],\n [5, \"minutes\"],\n [10, \"minutes\"],\n [15, \"minutes\"],\n [30, \"minutes\"],\n // day divisors\n [1, \"hours\"],\n [2, \"hours\"],\n [3, \"hours\"],\n [4, \"hours\"],\n [6, \"hours\"],\n [8, \"hours\"],\n [12, \"hours\"],\n // month divisors\n [1, \"days\"],\n [3, \"days\"],\n [5, \"days\"],\n [7, \"days\"],\n [10, \"days\"],\n [15, \"days\"],\n // year divisors\n [1, \"months\"],\n [2, \"months\"],\n [3, \"months\"],\n [4, \"months\"],\n [6, \"months\"],\n // century divisors\n [1, \"years\"],\n [2, \"years\"],\n [5, \"years\"],\n [10, \"years\"],\n [25, \"years\"],\n [50, \"years\"],\n [100, \"years\"],\n];\n\nconst durationToMilliseconds = (duration: Duration): number => {\n const [value, unit] = duration;\n switch (unit) {\n case \"milliseconds\":\n return value;\n case \"seconds\":\n return value * second;\n case \"minutes\":\n return value * minute;\n case \"hours\":\n return value * hour;\n case \"days\":\n return value * day;\n case \"months\":\n return value * month;\n case \"years\":\n return value * year;\n }\n};\n\nconst addUTCMilliseconds = (date: number | Date, deltaMilliseconds: number) => {\n const result = new Date(date);\n result.setUTCMilliseconds(result.getUTCMilliseconds() + deltaMilliseconds);\n return result.getTime();\n};\n\nconst addUTCSeconds = (date: number | Date, deltaSeconds: number) => {\n const result = new Date(date);\n result.setUTCSeconds(result.getUTCSeconds() + deltaSeconds);\n return result.getTime();\n};\n\nconst addUTCMinutes = (date: number | Date, deltaMinutes: number) => {\n const result = new Date(date);\n result.setUTCMinutes(result.getUTCMinutes() + deltaMinutes);\n return result.getTime();\n};\n\nconst addUTCHours = (date: number | Date, deltaHours: number) => {\n const result = new Date(date);\n result.setUTCHours(result.getUTCHours() + deltaHours);\n return result.getTime();\n};\n\nconst addUTCDays = (date: number | Date, deltaDays: number) => {\n const result = new Date(date);\n result.setUTCDate(result.getUTCDate() + deltaDays);\n return result.getTime();\n};\n\nconst addUTCMonths = (date: number | Date, deltaMonths: number) => {\n const result = new Date(date);\n result.setUTCMonth(result.getUTCMonth() + deltaMonths);\n return result.getTime();\n};\n\nconst addUTC = (date: number | Date, delta: Duration): number => {\n const [deltaValue, deltaUnit] = delta;\n switch (deltaUnit) {\n case \"milliseconds\":\n return addUTCMilliseconds(date, deltaValue);\n case \"seconds\":\n return addUTCSeconds(date, deltaValue);\n case \"minutes\":\n return addUTCMinutes(date, deltaValue);\n case \"hours\":\n return addUTCHours(date, deltaValue);\n case \"days\":\n return addUTCDays(date, deltaValue);\n case \"months\":\n return addUTCMonths(date, deltaValue);\n case \"years\":\n return addUTCMonths(date, deltaValue * 12);\n }\n};\n\nfunction getTimezoneOffsetHours(atTime: Date | number, timeZone: string) {\n const date = new Date(atTime);\n const localizedTime = new Date(date.toLocaleString(\"en-US\", { timeZone }));\n const utcTime = new Date(date.toLocaleString(\"en-US\", { timeZone: \"UTC\" }));\n return (localizedTime.getTime() - utcTime.getTime()) / (60 * 60 * 1000);\n}\n\nconst makeFirstTick = (\n minDate: number,\n incr: Duration,\n timeZone: string = \"UTC\"\n): number => {\n const [incrValue, incrUnit] = incr;\n let result = new Date(minDate);\n const setTimeToMidnight = () => {\n result.setUTCHours(-getTimezoneOffsetHours(result, timeZone), 0, 0, 0);\n };\n switch (incrUnit) {\n case \"milliseconds\":\n result.setUTCMilliseconds(\n Math.ceil(result.getUTCMilliseconds() / incrValue) * incrValue\n );\n break;\n case \"seconds\":\n result.setUTCSeconds(\n Math.ceil(result.getUTCSeconds() / incrValue) * incrValue,\n 0\n );\n break;\n case \"minutes\":\n result.setUTCMinutes(\n Math.ceil((result.getTime() % hour) / minute / incrValue) * incrValue,\n 0,\n 0\n );\n break;\n case \"hours\":\n result.setUTCHours(\n Math.ceil((result.getTime() % day) / hour / incrValue) * incrValue,\n 0,\n 0,\n 0\n );\n break;\n case \"days\":\n case \"months\":\n case \"years\":\n if (incrUnit === \"months\") {\n result.setUTCDate(1);\n } else if (incrUnit === \"years\") {\n result.setUTCMonth(0, 1);\n }\n setTimeToMidnight();\n if (result.getTime() < minDate) {\n result = new Date(addUTC(result, [1, incrUnit]));\n }\n break;\n }\n return result.getTime();\n};\n\ntype GenTimeTicksOpts = {\n timeZone?: string;\n space?: number;\n};\n\nexport const genTimeTicks = ({\n timeZone = DEFAULT_TIMEZONE,\n space = DEFAULT_X_SPLIT_SPACE,\n}: GenTimeTicksOpts): PlotAxisGenTicks => {\n return ({ frame, scaleId }) => {\n const { min: scaleMin, max: scaleMax } = getScale(frame, scaleId);\n const splitsCount = Math.floor(frame.chartAreaCanvasPX.width / space) + 1;\n const range = scaleMax - scaleMin;\n const splitDistance = range / splitsCount;\n const [incrValue, incrUnit] = TIME_INCRS.find(\n (a) => durationToMilliseconds(a) >= splitDistance\n ) ?? [1, \"milliseconds\"];\n\n const firstTick = makeFirstTick(scaleMin, [incrValue, incrUnit], timeZone);\n const firstTickOffset = getTimezoneOffsetHours(firstTick, timeZone);\n\n const splits: number[] = [firstTick];\n\n let candidate: number;\n while (true) {\n switch (incrUnit) {\n case \"milliseconds\":\n case \"seconds\":\n case \"minutes\":\n case \"hours\": {\n candidate = addUTC(firstTick, [splits.length * incrValue, incrUnit]);\n break;\n }\n case \"days\": {\n const tickNoDST = addUTC(firstTick, [\n splits.length * incrValue,\n incrUnit,\n ]);\n candidate = addUTC(tickNoDST, [\n firstTickOffset - getTimezoneOffsetHours(tickNoDST, timeZone),\n \"hours\",\n ]);\n break;\n }\n case \"months\":\n case \"years\": {\n const tickNoDST = addUTC(\n addUTC(addUTC(firstTick, [firstTickOffset, \"hours\"]), [\n splits.length * incrValue,\n incrUnit,\n ]),\n [-firstTickOffset, \"hours\"]\n );\n candidate = addUTC(tickNoDST, [\n firstTickOffset - getTimezoneOffsetHours(tickNoDST, timeZone),\n \"hours\",\n ]);\n break;\n }\n }\n if (candidate > scaleMax) {\n break;\n }\n splits.push(candidate);\n }\n\n return splits;\n };\n};\n\nconst isTimeFormatPartDifferent = (\n a: Intl.DateTimeFormatPart[],\n b: Intl.DateTimeFormatPart[],\n type: Intl.DateTimeFormatPart[\"type\"]\n) => {\n return (\n a.find((candidate) => candidate.type === type)?.value !==\n b.find((candidate) => candidate.type === type)?.value\n );\n};\n\ntype MakeTimeTickFormatOpts = {\n timeZone?: string;\n locale?: string;\n showTimezone?: boolean;\n};\n\nexport const makeTimeTickFormat = ({\n timeZone = DEFAULT_TIMEZONE,\n locale = DEFAULT_LOCALE,\n showTimezone = true,\n}: MakeTimeTickFormatOpts): PlotAxisTickFormat => {\n const formatter = new Intl.DateTimeFormat(locale, {\n year: \"numeric\",\n day: \"numeric\",\n month: \"short\",\n hour: \"numeric\",\n hourCycle: \"h23\",\n minute: \"numeric\",\n second: \"numeric\",\n fractionalSecondDigits: 3,\n timeZoneName: \"short\",\n timeZone,\n });\n return ({ ticks }) => {\n const splitMs = ticks[1] - ticks[0];\n const showHours = splitMs < durationToMilliseconds([1, \"days\"]);\n const showSeconds = splitMs < durationToMilliseconds([1, \"minutes\"]);\n const showMilliseconds = splitMs < durationToMilliseconds([1, \"seconds\"]);\n\n return ticks\n .map((tick) => {\n return formatter.formatToParts(new Date(tick));\n })\n .map((curr, index, arr) => {\n const prev = arr[index - 1];\n const newYear =\n index === 0 || isTimeFormatPartDifferent(curr, prev, \"year\");\n const newDay =\n index === 0 || isTimeFormatPartDifferent(curr, prev, \"day\");\n const newMonth =\n index === 0 || isTimeFormatPartDifferent(curr, prev, \"month\");\n const newHour =\n index === 0 || isTimeFormatPartDifferent(curr, prev, \"hour\");\n const newTimeZoneName =\n index === 0 || isTimeFormatPartDifferent(curr, prev, \"timeZoneName\");\n const newMinute =\n index === 0 || isTimeFormatPartDifferent(curr, prev, \"minute\");\n const newSecond =\n index === 0 || isTimeFormatPartDifferent(curr, prev, \"second\");\n const newMillisecond =\n index === 0 ||\n isTimeFormatPartDifferent(curr, prev, \"fractionalSecond\");\n\n const visibleParts: (string | undefined)[] = [];\n if (\n showHours &&\n (newHour ||\n newMinute ||\n newTimeZoneName ||\n newSecond ||\n newMillisecond)\n ) {\n const h = curr.find((a) => a.type === \"hour\")?.value;\n const m = curr.find((a) => a.type === \"minute\")?.value;\n const tz = curr.find((a) => a.type === \"timeZoneName\")?.value;\n let secondsPart = \"\";\n if (showSeconds) {\n const s = curr.find((a) => a.type === \"second\")?.value;\n const ms = curr.find((a) => a.type === \"fractionalSecond\")?.value;\n secondsPart = `:${s}` + (showMilliseconds ? `.${ms}` : \"\");\n }\n visibleParts.push(\n `${h}:${m}${secondsPart}` +\n (showTimezone && newTimeZoneName ? ` ${tz}` : \"\")\n );\n }\n if (newDay || newMonth) {\n visibleParts.push(\n [\n curr.find((a) => a.type === \"month\")?.value,\n newDay && curr.find((a) => a.type === \"day\")?.value,\n ]\n .filter(Boolean)\n .join(\" \")\n );\n }\n if (newYear) {\n visibleParts.push(curr.find((a) => a.type === \"year\")?.value);\n }\n\n return visibleParts.filter((a) => a).join(\"\\n\");\n });\n };\n};\n","import {\n DEFAULT_MULTILINE_GAP,\n DEFAULT_TICK_SIZE,\n DEFAULT_X_SPLIT_SPACE,\n DEFAULT_Y_SPLIT_SPACE,\n} from \"./defaults\";\nimport {\n applyStyles,\n getScale,\n isXScale,\n pxToValDistance,\n valToPos,\n} from \"./helpers\";\nimport { genTimeTicks, makeTimeTickFormat } from \"./time\";\nimport type { PlotDrawFrame } from \"./types\";\n\nconst acceptable_tick_values: number[] = [];\nfor (let i = -12; i <= 12; i++) {\n acceptable_tick_values.push(1 * 10 ** i);\n acceptable_tick_values.push(2 * 10 ** i);\n acceptable_tick_values.push(5 * 10 ** i);\n}\n\nexport const drawAxes = (plotDrawFrame: PlotDrawFrame) => {\n const { ctx, scales } = plotDrawFrame;\n ctx.save();\n ctx.strokeStyle = \"black\";\n ctx.fillStyle = \"black\";\n ctx.lineWidth = 1;\n ctx.font = \"12px Arial\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n\n for (const scale of scales) {\n if (!scale.axis) continue;\n const genTicks: PlotAxisGenTicks =\n scale.type === \"time\"\n ? genTimeTicks({\n space: scale.axis.tickSpace,\n timeZone: scale.timeZone,\n })\n : makeGenTicksDefault({ space: scale.axis.tickSpace });\n const formatTicks: PlotAxisTickFormat =\n scale.type === \"time\"\n ? makeTimeTickFormat({\n timeZone: scale.timeZone,\n showTimezone: scale.axis.showTimezone,\n locale: scale.locale,\n })\n : formatTicksDefault;\n const rect = scale.axis.canvasRect;\n if (scale.origin === \"x\") {\n if (scale.axis.position === \"bottom\") {\n ctx.beginPath();\n ctx.moveTo(rect.x, rect.y);\n ctx.lineTo(rect.x + rect.width, rect.y);\n ctx.stroke();\n drawXTicks(plotDrawFrame, scale.id, rect.y, genTicks, formatTicks);\n } else if (scale.axis.position === \"top\") {\n const y = rect.y + rect.height;\n ctx.beginPath();\n ctx.moveTo(rect.x, y);\n ctx.lineTo(rect.x + rect.width, y);\n ctx.stroke();\n drawXTicks(plotDrawFrame, scale.id, y, genTicks, formatTicks);\n }\n } else {\n if (scale.axis.position === \"left\") {\n const x = rect.x + rect.width;\n ctx.beginPath();\n ctx.moveTo(x, rect.y);\n ctx.lineTo(x, rect.y + rect.height);\n ctx.stroke();\n drawYTicks(plotDrawFrame, scale.id, x, genTicks, formatTicks);\n } else if (scale.axis.position === \"right\") {\n ctx.beginPath();\n ctx.moveTo(rect.x, rect.y);\n ctx.lineTo(rect.x, rect.y + rect.height);\n ctx.stroke();\n drawYTicks(plotDrawFrame, scale.id, rect.x, genTicks, formatTicks);\n }\n }\n }\n\n ctx.restore();\n};\n\nconst drawYTicks = (\n frame: PlotDrawFrame,\n scaleId: string,\n x: number,\n genTicks: PlotAxisGenTicks,\n formatTicks: PlotAxisTickFormat\n) => {\n const { ctx } = frame;\n const axis = frame.scales.find((s) => s.id === scaleId)?.axis;\n if (!axis) return;\n const dpr = window.devicePixelRatio || 1;\n const tickSize = DEFAULT_TICK_SIZE;\n const x0 = x;\n const x1 = axis.position === \"left\" ? x - tickSize : x + tickSize;\n const multilineGap = DEFAULT_MULTILINE_GAP * dpr;\n\n const ticks = genTicks({ frame, scaleId }) ?? [];\n\n const labels = formatTicks({\n frame,\n scaleId,\n ticks,\n });\n\n // draw ticks\n ctx.save();\n ctx.fontKerning = \"auto\";\n applyStyles(ctx, {});\n ctx.beginPath();\n\n for (let i = 0; i < ticks.length; i++) {\n const y = valToPos(frame, ticks[i], scaleId, \"canvas\");\n ctx.moveTo(x0, y);\n ctx.lineTo(x1, y);\n }\n ctx.stroke();\n ctx.restore();\n\n // draw tick labels\n ctx.save();\n applyStyles(ctx, {\n textBaseline: \"middle\",\n textAlign: axis.position === \"left\" ? \"right\" : \"left\",\n // ...axis.axisStyle,\n // ...axis.tickLabelStyle,\n });\n for (let i = 0; i < ticks.length; i++) {\n const y = valToPos(frame, ticks[i], scaleId, \"canvas\");\n const labelLines = labels[i].split(\"\\n\");\n for (let j = 0; j < labelLines.length; j++) {\n ctx.fillText(` ${labelLines[j]} `, x1, y + j * multilineGap);\n }\n }\n ctx.restore();\n};\n\nconst drawXTicks = (\n frame: PlotDrawFrame,\n scaleId: string,\n y: number,\n genTicks: PlotAxisGenTicks,\n formatTicks: PlotAxisTickFormat\n) => {\n const { ctx } = frame;\n const axis = frame.scales.find((s) => s.id === scaleId)?.axis;\n if (!axis) return;\n const dpr = window.devicePixelRatio || 1;\n const tickSize = DEFAULT_TICK_SIZE;\n const y0 = y;\n const y1 = axis.position === \"top\" ? y - tickSize : y + tickSize;\n const multilineGap = DEFAULT_MULTILINE_GAP * dpr;\n\n const ticks = genTicks({ frame, scaleId }) ?? [];\n\n const labels = formatTicks({ frame, scaleId, ticks });\n\n // draw ticks\n ctx.save();\n ctx.fontKerning = \"auto\";\n applyStyles(ctx, {});\n ctx.beginPath();\n\n for (let i = 0; i < ticks.length; i++) {\n const x = valToPos(frame, ticks[i], scaleId, \"canvas\");\n ctx.moveTo(x, y0);\n ctx.lineTo(x, y1);\n }\n ctx.stroke();\n ctx.restore();\n\n // draw tick labels\n ctx.save();\n applyStyles(ctx, {\n textBaseline: axis.position === \"top\" ? \"bottom\" : \"top\",\n textAlign: \"center\",\n // ...axis.axisStyle,\n // ...axis.tickLabelStyle,\n });\n for (let i = 0; i < ticks.length; i++) {\n const x = valToPos(frame, ticks[i], scaleId, \"canvas\");\n const labelLines = labels[i].split(\"\\n\");\n for (let j = 0; j < labelLines.length; j++) {\n ctx.fillText(labelLines[j], x, y1 + dpr * 2 + j * multilineGap);\n }\n }\n ctx.restore();\n};\n\nexport type PlotAxisGenTicksOpts = {\n frame: PlotDrawFrame;\n scaleId: string;\n};\n\nexport type PlotAxisTickFormatOpts = {\n frame: PlotDrawFrame;\n scaleId: string;\n ticks: number[];\n};\n\nexport type PlotAxisGenTicks = (opts: PlotAxisGenTicksOpts) => number[];\nexport type PlotAxisTickFormat = (opts: PlotAxisTickFormatOpts) => string[];\n\nexport const makeGenTicksDefault = ({\n space,\n}: { space?: number } = {}): PlotAxisGenTicks => {\n return ({ frame: frame, scaleId }) => {\n const { min: scaleMin, max: scaleMax } = getScale(frame, scaleId);\n const ticks = [];\n const dpr = window.devicePixelRatio || 1;\n const effectiveSpace =\n (space ??\n (isXScale(frame, scaleId)\n ? DEFAULT_X_SPLIT_SPACE\n : DEFAULT_Y_SPLIT_SPACE)) * dpr;\n const unnormalizedIncr = pxToValDistance(\n frame,\n effectiveSpace,\n scaleId,\n \"canvas\"\n );\n const incr = acceptable_tick_values.find((a) => a > unnormalizedIncr) ?? 1;\n let curr =\n scaleMin % incr < Number.EPSILON\n ? scaleMin\n : scaleMin + incr - (scaleMin % incr);\n while (curr <= scaleMax) {\n ticks.push(curr);\n curr += incr;\n }\n\n return ticks;\n };\n};\n\nexport const formatTicksDefault: PlotAxisTickFormat = ({ ticks }) => {\n const span = Math.max(0, Math.ceil(-Math.log10(ticks[1] - ticks[0])));\n return ticks.map((tick) => tick.toFixed(span));\n};\n","import { createContext, useContext, useLayoutEffect, useRef } from \"react\";\nimport type { PlotDrawFrame } from \"./types\";\nimport { createStore, useStore } from \"zustand\";\nimport {\n clampXPosToChartArea,\n clampYPosToChartArea,\n getScale,\n valFits,\n valToPos,\n valToPxDistance,\n} from \"./helpers\";\n\nexport interface FrameStoreState {\n _frame: PlotDrawFrame | null;\n clampXPosToChartArea: (x: number, space?: \"canvas\" | \"css\") => number;\n clampYPosToChartArea: (y: number, space?: \"canvas\" | \"css\") => number;\n getFrame: () => PlotDrawFrame;\n getCtx: () => CanvasRenderingContext2D;\n valToPos: (\n value: number,\n scaleId: string,\n space?: \"canvas\" | \"css\"\n ) => number;\n valToPxDistance: (\n value: number,\n scaleId: string,\n space?: \"canvas\" | \"css\"\n ) => number;\n valFits: (value: number, scaleId: string) => boolean;\n getScale: (scaleId: string) => PlotDrawFrame[\"scales\"][number] | undefined;\n}\n\nexport const createFrameStore = () =>\n createStore<FrameStoreState>((_, get) => {\n const getFrameOrDie = () => {\n const _frame = get()._frame;\n if (!_frame) throw new Error(\"No frame set in frame store\");\n return _frame;\n };\n return {\n _frame: null,\n getFrame: getFrameOrDie,\n getCtx: () => {\n return getFrameOrDie().ctx;\n },\n clampXPosToChartArea: (x, space) => {\n return clampXPosToChartArea(getFrameOrDie(), x, space ?? \"canvas\");\n },\n clampYPosToChartArea: (y, space) => {\n return clampYPosToChartArea(getFrameOrDie(), y, space ?? \"canvas\");\n },\n valToPos: (value, scaleId, space) => {\n return valToPos(getFrameOrDie(), value, scaleId, space ?? \"canvas\");\n },\n valToPxDistance: (value, scaleId, space) => {\n return valToPxDistance(\n getFrameOrDie(),\n value,\n scaleId,\n space ?? \"canvas\"\n );\n },\n valFits: (value, scaleId) => {\n return valFits(getFrameOrDie(), value, scaleId);\n },\n getScale: (scaleId) => {\n return getScale(getFrameOrDie(), scaleId);\n },\n };\n });\n\nexport type FrameStoreType = ReturnType<typeof createFrameStore>;\n\nexport const FrameContext = createContext<FrameStoreType | null>(null);\n\nexport const useDrawEffect = (\n runner: (params: Omit<FrameStoreState, \"_frame\">) => void,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deps: ReadonlyArray<any>\n) => {\n const frameStore = useContext(FrameContext);\n if (!frameStore) {\n throw new Error(\"useFrame must be used within a CanPlot component\");\n }\n\n const runnerRef = useRef(runner);\n runnerRef.current = runner;\n\n useLayoutEffect(() => {\n // run initial\n runnerRef.current(frameStore.getState());\n // subscribe to updates\n frameStore.subscribe((state) => {\n if (!state._frame) {\n return;\n }\n runnerRef.current(state);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [frameStore, ...deps]);\n};\n\nexport const useFrameState = <T = PlotDrawFrame>(\n selector?: (state: FrameStoreState) => T\n) => {\n const frameStore = useContext(FrameContext);\n if (!frameStore) {\n throw new Error(\"useFrame must be used within a CanPlot component\");\n }\n return useStore(\n frameStore,\n (selector as (state: FrameStoreState) => T) ?? ((state) => state.getFrame())\n );\n};\n","// src/index.ts\nimport { useMemo, version } from \"react\";\n\n// src/mergeRefsReact16.ts\nfunction mergeRefsReact16(refs) {\n return (value) => {\n for (const ref of refs) assignRef(ref, value);\n };\n}\n\n// src/mergeRefsReact19.ts\nfunction mergeRefsReact19(refs) {\n return (value) => {\n const cleanups = [];\n for (const ref of refs) {\n const cleanup = assignRef(ref, value);\n const isCleanup = typeof cleanup === \"function\";\n cleanups.push(isCleanup ? cleanup : () => assignRef(ref, null));\n }\n return () => {\n for (const cleanup of cleanups) cleanup();\n };\n };\n}\n\n// src/index.ts\nfunction assignRef(ref, value) {\n if (typeof ref === \"function\") {\n return ref(value);\n } else if (ref) {\n ref.current = value;\n }\n}\nvar mergeRefs = parseInt(version.split(\".\")[0], 10) >= 19 ? mergeRefsReact19 : mergeRefsReact16;\nfunction useMergeRefs(refs) {\n return useMemo(() => mergeRefs(refs), refs);\n}\nexport {\n assignRef,\n mergeRefs,\n useMergeRefs\n};\n","import {\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n forwardRef,\n useMemo,\n} from \"react\";\nimport type { PlotConfiguration, PlotDrawFrame, PlotSize, Rect } from \"./types\";\nimport { drawAxes } from \"./axes\";\nimport {\n createFrameStore,\n FrameContext,\n type FrameStoreState,\n} from \"./frameContext\";\nimport { mergeRefs } from \"react-merge-refs\";\nimport { useStore, type StoreApi } from \"zustand\";\n\nexport const CanPlot = forwardRef<\n HTMLDivElement,\n {\n configuration: PlotConfiguration;\n children?: ReactNode;\n style?: React.CSSProperties;\n className?: string;\n }\n>(({ configuration, children, style, className }, ref) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n\n const plotSize = useSize(rootRef);\n\n const frameStore = useMemo(createFrameStore, []);\n\n useLayoutEffect(() => {\n frameStore.setState({\n _frame: makeFrame(configuration, plotSize, canvasRef.current),\n });\n }, [configuration, plotSize, canvasRef, frameStore]);\n\n useLayoutEffect(() => {\n return frameStore.subscribe((state) => {\n if (state._frame) {\n drawFrame(state._frame);\n }\n });\n }, [frameStore]);\n\n const dpr = window.devicePixelRatio || 1;\n\n return (\n <div\n ref={mergeRefs([ref, rootRef])}\n className={className}\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n ...style,\n }}\n data-canplotroot\n >\n <canvas\n ref={canvasRef}\n width={plotSize.width * dpr}\n height={plotSize.height * dpr}\n style={{\n inset: 0,\n position: \"absolute\",\n width: `${plotSize.width}px`,\n height: `${plotSize.height}px`,\n }}\n />\n <FrameProvider frameStore={frameStore}>{children}</FrameProvider>\n </div>\n );\n});\n\nconst FrameProvider: React.FC<{\n frameStore: StoreApi<FrameStoreState>;\n children: ReactNode;\n}> = ({ frameStore, children }) => {\n const hasFrame = useStore(frameStore, (state) => !!state._frame);\n if (!hasFrame) {\n return null;\n }\n return (\n <FrameContext.Provider value={frameStore}>{children}</FrameContext.Provider>\n );\n};\n\nconst useSize = (ref: React.RefObject<HTMLElement | null>) => {\n const [plotSize, setPlotSize] = useState<PlotSize>({\n width: 0,\n height: 0,\n });\n\n const [resizeObserver] = useState(() => {\n return new ResizeObserver((entries) => {\n for (const entry of entries) {\n const width = Math.round(entry.contentRect.width);\n const height = Math.round(entry.contentRect.height);\n\n setPlotSize((prev) =>\n prev.width !== width || prev.height !== height\n ? { ...prev, width, height }\n : prev\n );\n }\n });\n });\n\n useLayoutEffect(() => {\n if (!ref.current) return;\n const width = ref.current.clientWidth;\n const height = ref.current.clientHeight;\n setPlotSize((prev) =>\n prev.width !== width || prev.height !== height\n ? { ...prev, width, height }\n : prev\n );\n resizeObserver.observe(ref.current, { box: \"border-box\" });\n return () => resizeObserver.disconnect();\n }, [resizeObserver, ref]);\n return plotSize;\n};\n\nconst makeFrame = (\n configuration: PlotConfiguration,\n size: PlotSize,\n canvas: HTMLCanvasElement | undefined | null\n): PlotDrawFrame | null => {\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx) return null;\n\n const dpr = window.devicePixelRatio || 1;\n\n if (size.width === 0 || size.height === 0) {\n return null;\n }\n\n const chartAreaCSS: PlotDrawFrame[\"chartAreaCSS\"] = {\n x: configuration.padding.left,\n y: configuration.padding.top,\n width:\n size.width - configuration.padding.left - configuration.padding.right,\n height:\n size.height - configuration.padding.top - configuration.padding.bottom,\n };\n\n for (const scale of configuration.scales) {\n if (!scale.axis) continue;\n if (scale.origin === \"x\") {\n if (scale.axis.position === \"bottom\" || scale.axis.position === \"top\") {\n chartAreaCSS.height = Math.max(\n 0,\n chartAreaCSS.height - scale.axis.size\n );\n if (scale.axis.position === \"top\") {\n chartAreaCSS.y += scale.axis.size;\n }\n }\n } else {\n if (scale.axis.position === \"left\" || scale.axis.position === \"right\") {\n chartAreaCSS.width = Math.max(0, chartAreaCSS.width - scale.axis.size);\n if (scale.axis.position === \"left\") {\n chartAreaCSS.x += scale.axis.size;\n }\n }\n }\n }\n\n const chartAreaCanvasPX: PlotDrawFrame[\"chartAreaCanvasPX\"] = {\n x: chartAreaCSS.x * dpr,\n y: chartAreaCSS.y * dpr,\n width: chartAreaCSS.width * dpr,\n height: chartAreaCSS.height * dpr,\n };\n\n const scales: PlotDrawFrame[\"scales\"] = [];\n\n let currentLeftOffset = configuration.padding.left * dpr;\n let currentRightOffset = ctx.canvas.width - configuration.padding.right * dpr;\n let currentBottomOffset =\n ctx.canvas.height - configuration.padding.bottom * dpr;\n let currentTopOffset = configuration.padding.top * dpr;\n\n for (const scale of configuration.scales) {\n if (!scale.axis) {\n scales.push({ ...scale, axis: null });\n continue;\n }\n let cssRect: Rect;\n if (scale.origin === \"x\") {\n switch (scale.axis.position) {\n case \"bottom\":\n currentBottomOffset -= scale.axis.size * dpr;\n cssRect = {\n x: chartAreaCSS.x,\n y: currentBottomOffset / dpr,\n width: chartAreaCSS.width,\n height: scale.axis.size,\n };\n break;\n case \"top\":\n currentTopOffset += scale.axis.size * dpr;\n cssRect = {\n x: chartAreaCSS.x,\n y: currentTopOffset / dpr - scale.axis.size,\n width: chartAreaCSS.width,\n height: scale.axis.size,\n };\n break;\n case \"left\":\n case \"right\":\n throw new Error(\"Invalid axis position for x origin\");\n }\n } else {\n switch (scale.axis.position) {\n case \"left\":\n currentLeftOffset += scale.axis.size * dpr;\n cssRect = {\n x: currentLeftOffset / dpr - scale.axis.size,\n y: chartAreaCSS.y,\n width: scale.axis.size,\n height: chartAreaCSS.height,\n };\n break;\n case \"right\":\n currentRightOffset -= scale.axis.size * dpr;\n cssRect = {\n x: currentRightOffset / dpr,\n y: chartAreaCSS.y,\n width: scale.axis.size,\n height: chartAreaCSS.height,\n };\n break;\n case \"top\":\n case \"bottom\":\n throw new Error(\"Invalid axis position for y origin\");\n }\n }\n const canvasRect: Rect = {\n x: cssRect.x * dpr,\n y: cssRect.y * dpr,\n width: cssRect.width * dpr,\n height: cssRect.height * dpr,\n };\n scales.push({\n ...scale,\n axis: {\n ...scale.axis,\n cssRect,\n canvasRect,\n },\n });\n }\n\n const result: PlotDrawFrame = {\n ctx,\n dpr,\n padding: configuration.padding,\n scales,\n chartAreaCSS,\n chartAreaCanvasPX,\n };\n\n return result;\n};\n\nconst drawFrame = (frame: PlotDrawFrame) => {\n frame.ctx.clearRect(0, 0, frame.ctx.canvas.width, frame.ctx.canvas.height);\n drawAxes(frame);\n};\n","import { useDrawEffect } from \"../frameContext\";\nimport { applyStyles } from \"../helpers\";\n\nexport const LinePlot: React.FC<{\n data: Array<{ x: number; y: number }>;\n xScaleId: string;\n yScaleId: string;\n style?: Partial<\n {\n fillStyle: CanvasFillStrokeStyles[\"fillStyle\"];\n strokeStyle: CanvasFillStrokeStyles[\"strokeStyle\"];\n } & Pick<\n CanvasPathDrawingStyles,\n \"lineCap\" | \"lineDashOffset\" | \"lineJoin\" | \"lineWidth\" | \"miterLimit\"\n >\n >;\n}> = ({ data, xScaleId, yScaleId, style }) => {\n useDrawEffect(\n ({ getCtx, clampXPosToChartArea, clampYPosToChartArea, valToPos }) => {\n const ctx = getCtx();\n ctx.save();\n ctx.beginPath();\n applyStyles(ctx, style);\n for (const point of data) {\n const x = clampXPosToChartArea(valToPos(point.x, xScaleId));\n const y = clampYPosToChartArea(valToPos(point.y, yScaleId));\n ctx.lineTo(x, y);\n }\n ctx.stroke();\n ctx.restore();\n },\n [data, xScaleId, yScaleId, style]\n );\n return null;\n};\n","import { useDrawEffect } from \"../frameContext\";\nimport { applyStyles } from \"../helpers\";\n\nexport const ScatterPlot: React.FC<{\n data: Array<{ x: number; y: number }>;\n xScaleId: string;\n yScaleId: string;\n radius?: number;\n style?: Partial<\n {\n fillStyle: CanvasFillStrokeStyles[\"fillStyle\"];\n strokeStyle: CanvasFillStrokeStyles[\"strokeStyle\"];\n } & Pick<\n CanvasPathDrawingStyles,\n \"lineCap\" | \"lineDashOffset\" | \"lineJoin\" | \"lineWidth\" | \"miterLimit\"\n >\n >;\n}> = ({ data, xScaleId, yScaleId, radius = 5, style }) => {\n useDrawEffect(({ getCtx, valToPos, valFits }) => {\n const ctx = getCtx();\n ctx.save();\n ctx.beginPath();\n applyStyles(ctx, style);\n for (const point of data) {\n if (!valFits(point.x, xScaleId) || !valFits(point.y, yScaleId)) {\n continue;\n }\n const x = valToPos(point.x, xScaleId);\n const y = valToPos(point.y, yScaleId);\n ctx.moveTo(x + radius, y);\n ctx.arc(x, y, radius, 0, Math.PI * 2);\n }\n ctx.stroke();\n ctx.fill();\n ctx.restore();\n }, [data, xScaleId, yScaleId, radius, style]);\n return null;\n};\n","import { useDrawEffect } from \"../frameContext\";\nimport { applyStyles } from \"../helpers\";\n\nexport const BarPlot: React.FC<{\n data: Array<{ x: number; y: number }>;\n xPositionOffset: number;\n xScaleId: string;\n yScaleId: string;\n barWidth: number;\n radius?: number;\n style?: Partial<\n {\n fillStyle: CanvasFillStrokeStyles[\"fillStyle\"];\n strokeStyle: CanvasFillStrokeStyles[\"strokeStyle\"];\n } & Pick<\n CanvasPathDrawingStyles,\n \"lineCap\" | \"lineDashOffset\" | \"lineJoin\" | \"lineWidth\" | \"miterLimit\"\n >\n >;\n}> = ({\n data,\n xScaleId,\n yScaleId,\n style,\n barWidth: barWidthRaw,\n xPositionOffset,\n radius,\n}) => {\n useDrawEffect(\n ({\n getCtx,\n valToPxDistance,\n valToPos,\n clampXPosToChartArea,\n clampYPosToChartArea,\n }) => {\n if (data.length === 0) return;\n const ctx = getCtx();\n\n ctx.save();\n applyStyles(ctx, style);\n\n const barWidth = valToPxDistance(barWidthRaw, xScaleId);\n ctx.beginPath();\n for (const datapoint of data) {\n const xCenter = valToPos(datapoint.x, xScaleId);\n\n // Adjust x position based on bar position\n const x = xCenter - barWidth / 2 + xPositionOffset * barWidth;\n\n const yBottom = clampYPosToChartArea(valToPos(0, yScaleId));\n const yTop = clampYPosToChartArea(valToPos(datapoint.y, yScaleId));\n\n const barHeight = yBottom - yTop;\n\n const compensatedX = clampXPosToChartArea(x);\n const compensatedWidth =\n clampXPosToChartArea(x + barWidth) - compensatedX;\n\n if (radius) {\n ctx.roundRect(\n compensatedX,\n yTop,\n compensatedWidth,\n barHeight,\n radius\n );\n } else {\n ctx.rect(compensatedX, yTop, compensatedWidth, barHeight);\n }\n }\n ctx.closePath();\n ctx.fill();\n if (style?.strokeStyle) {\n ctx.stroke();\n }\n\n ctx.restore();\n },\n [data, xScaleId, yScaleId, style, barWidthRaw, xPositionOffset, radius]\n );\n return null;\n};\n","import { useDrawEffect } from \"../frameContext\";\nimport { applyStyles } from \"../helpers\";\n\nexport const AreaPlot: React.FC<{\n data: Array<{ x: number; y: [number, number] }>;\n xScaleId: string;\n yScaleId: string;\n style?: Partial<\n {\n fillStyle: CanvasFillStrokeStyles[\"fillStyle\"];\n strokeStyle: CanvasFillStrokeStyles[\"strokeStyle\"];\n } & Pick<\n CanvasPathDrawingStyles,\n \"lineCap\" | \"lineDashOffset\" | \"lineJoin\" | \"lineWidth\" | \"miterLimit\"\n >\n >;\n}> = ({ data, xScaleId, yScaleId, style }) => {\n useDrawEffect(({ getCtx, clampXPosToChartArea, clampYPosToChartArea, valToPos }) => {\n const drawPoints: Array<{ x: number; y: number }> = [];\n for (const datapoint of data) {\n const x = clampXPosToChartArea(valToPos(datapoint.x, xScaleId));\n const y0 = clampYPosToChartArea(valToPos(datapoint.y[0], yScaleId));\n const y1 = clampYPosToChartArea(valToPos(datapoint.y[1], yScaleId));\n drawPoints.push({ x, y: y0 });\n drawPoints.unshift({ x, y: y1 });\n }\n \n const ctx = getCtx();\n if (drawPoints.length > 0) {\n ctx.save();\n ctx.beginPath();\n applyStyles(ctx, style);\n ctx.moveTo(drawPoints[0].x, drawPoints[0].y);\n for (const point of drawPoints) {\n ctx.lineTo(point.x, point.y);\n }\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n }\n }, [data, xScaleId, yScaleId, style]);\n return null;\n};\n","import { useDrawEffect } from \"../frameContext\";\nimport { applyStyles } from \"../helpers\";\n\nexport const SparklinePlot: React.FC<{\n data: Array<{ x: number; y: number }>;\n xScaleId: string;\n yScaleId: string;\n stroked?: boolean;\n style?: Partial<\n {\n fillStyle: CanvasFillStrokeStyles[\"fillStyle\"];\n strokeStyle: CanvasFillStrokeStyles[\"strokeStyle\"];\n } & Pick<\n CanvasPathDrawingStyles,\n \"lineCap\" | \"lineDashOffset\" | \"lineJoin\" | \"lineWidth\" | \"miterLimit\"\n >\n >;\n}> = ({ data, stroked, xScaleId, yScaleId, style }) => {\n useDrawEffect(\n ({ getCtx, clampXPosToChartArea, clampYPosToChartArea, valToPos }) => {\n const drawPoints: Array<{ x: number; y: number }> = [];\n const ctx = getCtx();\n\n for (const point of data) {\n const x = clampXPosToChartArea(valToPos(point.x, xScaleId));\n const y = clampYPosToChartArea(valToPos(point.y, yScaleId));\n drawPoints.push({ x, y });\n }\n const first = drawPoints.at(0);\n const last = drawPoints.at(-1);\n\n if (!first || !last) {\n return;\n }\n const scaledZeroY = clampYPosToChartArea(valToPos(0, yScaleId));\n\n ctx.save();\n ctx.beginPath();\n applyStyles(ctx, style);\n ctx.moveTo(first.x, scaledZeroY);\n for (const point of drawPoints) {\n ctx.lineTo(point.x, point.y);\n }\n ctx.lineTo(last.x, scaledZeroY);\n ctx.closePath();\n ctx.fill();\n if (stroked) {\n ctx.beginPath();\n ctx.moveTo(first.x, first.y);\n for (const point of drawPoints) {\n ctx.lineTo(point.x, point.y);\n }\n ctx.stroke();\n }\n ctx.restore();\n },\n [data, stroked, xScaleId, yScaleId, style]\n );\n return null;\n};\n","import { useFrameState } from \"../frameContext\";\n\nexport const usePositioned = <\n T extends Record<\n string,\n {\n value: number;\n scaleId: string;\n exceeding: \"clamp\" | \"discard\";\n }\n >\n>(\n points: T,\n space: \"canvas\" | \"css\"\n) => {\n return useFrameState(\n ({\n clampXPosToChartArea,\n clampYPosToChartArea,\n getScale,\n valToPos,\n valFits,\n }) => {\n const positioned: { [K in keyof T]?: number | undefined } = {};\n for (const key in points) {\n const point = points[key];\n switch (point.exceeding) {\n case \"discard\": {\n if (valFits(point.value, point.scaleId)) {\n const cssValue = valToPos(point.value, point.scaleId, space);\n positioned[key] = cssValue;\n }\n break;\n }\n case \"clamp\": {\n const cssValue = valToPos(point.value, point.scaleId, space);\n positioned[key] =\n getScale(point.scaleId)?.origin === \"x\"\n ? clampXPosToChartArea(cssValue, space)\n : clampYPosToChartArea(cssValue, space);\n break;\n }\n }\n }\n return positioned;\n }\n );\n};\n","import React from \"react\";\nimport type {\n ClickEvent,\n DblClickEvent,\n DocumentMouseUpEvent,\n MouseDownEvent,\n MouseUpEvent,\n MoveEvent,\n SpanSelectEvent,\n PressAndWheelEvent,\n SyncEvent_Click,\n SyncEvent_DblClick,\n SyncEvent_MouseDown,\n SyncEvent_MouseUp,\n SyncEvent_Move,\n SyncEvent_SpanSelect,\n SyncEvent_PressAndWheel,\n} from \"./types\";\n\nexport const makeInteractionsBus = <T>() => {\n const listeners: {\n syncKey: string;\n callback: (syncKey: string, payload: T) => void;\n }[] = [];\n return {\n addEventListener: (\n syncKey: string,\n callback: (syncKey: string, payload: T) => void\n ) => {\n listeners.push({\n syncKey,\n callback,\n });\n return () => {\n const index = listeners.findIndex((l) => l.callback === callback);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n };\n },\n dispatchEvent: (syncKey: string, payload: T) => {\n for (const listener of listeners) {\n if (listener.syncKey === syncKey) {\n listener.callback(syncKey, payload);\n }\n }\n },\n };\n};\n\nexport type InteractionsBus<T> = ReturnType<typeof makeInteractionsBus<T>>;\n\nexport const InteractionsBus = {\n dblclick: makeInteractionsBus<DblClickEvent>(),\n click: makeInteractionsBus<ClickEvent>(),\n move: makeInteractionsBus<MoveEvent>(),\n mousedown: makeInteractionsBus<MouseDownEvent>(),\n mouseup: makeInteractionsBus<MouseUpEvent>(),\n spanselect: makeInteractionsBus<SpanSelectEvent>(),\n documentmouseup: makeInteractionsBus<DocumentMouseUpEvent>(),\n pressandwheel: makeInteractionsBus<PressAndWheelEvent>(),\n sync_dblclick: makeInteractionsBus<SyncEvent_DblClick>(),\n sync_click: makeInteractionsBus<SyncEvent_Click>(),\n sync_move: makeInteractionsBus<SyncEvent_Move>(),\n sync_mousedown: makeInteractionsBus<SyncEvent_MouseDown>(),\n sync_mouseup: makeInteractionsBus<SyncEvent_MouseUp>(),\n sync_spanselect: makeInteractionsBus<SyncEvent_SpanSelect>(),\n sync_pressandwheel: makeInteractionsBus<SyncEvent_PressAndWheel>(),\n};\n\nexport const useGenericInteractionsEvent = <\n K extends keyof typeof InteractionsBus\n>(\n eventName: K,\n syncKey: string,\n callback: (\n payload: Parameters<(typeof InteractionsBus)[K][\"dispatchEvent\"]>[1],\n syncKey: string\n ) => void\n) => {\n const callbackRef = React.useRef(callback);\n callbackRef.current = callback;\n\n React.useEffect(() => {\n const removeListener = InteractionsBus[eventName].addEventListener(\n syncKey,\n (syncKey, payload) => {\n callbackRef.current(payload, syncKey);\n }\n );\n return removeListener;\n }, [syncKey, eventName, callbackRef]);\n};\n\nexport const InteractionsIdContext = React.createContext<string>(\"\");\n\nexport const useInteractionsEvent = <K extends keyof typeof InteractionsBus>(\n eventName: K,\n callback: (\n payload: Parameters<(typeof InteractionsBus)[K][\"dispatchEvent\"]>[1],\n syncKey: string\n ) => void\n) => {\n const interactionsId = React.useContext(InteractionsIdContext);\n\n return useGenericInteractionsEvent(eventName, interactionsId, callback);\n};\n","import { getScale, posToVal, valToPos } from \"../helpers\";\nimport type { PlotDrawFrame, PlotDrawScaleConfig } from \"../types\";\nimport type {\n InteractionsEventPointerPosition,\n PointerSyncPosition,\n ScaledSelectionRange,\n} from \"./types\";\n\nexport const makePointerSyncPosition = (\n event: Pick<MouseEvent, \"clientX\" | \"clientY\">,\n rect: DOMRect | undefined,\n frame: PlotDrawFrame,\n xViaScaleId: string | undefined,\n yViaScaleId: string | undefined\n):\n | { pointerSyncPosition: PointerSyncPosition; cssX: number; cssY: number }\n | undefined => {\n if (!rect) return;\n const effectiveXSyncViaScaleId =\n xViaScaleId ?? frame.scales.find((s) => s.origin === \"x\")?.id;\n const effectiveYSyncViaScaleId =\n yViaScaleId ?? frame.scales.find((s) => s.origin === \"y\")?.id;\n\n if (!effectiveXSyncViaScaleId || !effectiveYSyncViaScaleId) {\n return undefined;\n }\n\n const cssX = event.clientX - rect.left;\n const x: PointerSyncPosition[\"x\"] = {\n scaleId: effectiveXSyncViaScaleId,\n value: posToVal(frame, cssX, effectiveXSyncViaScaleId, \"css\"),\n };\n\n const cssY = event.clientY - rect.top;\n const y: PointerSyncPosition[\"y\"] = {\n scaleId: effectiveYSyncViaScaleId,\n value: posToVal(frame, cssY, effectiveYSyncViaScaleId, \"css\"),\n };\n\n return { pointerSyncPosition: { x, y }, cssX, cssY };\n};\n\nexport const pointerSyncPositionToInteractionsPosition = (\n pointerSyncPosition: PointerSyncPosition,\n frame: PlotDrawFrame\n): InteractionsEventPointerPosition | undefined => {\n const cssX = pointerSyncPosition.x\n ? valToPos(\n frame,\n pointerSyncPosition.x.value,\n pointerSyncPosition.x.scaleId,\n \"css\"\n )\n : 0;\n const cssY = pointerSyncPosition.y\n ? valToPos(\n frame,\n pointerSyncPosition.y.value,\n pointerSyncPosition.y.scaleId,\n \"css\"\n )\n : 0;\n return {\n cssX,\n cssY,\n scaled: Object.fromEntries(\n frame.scales.map((scale) => {\n const pos = scale.origin === \"y\" ? cssY : cssX;\n\n return [scale.id, posToVal(frame, pos, scale.id, \"css\")];\n })\n ),\n };\n};\n\nexport const extrapolateScaledSelectionRange = (\n origin: PlotDrawScaleConfig[\"origin\"],\n selectionRange: ScaledSelectionRange | undefined,\n frame: PlotDrawFrame\n): { fromCSS: number; toCSS: number; scaled: ScaledSelectionRange[] } => {\n if (!selectionRange) {\n const fromCSS =\n origin === \"x\" ? frame.chartAreaCSS.x : frame.chartAreaCSS.y;\n const toCSS =\n origin === \"x\"\n ? frame.chartAreaCSS.x + frame.chartAreaCSS.width\n : frame.chartAreaCSS.y + frame.chartAreaCSS.height;\n return {\n fromCSS,\n toCSS,\n scaled: frame.scales.flatMap((scale): ScaledSelectionRange[] => {\n if (scale.origin !== origin) {\n return [];\n }\n const { min, max } = getScale(frame, scale.id);\n return [{ scaleId: scale.id, from: min, to: max }];\n }),\n };\n }\n\n const fromCSS = valToPos(\n frame,\n selectionRange.from,\n selectionRange.scaleId,\n \"css\"\n );\n const toCSS = valToPos(\n frame,\n selectionRange.to,\n selectionRange.scaleId,\n \"css\"\n );\n const scaled: ScaledSelectionRange[] = frame.scales.flatMap(\n (scale): ScaledSelectionRange[] => {\n if (scale.origin !== origin) {\n return [];\n }\n const from = posToVal(frame, fromCSS, scale.id, \"css\");\n const to = posToVal(frame, toCSS, scale.id, \"css\");\n return [\n {\n scaleId: scale.id,\n from,\n to,\n },\n ];\n }\n );\n return {\n fromCSS,\n toCSS,\n scaled,\n };\n};\n","import { useContext, useEffect, useId, useRef } from \"react\";\nimport {\n clampXPosToChartArea,\n clampYPosToChartArea,\n getScale,\n posToVal,\n} from \"../helpers\";\nimport { useFrameState } from \"../frameContext\";\nimport {\n InteractionsBus,\n InteractionsIdContext,\n useGenericInteractionsEvent,\n} from \"./interactionsBus\";\nimport type {\n ClickEvent,\n DblClickEvent,\n DocumentMouseUpEvent,\n MouseDownEvent,\n MouseUpEvent,\n MoveEvent,\n PointerSyncPosition,\n SpanSelectEvent,\n SyncEvent_Move,\n SyncEvent_SpanSelect,\n} from \"./types\";\nimport {\n extrapolateScaledSelectionRange,\n makePointerSyncPosition,\n pointerSyncPositionToInteractionsPosition,\n} from \"./positioning\";\n\ntype ChartAreaInteractionsProps = {\n onDblClick?: (event: DblClickEvent) => void;\n onClick?: (event: ClickEvent) => void;\n onMouseMove?: (event: MoveEvent) => void;\n onMouseDown?: (event: MouseDownEvent) => void;\n onMouseUp?: (event: MouseUpEvent) => void;\n onDocumentMouseUp?: (event: DocumentMouseUpEvent) => void;\n onSpanSelect?: (event: SpanSelectEvent) => void;\n className?: string;\n style?: React.CSSProperties;\n id?: string;\n sync?: {\n key: string;\n xViaScaleId?: string;\n yViaScaleId?: string;\n };\n children?: React.ReactNode;\n};\n\nexport const ChartAreaInteractions: React.FC<ChartAreaInteractionsProps> = ({\n id,\n onClick,\n onDblClick,\n onMouseMove,\n onMouseDown,\n onMouseUp,\n onDocumentMouseUp,\n onSpanSelect,\n className,\n style,\n sync,\n children,\n}) => {\n const fallbackInteractionsId = useId();\n const interactionsId = id || fallbackInteractionsId;\n\n useGenericInteractionsEvent(\"dblclick\", interactionsId, (event) => {\n onDblClick?.(event);\n });\n useGenericInteractionsEvent(\"click\", interactionsId, (event) => {\n onClick?.(event);\n });\n useGenericInteractionsEvent(\"move\", interactionsId, (event) => {\n onMouseMove?.(event);\n });\n useGenericInteractionsEvent(\"mousedown\", interactionsId, (event) => {\n onMouseDown?.(event);\n });\n useGenericInteractionsEvent(\"mouseup\", interactionsId, (event) => {\n onMouseUp?.(event);\n });\n useGenericInteractionsEvent(\"documentmouseup\", interactionsId, (event) => {\n onDocumentMouseUp?.(event);\n });\n useGenericInteractionsEvent(\"spanselect\", interactionsId, (event) => {\n onSpanSelect?.(event);\n });\n return (\n <InteractionsIdContext value={interactionsId}>\n <ChartAreaInteractionsImpl\n className={className}\n style={style}\n sync={sync}\n />\n {children}\n </InteractionsIdContext>\n );\n};\n\nconst ChartAreaInteractionsImpl: React.FC<{\n className?: string;\n style?: React.CSSProperties;\n sync?: ChartAreaInteractionsProps[\"sync\"];\n}> = ({ className, style, sync }) => {\n const interactionsAreaRef = useRef<HTMLDivElement>(null);\n\n const _frame = useFrameState();\n\n const frameRef = useRef(_frame);\n frameRef.current = _frame;\n\n const interactionsId = useContext(InteractionsIdContext);\n\n const effectiveSyncKey = sync?.key || interactionsId;\n\n const selectStateRef = useRef<{\n xRangeCss: { start: number; end: number };\n yRangeCss: { start: number; end: number };\n } | null>(null);\n\n const lastSpanSelectSyncEventRef = useRef<SyncEvent_SpanSelect | null>(null);\n const lastMoveSyncEventRef = useRef<SyncEvent_Move | null>(null);\n\n const getRect = () => {\n const root = interactionsAreaRef.current?.parentElement;\n if (!root) {\n return undefined;\n }\n if (root.dataset.canplotroot === undefined) {\n throw new Error(\n \"ChartAreaInteractions must be used within a CanPlot component\"\n );\n }\n return root.getBoundingClientRect();\n };\n\n const withPointerPosition = (\n event: Pick<\n MouseEvent,\n \"clientX\" | \"clientY\" | \"ctrlKey\" | \"altKey\" | \"shiftKey\" | \"metaKey\"\n >,\n foo: (\n pointerSyncPosition: PointerSyncPosition,\n css: { cssX: number; cssY: number },\n keys: {\n ctrlKey: boolean;\n altKey: boolean;\n shiftKey: boolean;\n metaKey: boolean;\n }\n ) => void\n ) => {\n const positions = makePointerSyncPosition(\n event,\n getRect(),\n frameRef.current,\n sync?.xViaScaleId,\n sync?.yViaScaleId\n );\n if (positions) {\n foo(\n positions.pointerSyncPosition,\n { cssX: positions.cssX, cssY: positions.cssY },\n {\n ctrlKey: event.ctrlKey,\n altKey: event.altKey,\n shiftKey: event.shiftKey,\n metaKey: event.metaKey,\n }\n );\n }\n };\n\n const withPointerPositionRef = useRef(withPointerPosition);\n withPointerPositionRef.current = withPointerPosition;\n\n useEffect(() => {\n const mouseUpListener = (event: MouseEvent) => {\n const lastSpanSelectSyncEvent = lastSpanSelectSyncEventRef.current;\n if (lastSpanSelectSyncEvent) {\n InteractionsBus.sync_spanselect.dispatchEvent(effectiveSyncKey, {\n ...lastSpanSelectSyncEvent,\n completed: true,\n });\n }\n InteractionsBus.documentmouseup.dispatchEvent(effectiveSyncKey, {\n frame: frameRef.current,\n keys: {\n ctrlKey: event.ctrlKey,\n altKey: event.altKey,\n shiftKey: event.shiftKey,\n metaKey: event.metaKey,\n },\n });\n };\n\n const keyListener = (event: KeyboardEvent) => {\n const newKeys = {\n ctrlKey: event.ctrlKey,\n altKey: event.altKey,\n shiftKey: event.shiftKey,\n metaKey: event.metaKey,\n };\n\n const lastMove = lastMoveSyncEventRef.current;\n if (\n lastMove &&\n Object.entries(newKeys).some(\n ([key, value]) => lastMove.keys[key as keyof typeof newKeys] !== value\n )\n ) {\n const newMoveEvent = { ...lastMove, keys: newKeys };\n lastMoveSyncEventRef.current = newMoveEvent;\n InteractionsBus.sync_move.dispatchEvent(effectiveSyncKey, newMoveEvent);\n }\n\n const lastSpan = lastSpanSelectSyncEventRef.current;\n if (\n lastSpan &&\n Object.entries(newKeys).some(\n ([key, value]) => lastSpan.keys[key as keyof typeof newKeys] !== value\n )\n ) {\n // prevent default, because we're in the middle of spanning\n event.stopPropagation();\n event.preventDefault();\n const newSpanEvent = { ...lastSpan, keys: newKeys };\n lastSpanSelectSyncEventRef.current = newSpanEvent;\n InteractionsBus.sync_spanselect.dispatchEvent(\n effectiveSyncKey,\n newSpanEvent\n );\n }\n };\n\n const mouseOverDocumentListener = (event: MouseEvent) => {\n withPointerPositionRef.current(\n event,\n (positions, { cssX, cssY }, keys) => {\n const selectState = selectStateRef.current;\n if (!selectState) return;\n if (!positions.x || !positions.y) return;\n\n const frame = frameRef.current;\n const startCSSX = selectState.xRangeCss.start;\n const endCSSX = cssX;\n const startCSSY = selectState.yRangeCss.start;\n const endCSSY = cssY;\n const xScale = getScale(frame, positions.x.scaleId);\n const yScale = getScale(frame, positions.y.scaleId);\n selectStateRef.current = {\n xRangeCss: { start: startCSSX, end: endCSSX },\n yRangeCss: { start: startCSSY, end: endCSSY },\n };\n\n let mode: \"none\" | \"x\" | \"y\" | \"box\" = \"none\";\n const dY = Math.abs(startCSSY - endCSSY);\n const dX = Math.abs(startCSSX - endCSSX);\n\n if (dY < 10 && dX < 10) {\n mode = \"none\";\n } else if (dY > 30 && dX > 30) {\n mode = \"box\";\n } else if (dY > dX) {\n mode = \"y\";\n } else {\n mode = \"x\";\n }\n\n const xRange: SyncEvent_SpanSelect[\"xRange\"] =\n mode === \"x\" || mode === \"box\"\n ? {\n scaleId: xScale.id,\n from: posToVal(\n frame,\n clampXPosToChartArea(frameRef.current, startCSSX, \"css\"),\n xScale.id,\n \"css\"\n ),\n\n to: posToVal(\n frame,\n clampXPosToChartArea(frameRef.current, endCSSX, \"css\"),\n xScale.id,\n \"css\"\n ),\n }\n : undefined;\n\n const yRange: SyncEvent_SpanSelect[\"yRange\"] =\n mode === \"y\" || mode === \"box\"\n ? {\n scaleId: yScale.id,\n from: posToVal(\n frame,\n clampYPosToChartArea(frameRef.current, startCSSY, \"css\"),\n yScale.id,\n \"css\"\n ),\n\n to: posToVal(\n frame,\n clampYPosToChartArea(frameRef.current, endCSSY, \"css\"),\n yScale.id,\n \"css\"\n ),\n }\n : undefined;\n\n const spanSelectSyncEvent: SyncEvent_SpanSelect = {\n mode,\n xRange,\n yRange,\n completed: false,\n keys,\n };\n lastSpanSelectSyncEventRef.current = spanSelectSyncEvent;\n\n InteractionsBus.sync_spanselect.dispatchEvent(\n effectiveSyncKey,\n spanSelectSyncEvent\n );\n }\n );\n };\n\n const mouseWheelListener = (event: WheelEvent) => {\n withPointerPositionRef.current(event, (positions, _, keys) => {\n const anyButtonPressed = Object.values(keys).some((v) => v);\n if (anyButtonPressed) {\n event.preventDefault();\n const deltaAbs =\n Math.abs(event.deltaY) > Math.abs(event.deltaX)\n ? event.deltaY\n : event.deltaX;\n InteractionsBus.sync_pressandwheel.dispatchEvent(effectiveSyncKey, {\n positions,\n keys,\n deltaX: event.deltaX,\n deltaY: event.deltaY,\n deltaAbs,\n });\n }\n });\n };\n\n document.addEventListener(\"mouseup\", mouseUpListener);\n document.addEventListener(\"keydown\", keyListener);\n document.addEventListener(\"keyup\", keyListener);\n document.addEventListener(\"mousemove\", mouseOverDocumentListener);\n const interactionsAreaElement = interactionsAreaRef.current;\n interactionsAreaElement?.addEventListener(\"wheel\", mouseWheelListener, {\n passive: false,\n });\n return () => {\n document.removeEventListener(\"mouseup\", mouseUpListener);\n document.removeEventListener(\"keydown\", keyListener);\n document.removeEventListener(\"keyup\", keyListener);\n document.removeEventListener(\"mousemove\", mouseOverDocumentListener);\n interactionsAreaElement?.removeEventListener(\"wheel\", mouseWheelListener);\n };\n }, [frameRef, effectiveSyncKey, withPointerPositionRef]);\n\n // SYNC EVENTS\n useGenericInteractionsEvent(\"sync_dblclick\", effectiveSyncKey, (event) => {\n const positions = pointerSyncPositionToInteractionsPosition(\n event.positions,\n frameRef.current\n );\n if (!positions) return;\n InteractionsBus.dblclick.dispatchEvent(interactionsId, {\n frame: frameRef.current,\n pointer: positions,\n keys: event.keys,\n });\n });\n\n useGenericInteractionsEvent(\"sync_click\", effectiveSyncKey, (event) => {\n const positions = pointerSyncPositionToInteractionsPosition(\n event.positions,\n frameRef.current\n );\n if (!positions) return;\n InteractionsBus.click.dispatchEvent(interactionsId, {\n frame: frameRef.current,\n pointer: positions,\n keys: event.keys,\n });\n });\n\n useGenericInteractionsEvent(\"sync_move\", effectiveSyncKey, (event) => {\n const positions = event.positions\n ? pointerSyncPositionToInteractionsPosition(\n event.positions,\n frameRef.current\n )\n : null;\n lastMoveSyncEventRef.current = event;\n\n InteractionsBus.move.dispatchEvent(interactionsId, {\n frame: frameRef.current,\n pointer: positions ?? null,\n keys: event.keys,\n });\n });\n\n useGenericInteractionsEvent(\"sync_mousedown\", effectiveSyncKey, (event) => {\n const positions = pointerSyncPositionToInteractionsPosition(\n event.positions,\n frameRef.current\n );\n if (!positions) return;\n\n InteractionsBus.mousedown.dispatchEvent(interactionsId, {\n frame: frameRef.current,\n pointer: positions,\n keys: event.keys,\n });\n });\n\n useGenericInteractionsEvent(\"sync_mouseup\", effectiveSyncKey, (event) => {\n const positions = pointerSyncPositionToInteractionsPosition(\n event.positions,\n frameRef.current\n );\n if (!positions) return;\n InteractionsBus.mouseup.dispatchEvent(interactionsId, {\n frame: frameRef.current,\n pointer: positions,\n keys: event.keys,\n });\n });\n\n useGenericInteractionsEvent(\n \"sync_pressandwheel\",\n effectiveSyncKey,\n (event) => {\n const positions = pointerSyncPositionToInteractionsPosition(\n event.positions,\n frameRef.current\n );\n if (!positions) return;\n InteractionsBus.pressandwheel.dispatchEvent(interactionsId, {\n frame: frameRef.current,\n pointer: positions,\n keys: event.keys,\n deltaX: event.deltaX,\n deltaY: event.deltaY,\n deltaAbs: event.deltaAbs,\n });\n }\n );\n\n useGenericInteractionsEvent(\"sync_spanselect\", effectiveSyncKey, (event) => {\n const xMappedRange = extrapolateScaledSelectionRange(\n \"x\",\n event.xRange,\n frameRef.current\n );\n const yMappedRange = extrapolateScaledSelectionRange(\n \"y\",\n event.yRange,\n frameRef.current\n );\n\n const xRanges = xMappedRange.scaled;\n const yRanges = yMappedRange.scaled;\n\n if (event.completed) {\n selectStateRef.current = null;\n }\n\n InteractionsBus.spanselect.dispatchEvent(interactionsId, {\n mode: event.mode,\n frame: frameRef.current,\n xRanges,\n yRanges,\n completed: event.completed,\n x: { fromCSS: xMappedRange.fromCSS, toCSS: xMappedRange.toCSS },\n y: { fromCSS: yMappedRange.fromCSS, toCSS: yMappedRange.toCSS },\n keys: event.keys,\n });\n });\n\n return (\n <div\n ref={interactionsAreaRef}\n id=\"interactions\"\n className={className}\n style={{\n position: \"absolute\",\n left: _frame.chartAreaCSS.x,\n top: _frame.chartAreaCSS.y,\n width: _frame.chartAreaCSS.width,\n height: _frame.chartAreaCSS.height,\n zIndex: 25,\n ...style,\n }}\n onClick={(event) => {\n withPointerPosition(event, (positions, _, keys) => {\n InteractionsBus.sync_click.dispatchEvent(effectiveSyncKey, {\n positions,\n keys,\n });\n });\n }}\n onMouseLeave={(event) => {\n withPointerPosition(event, (_, __, keys) => {\n InteractionsBus.sync_move.dispatchEvent(effectiveSyncKey, {\n positions: null,\n keys,\n });\n });\n }}\n onMouseMove={(event) => {\n withPointerPosition(event, (positions, _, keys) => {\n InteractionsBus.sync_move.dispatchEvent(effectiveSyncKey, {\n positions,\n keys,\n });\n });\n }}\n onMouseDown={(event) => {\n withPointerPosition(event, (positions, { cssX, cssY }, keys) => {\n InteractionsBus.sync_mousedown.dispatchEvent(effectiveSyncKey, {\n positions,\n keys,\n });\n lastSpanSelectSyncEventRef.current = null;\n selectStateRef.current = {\n xRangeCss: { start: cssX, end: cssX },\n yRangeCss: { start: cssY, end: cssY },\n };\n });\n }}\n onMouseUp={(event) => {\n withPointerPosition(event, (positions, _, keys) => {\n InteractionsBus.sync_mouseup.dispatchEvent(effectiveSyncKey, {\n positions,\n keys,\n });\n const lastSpanSelectEvent = lastSpanSelectSyncEventRef.current;\n lastSpanSelectSyncEventRef.current = null;\n const selectState = selectStateRef.current;\n selectStateRef.current = null;\n if (selectState && lastSpanSelectEvent) {\n const spanSelectEvent = {\n ...lastSpanSelectEvent,\n keys,\n completed: true,\n };\n InteractionsBus.sync_spanselect.dispatchEvent(\n effectiveSyncKey,\n spanSelectEvent\n );\n }\n });\n }}\n onDoubleClick={(event) => {\n withPointerPosition(event, (positions, _, keys) => {\n InteractionsBus.sync_dblclick.dispatchEvent(effectiveSyncKey, {\n positions,\n keys,\n });\n });\n }}\n />\n );\n};\n","import { useMemo, useState } from \"react\";\nimport { useInteractionsEvent } from \"./interactionsBus\";\nimport type { MoveEvent } from \"./types\";\nimport { valFits, valToPxDistance } from \"../helpers\";\nimport type { PlotDrawFrame } from \"../types\";\n\ntype TooltipState = {\n frame: PlotDrawFrame;\n x: number;\n points: {\n seriesId: string;\n y: number | null;\n }[];\n};\n\nexport const TooltipsX: React.FC<{\n xScaleId: string;\n data: {\n seriesId: string;\n yScaleId: string;\n points: Array<{ x: number; y: number }>;\n }[];\n renderTooltip: (params: TooltipState | null) => React.ReactNode;\n}> = ({ data, renderTooltip, xScaleId }) => {\n const [moveState, setMoveState] = useState<MoveEvent | null>(null);\n\n useInteractionsEvent(\"move\", (event) => {\n const pointer = event;\n setMoveState(pointer);\n });\n\n const tooltipState = useMemo((): TooltipState | null => {\n if (!moveState) {\n return null;\n }\n\n const { frame, pointer } = moveState;\n\n const rawScaledX = pointer?.scaled[xScaleId];\n if (rawScaledX === undefined) {\n return null;\n }\n const points: TooltipState[\"points\"] = [];\n let x = rawScaledX;\n for (const series of data) {\n let closestPointIndex: number | null = null;\n let closestDistance = Infinity;\n for (const [index, point] of series.points.entries()) {\n if (\n !valFits(frame, point.x, xScaleId) ||\n !valFits(frame, point.y, series.yScaleId)\n ) {\n continue;\n }\n const distance = Math.abs(point.x - rawScaledX);\n if (distance < closestDistance) {\n closestDistance = distance;\n closestPointIndex = index;\n }\n }\n const closestPoint = series.points[closestPointIndex ?? -1];\n if (\n !closestPoint ||\n valToPxDistance(frame, closestDistance, xScaleId, \"css\") > 30\n ) {\n points.push({ seriesId: series.seriesId, y: null });\n continue;\n }\n x = closestPoint.x;\n points.push({\n seriesId: series.seriesId,\n y: closestPoint.y,\n });\n }\n return {\n frame,\n x,\n points,\n };\n }, [data, moveState, xScaleId]);\n\n return renderTooltip(tooltipState);\n};\n","import React, { useState } from \"react\";\nimport { useInteractionsEvent } from \"./interactionsBus\";\nimport type { MoveEvent } from \"./types\";\nimport { clampXPosToChartArea, clampYPosToChartArea } from \"../helpers\";\n\nexport const Crosshair: React.FC<{\n makeXStyle?: (moveEvent: MoveEvent) => React.CSSProperties | undefined;\n makeXClassName?: (moveEvent: MoveEvent) => string;\n makeYStyle?: (moveEvent: MoveEvent) => React.CSSProperties | undefined;\n makeYClassName?: (moveEvent: MoveEvent) => string;\n}> = ({ makeXStyle, makeXClassName, makeYStyle, makeYClassName }) => {\n const [moveState, setMoveState] = useState<MoveEvent | null>(null);\n\n useInteractionsEvent(\"move\", (event) => {\n const pointer = event;\n setMoveState(pointer);\n });\n\n if (!moveState) {\n return null;\n }\n\n const { frame, pointer } = moveState;\n\n const clampedX = clampXPosToChartArea(frame, pointer?.cssX ?? 0, \"css\");\n\n const clampedY = clampYPosToChartArea(frame, pointer?.cssY ?? 0, \"css\");\n\n return (\n <>\n <div\n data-show={!!pointer}\n className={makeXClassName?.(moveState)}\n style={{\n position: \"absolute\",\n left: 0,\n top: frame.chartAreaCSS.y,\n height: frame.chartAreaCSS.height,\n borderColor: \"red\",\n borderLeftWidth: \"1px\",\n borderLeftStyle: \"solid\",\n pointerEvents: \"none\",\n opacity: pointer ? 1 : 0,\n transform: `translateX(${clampedX}px)`,\n ...makeXStyle?.(moveState),\n }}\n />\n <div\n className={makeYClassName?.(moveState)}\n data-show={!!pointer}\n style={{\n position: \"absolute\",\n top: 0,\n height: 0,\n borderTop: \"solid 1px red\",\n left: frame.chartAreaCSS.x,\n width: frame.chartAreaCSS.width,\n pointerEvents: \"none\",\n opacity: pointer ? 1 : 0,\n transform: `translateY(${clampedY}px)`,\n ...makeYStyle?.(moveState),\n }}\n />\n </>\n );\n};\n","import React, { useState } from \"react\";\nimport { useInteractionsEvent } from \"./interactionsBus\";\nimport type { SpanSelectEvent } from \"./types\";\nimport { clampXPosToChartArea, clampYPosToChartArea } from \"../helpers\";\n\nexport const SelectBox: React.FC<{\n makeClassName?: (selectState: SpanSelectEvent) => string;\n makeStyle?: (selectState: SpanSelectEvent) => React.CSSProperties | undefined;\n}> = ({ makeClassName, makeStyle }) => {\n const [selectState, setSelectState] = useState<SpanSelectEvent | null>(null);\n\n useInteractionsEvent(\"spanselect\", (event) => {\n setSelectState(event.mode === \"none\" || event.completed ? null : event);\n });\n\n if (!selectState) {\n return null;\n }\n\n const clampedFromX = clampXPosToChartArea(\n selectState.frame,\n selectState.x.fromCSS,\n \"css\"\n );\n const clampedToX = clampXPosToChartArea(\n selectState.frame,\n selectState.x.toCSS,\n \"css\"\n );\n const clampedFromY = clampYPosToChartArea(\n selectState.frame,\n selectState.y.fromCSS,\n \"css\"\n );\n const clampedToY = clampYPosToChartArea(\n selectState.frame,\n selectState.y.toCSS,\n \"css\"\n );\n\n const leftPx = Math.min(clampedFromX, clampedToX);\n const topPx = Math.min(clampedFromY, clampedToY);\n const widthPx = Math.abs(clampedToX - clampedFromX);\n const heightPx = Math.abs(clampedToY - clampedFromY);\n\n return (\n <div\n className={makeClassName?.(selectState)}\n style={{\n position: \"absolute\",\n backgroundColor: \"#0000ff22\",\n left: `${leftPx}px`,\n top: `${topPx}px`,\n width: `${widthPx}px`,\n height: `${heightPx}px`,\n pointerEvents: \"none\",\n ...makeStyle?.(selectState),\n }}\n />\n );\n};\n","import React from \"react\";\nimport { useFrameState } from \"../frameContext\";\n\nexport const AxisOverlay: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n scaleId: string;\n }\n> = ({ style, children, scaleId, ...rest }) => {\n const axis = useFrameState((it) => it.getScale(scaleId)?.axis);\n\n if (!axis) {\n return null;\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n backgroundColor: \"#0000ff11\",\n left: axis.cssRect.x,\n top: axis.cssRect.y,\n height: axis.cssRect.height,\n width: axis.cssRect.width,\n ...style,\n }}\n {...rest}\n >\n {children}\n </div>\n );\n};\n"],"names":["DEFAULT_TICK_SIZE","DEFAULT_MULTILINE_GAP","DEFAULT_X_SPLIT_SPACE","DEFAULT_Y_SPLIT_SPACE","DEFAULT_TIMEZONE","DEFAULT_LOCALE","clamp","val","min","max","pxToValDistance","frame","pxDistance","scaleId","space","getScale","chartArea","factor","isXScale","scale","a","s","isYScale","applyStyles","ctx","style","dpr","valToPxDistance","valToPos","relativePosition","clampXPosToChartArea","value","clampYPosToChartArea","valFits","posToVal","pos","millisecond","second","minute","hour","day","month","year","TIME_INCRS","durationToMilliseconds","duration","unit","addUTCMilliseconds","date","deltaMilliseconds","result","addUTCSeconds","deltaSeconds","addUTCMinutes","deltaMinutes","addUTCHours","deltaHours","addUTCDays","deltaDays","addUTCMonths","deltaMonths","addUTC","delta","deltaValue","deltaUnit","getTimezoneOffsetHours","atTime","timeZone","localizedTime","utcTime","makeFirstTick","minDate","incr","incrValue","incrUnit","setTimeToMidnight","genTimeTicks","scaleMin","scaleMax","splitsCount","splitDistance","firstTick","firstTickOffset","splits","candidate","tickNoDST","isTimeFormatPartDifferent","b","type","makeTimeTickFormat","locale","showTimezone","formatter","ticks","splitMs","showHours","showSeconds","showMilliseconds","tick","curr","index","arr","prev","newYear","newDay","newMonth","newHour","newTimeZoneName","newMinute","newSecond","newMillisecond","visibleParts","h","m","tz","secondsPart","ms","acceptable_tick_values","i","drawAxes","plotDrawFrame","scales","genTicks","makeGenTicksDefault","formatTicks","formatTicksDefault","rect","drawXTicks","y","x","drawYTicks","axis","tickSize","x0","x1","multilineGap","labels","labelLines","j","y0","y1","effectiveSpace","unnormalizedIncr","span","createFrameStore","createStore","_","get","getFrameOrDie","_frame","FrameContext","createContext","useDrawEffect","runner","deps","frameStore","useContext","runnerRef","useRef","useLayoutEffect","state","useFrameState","selector","useStore","mergeRefsReact16","refs","ref","assignRef","mergeRefsReact19","cleanups","cleanup","isCleanup","mergeRefs","version","CanPlot","forwardRef","configuration","children","className","canvasRef","rootRef","plotSize","useSize","useMemo","makeFrame","drawFrame","jsxs","jsx","FrameProvider","setPlotSize","useState","resizeObserver","entries","entry","width","height","size","canvas","chartAreaCSS","chartAreaCanvasPX","currentLeftOffset","currentRightOffset","currentBottomOffset","currentTopOffset","cssRect","canvasRect","LinePlot","data","xScaleId","yScaleId","getCtx","point","ScatterPlot","radius","BarPlot","barWidthRaw","xPositionOffset","barWidth","datapoint","yBottom","yTop","barHeight","compensatedX","compensatedWidth","AreaPlot","drawPoints","SparklinePlot","stroked","first","last","scaledZeroY","usePositioned","points","positioned","key","cssValue","makeInteractionsBus","listeners","syncKey","callback","l","payload","listener","InteractionsBus","useGenericInteractionsEvent","eventName","callbackRef","React","InteractionsIdContext","useInteractionsEvent","interactionsId","makePointerSyncPosition","event","xViaScaleId","yViaScaleId","effectiveXSyncViaScaleId","effectiveYSyncViaScaleId","cssX","cssY","pointerSyncPositionToInteractionsPosition","pointerSyncPosition","extrapolateScaledSelectionRange","origin","selectionRange","fromCSS","toCSS","scaled","from","to","ChartAreaInteractions","id","onClick","onDblClick","onMouseMove","onMouseDown","onMouseUp","onDocumentMouseUp","onSpanSelect","sync","fallbackInteractionsId","useId","ChartAreaInteractionsImpl","interactionsAreaRef","frameRef","effectiveSyncKey","selectStateRef","lastSpanSelectSyncEventRef","lastMoveSyncEventRef","getRect","root","withPointerPosition","foo","positions","withPointerPositionRef","useEffect","mouseUpListener","lastSpanSelectSyncEvent","keyListener","newKeys","lastMove","newMoveEvent","lastSpan","newSpanEvent","mouseOverDocumentListener","keys","selectState","startCSSX","endCSSX","startCSSY","endCSSY","xScale","yScale","mode","dY","dX","xRange","yRange","spanSelectSyncEvent","mouseWheelListener","v","deltaAbs","interactionsAreaElement","xMappedRange","yMappedRange","xRanges","yRanges","__","lastSpanSelectEvent","spanSelectEvent","TooltipsX","renderTooltip","moveState","setMoveState","tooltipState","pointer","rawScaledX","series","closestPointIndex","closestDistance","distance","closestPoint","Crosshair","makeXStyle","makeXClassName","makeYStyle","makeYClassName","clampedX","clampedY","Fragment","SelectBox","makeClassName","makeStyle","setSelectState","clampedFromX","clampedToX","clampedFromY","clampedToY","leftPx","topPx","widthPx","heightPx","AxisOverlay","rest","it"],"mappings":"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","x_google_ignoreList":[6]}
|