minerva-design 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/charts/canvas.d.cts +7 -0
  3. package/dist/charts/canvas.d.ts +7 -0
  4. package/dist/charts/core.cjs +1 -1
  5. package/dist/charts/core.d.cts +5 -1
  6. package/dist/charts/core.d.ts +5 -1
  7. package/dist/charts/core.js +4 -1
  8. package/dist/charts/engine/canvas.cjs +2 -0
  9. package/dist/charts/engine/canvas.cjs.map +1 -0
  10. package/dist/charts/engine/canvas.d.cts +85 -0
  11. package/dist/charts/engine/canvas.d.ts +85 -0
  12. package/dist/charts/engine/canvas.js +165 -0
  13. package/dist/charts/engine/canvas.js.map +1 -0
  14. package/dist/charts/engine/chart.cjs +2 -2
  15. package/dist/charts/engine/chart.cjs.map +1 -1
  16. package/dist/charts/engine/chart.js +382 -440
  17. package/dist/charts/engine/chart.js.map +1 -1
  18. package/dist/charts/engine/color.cjs +1 -1
  19. package/dist/charts/engine/color.cjs.map +1 -1
  20. package/dist/charts/engine/color.d.cts +10 -0
  21. package/dist/charts/engine/color.d.ts +10 -0
  22. package/dist/charts/engine/color.js +75 -3
  23. package/dist/charts/engine/color.js.map +1 -1
  24. package/dist/charts/engine/controller.cjs +3 -0
  25. package/dist/charts/engine/controller.cjs.map +1 -0
  26. package/dist/charts/engine/controller.d.cts +182 -0
  27. package/dist/charts/engine/controller.d.ts +182 -0
  28. package/dist/charts/engine/controller.js +528 -0
  29. package/dist/charts/engine/controller.js.map +1 -0
  30. package/dist/charts/engine/model.cjs +1 -1
  31. package/dist/charts/engine/model.cjs.map +1 -1
  32. package/dist/charts/engine/model.d.cts +2 -2
  33. package/dist/charts/engine/model.d.ts +2 -2
  34. package/dist/charts/engine/model.js +72 -72
  35. package/dist/charts/engine/model.js.map +1 -1
  36. package/dist/charts/engine/overlay.cjs +1 -1
  37. package/dist/charts/engine/overlay.cjs.map +1 -1
  38. package/dist/charts/engine/overlay.d.cts +17 -1
  39. package/dist/charts/engine/overlay.d.ts +17 -1
  40. package/dist/charts/engine/overlay.js +63 -49
  41. package/dist/charts/engine/overlay.js.map +1 -1
  42. package/dist/charts/engine/presets.cjs +3 -0
  43. package/dist/charts/engine/presets.cjs.map +1 -0
  44. package/dist/charts/engine/presets.d.cts +103 -0
  45. package/dist/charts/engine/presets.d.ts +103 -0
  46. package/dist/charts/engine/presets.js +153 -0
  47. package/dist/charts/engine/presets.js.map +1 -0
  48. package/dist/charts/engine/renderers/canvas2d.cjs +1 -1
  49. package/dist/charts/engine/renderers/canvas2d.cjs.map +1 -1
  50. package/dist/charts/engine/renderers/canvas2d.d.cts +17 -1
  51. package/dist/charts/engine/renderers/canvas2d.d.ts +17 -1
  52. package/dist/charts/engine/renderers/canvas2d.js +88 -51
  53. package/dist/charts/engine/renderers/canvas2d.js.map +1 -1
  54. package/dist/charts/engine/scene.cjs +2 -0
  55. package/dist/charts/engine/scene.cjs.map +1 -0
  56. package/dist/charts/engine/scene.d.cts +89 -0
  57. package/dist/charts/engine/scene.d.ts +89 -0
  58. package/dist/charts/engine/scene.js +241 -0
  59. package/dist/charts/engine/scene.js.map +1 -0
  60. package/dist/charts/engine/theme.cjs +1 -1
  61. package/dist/charts/engine/theme.cjs.map +1 -1
  62. package/dist/charts/engine/theme.d.cts +25 -1
  63. package/dist/charts/engine/theme.d.ts +25 -1
  64. package/dist/charts/engine/theme.js +42 -26
  65. package/dist/charts/engine/theme.js.map +1 -1
  66. package/dist/charts/engine/types.d.cts +69 -2
  67. package/dist/charts/engine/types.d.ts +69 -2
  68. package/dist/charts/index.cjs +1 -1
  69. package/dist/charts/index.d.cts +1 -1
  70. package/dist/charts/index.d.ts +1 -1
  71. package/dist/charts/index.js +5 -2
  72. package/dist/charts/react/Chart.cjs +1 -1
  73. package/dist/charts/react/Chart.cjs.map +1 -1
  74. package/dist/charts/react/Chart.d.cts +11 -4
  75. package/dist/charts/react/Chart.d.ts +11 -4
  76. package/dist/charts/react/Chart.js +81 -39
  77. package/dist/charts/react/Chart.js.map +1 -1
  78. package/dist/charts/react/charts.cjs +1 -1
  79. package/dist/charts/react/charts.cjs.map +1 -1
  80. package/dist/charts/react/charts.d.cts +1 -1
  81. package/dist/charts/react/charts.d.ts +1 -1
  82. package/dist/charts/react/charts.js +99 -145
  83. package/dist/charts/react/charts.js.map +1 -1
  84. package/dist/charts/react/types.d.cts +29 -61
  85. package/dist/charts/react/types.d.ts +29 -61
  86. package/dist/native/charts/src/canvas.cjs +1 -0
  87. package/dist/native/charts/src/canvas.js +6 -0
  88. package/dist/native/charts/src/engine/axis.cjs +2 -0
  89. package/dist/native/charts/src/engine/axis.cjs.map +1 -0
  90. package/dist/native/charts/src/engine/axis.js +38 -0
  91. package/dist/native/charts/src/engine/axis.js.map +1 -0
  92. package/dist/native/charts/src/engine/canvas.cjs +1 -0
  93. package/dist/native/charts/src/engine/canvas.js +1 -0
  94. package/dist/native/charts/src/engine/color.cjs +2 -0
  95. package/dist/native/charts/src/engine/color.cjs.map +1 -0
  96. package/dist/native/charts/src/engine/color.js +130 -0
  97. package/dist/native/charts/src/engine/color.js.map +1 -0
  98. package/dist/native/charts/src/engine/controller.cjs +3 -0
  99. package/dist/native/charts/src/engine/controller.cjs.map +1 -0
  100. package/dist/native/charts/src/engine/controller.js +528 -0
  101. package/dist/native/charts/src/engine/controller.js.map +1 -0
  102. package/dist/native/charts/src/engine/data.cjs +2 -0
  103. package/dist/native/charts/src/engine/data.cjs.map +1 -0
  104. package/dist/native/charts/src/engine/data.js +104 -0
  105. package/dist/native/charts/src/engine/data.js.map +1 -0
  106. package/dist/native/charts/src/engine/decimate.cjs +2 -0
  107. package/dist/native/charts/src/engine/decimate.cjs.map +1 -0
  108. package/dist/native/charts/src/engine/decimate.js +28 -0
  109. package/dist/native/charts/src/engine/decimate.js.map +1 -0
  110. package/dist/native/charts/src/engine/format.cjs +2 -0
  111. package/dist/native/charts/src/engine/format.cjs.map +1 -0
  112. package/dist/native/charts/src/engine/format.js +34 -0
  113. package/dist/native/charts/src/engine/format.js.map +1 -0
  114. package/dist/native/charts/src/engine/layout.cjs +2 -0
  115. package/dist/native/charts/src/engine/layout.cjs.map +1 -0
  116. package/dist/native/charts/src/engine/layout.js +26 -0
  117. package/dist/native/charts/src/engine/layout.js.map +1 -0
  118. package/dist/native/charts/src/engine/model.cjs +2 -0
  119. package/dist/native/charts/src/engine/model.cjs.map +1 -0
  120. package/dist/native/charts/src/engine/model.js +175 -0
  121. package/dist/native/charts/src/engine/model.js.map +1 -0
  122. package/dist/native/charts/src/engine/overlay.cjs +2 -0
  123. package/dist/native/charts/src/engine/overlay.cjs.map +1 -0
  124. package/dist/native/charts/src/engine/overlay.js +49 -0
  125. package/dist/native/charts/src/engine/overlay.js.map +1 -0
  126. package/dist/native/charts/src/engine/presets.cjs +3 -0
  127. package/dist/native/charts/src/engine/presets.cjs.map +1 -0
  128. package/dist/native/charts/src/engine/presets.js +147 -0
  129. package/dist/native/charts/src/engine/presets.js.map +1 -0
  130. package/dist/native/charts/src/engine/scale.cjs +2 -0
  131. package/dist/native/charts/src/engine/scale.cjs.map +1 -0
  132. package/dist/native/charts/src/engine/scale.js +37 -0
  133. package/dist/native/charts/src/engine/scale.js.map +1 -0
  134. package/dist/native/charts/src/engine/scene.cjs +2 -0
  135. package/dist/native/charts/src/engine/scene.cjs.map +1 -0
  136. package/dist/native/charts/src/engine/scene.js +241 -0
  137. package/dist/native/charts/src/engine/scene.js.map +1 -0
  138. package/dist/native/charts/src/engine/spatial.cjs +2 -0
  139. package/dist/native/charts/src/engine/spatial.cjs.map +1 -0
  140. package/dist/native/charts/src/engine/spatial.js +53 -0
  141. package/dist/native/charts/src/engine/spatial.js.map +1 -0
  142. package/dist/native/charts/src/engine/theme.cjs +2 -0
  143. package/dist/native/charts/src/engine/theme.cjs.map +1 -0
  144. package/dist/native/charts/src/engine/theme.js +62 -0
  145. package/dist/native/charts/src/engine/theme.js.map +1 -0
  146. package/dist/native/charts/src/engine/time.cjs +2 -0
  147. package/dist/native/charts/src/engine/time.cjs.map +1 -0
  148. package/dist/native/charts/src/engine/time.js +189 -0
  149. package/dist/native/charts/src/engine/time.js.map +1 -0
  150. package/dist/native/charts/src/engine/viewport.cjs +2 -0
  151. package/dist/native/charts/src/engine/viewport.cjs.map +1 -0
  152. package/dist/native/charts/src/engine/viewport.js +12 -0
  153. package/dist/native/charts/src/engine/viewport.js.map +1 -0
  154. package/dist/native/components/Chart/ChartBase.cjs +2 -0
  155. package/dist/native/components/Chart/ChartBase.cjs.map +1 -0
  156. package/dist/native/components/Chart/ChartBase.d.cts +29 -0
  157. package/dist/native/components/Chart/ChartBase.d.ts +29 -0
  158. package/dist/native/components/Chart/ChartBase.js +287 -0
  159. package/dist/native/components/Chart/ChartBase.js.map +1 -0
  160. package/dist/native/components/Chart/charts.cjs +2 -0
  161. package/dist/native/components/Chart/charts.cjs.map +1 -0
  162. package/dist/native/components/Chart/charts.d.cts +19 -0
  163. package/dist/native/components/Chart/charts.d.ts +19 -0
  164. package/dist/native/components/Chart/charts.js +173 -0
  165. package/dist/native/components/Chart/charts.js.map +1 -0
  166. package/dist/native/components/Chart/index.cjs +1 -0
  167. package/dist/native/components/Chart/index.d.cts +2 -0
  168. package/dist/native/components/Chart/index.d.ts +2 -0
  169. package/dist/native/components/Chart/index.js +2 -0
  170. package/dist/native/components/Chart/measure.cjs +2 -0
  171. package/dist/native/components/Chart/measure.cjs.map +1 -0
  172. package/dist/native/components/Chart/measure.d.cts +5 -0
  173. package/dist/native/components/Chart/measure.d.ts +5 -0
  174. package/dist/native/components/Chart/measure.js +11 -0
  175. package/dist/native/components/Chart/measure.js.map +1 -0
  176. package/dist/native/components/Chart/scene.cjs +2 -0
  177. package/dist/native/components/Chart/scene.cjs.map +1 -0
  178. package/dist/native/components/Chart/scene.d.cts +41 -0
  179. package/dist/native/components/Chart/scene.d.ts +41 -0
  180. package/dist/native/components/Chart/scene.js +419 -0
  181. package/dist/native/components/Chart/scene.js.map +1 -0
  182. package/dist/native/components/Chart/theme.cjs +2 -0
  183. package/dist/native/components/Chart/theme.cjs.map +1 -0
  184. package/dist/native/components/Chart/theme.d.cts +10 -0
  185. package/dist/native/components/Chart/theme.d.ts +10 -0
  186. package/dist/native/components/Chart/theme.js +10 -0
  187. package/dist/native/components/Chart/theme.js.map +1 -0
  188. package/dist/native/components/Chart/types.d.cts +129 -0
  189. package/dist/native/components/Chart/types.d.ts +129 -0
  190. package/dist/native/index.cjs +1 -1
  191. package/dist/native/index.d.cts +1 -0
  192. package/dist/native/index.d.ts +1 -0
  193. package/dist/native/index.js +6 -4
  194. package/dist/native/manifest.d.cts +7 -0
  195. package/dist/native/manifest.d.ts +7 -0
  196. package/dist/native/source/components/Chart/ChartBase.tsx +545 -0
  197. package/dist/native/source/components/Chart/charts.tsx +291 -0
  198. package/dist/native/source/components/Chart/index.ts +8 -0
  199. package/dist/native/source/components/Chart/measure.ts +50 -0
  200. package/dist/native/source/components/Chart/scene.tsx +987 -0
  201. package/dist/native/source/components/Chart/theme.ts +16 -0
  202. package/dist/native/source/components/Chart/types.ts +194 -0
  203. package/dist/native/source/index.ts +1 -0
  204. package/dist/native/source/manifest.ts +14 -0
  205. package/dist/taro/charts.d.ts +144 -0
  206. package/dist/taro/index.d.ts +1 -0
  207. package/dist/taro/index.js +3064 -618
  208. package/dist/uni/BarChart.vue +75 -0
  209. package/dist/uni/BarChart.vue.d.ts +111 -0
  210. package/dist/uni/Chart.vue +68 -0
  211. package/dist/uni/Chart.vue.d.ts +100 -0
  212. package/dist/uni/LineChart.vue +75 -0
  213. package/dist/uni/LineChart.vue.d.ts +111 -0
  214. package/dist/uni/ProgressIndicator.vue.d.ts +1 -1
  215. package/dist/uni/QuadrantChart.vue +184 -0
  216. package/dist/uni/QuadrantChart.vue.d.ts +173 -0
  217. package/dist/uni/ScatterChart.vue +69 -0
  218. package/dist/uni/ScatterChart.vue.d.ts +100 -0
  219. package/dist/uni/chart-canvas.d.ts +68 -0
  220. package/dist/uni/chart-canvas.js +363 -0
  221. package/dist/uni/chart-types.d.ts +135 -0
  222. package/dist/uni/chart-types.js +84 -0
  223. package/dist/uni/charts-canvas.d.ts +1 -0
  224. package/dist/uni/charts-canvas.js +8 -0
  225. package/dist/uni/index.d.ts +6 -0
  226. package/dist/uni/index.js +6 -0
  227. package/dist/weapp/bar-chart/index.js +1 -0
  228. package/dist/weapp/bar-chart/index.json +1 -0
  229. package/dist/weapp/bar-chart/index.wxml +1 -0
  230. package/dist/weapp/bar-chart/index.wxss +1 -0
  231. package/dist/weapp/chart/index.js +1 -0
  232. package/dist/weapp/chart/index.json +1 -0
  233. package/dist/weapp/chart/index.wxml +1 -0
  234. package/dist/weapp/chart/index.wxss +1 -0
  235. package/dist/weapp/controls.js +4019 -266
  236. package/dist/weapp/line-chart/index.js +1 -0
  237. package/dist/weapp/line-chart/index.json +1 -0
  238. package/dist/weapp/line-chart/index.wxml +1 -0
  239. package/dist/weapp/line-chart/index.wxss +1 -0
  240. package/dist/weapp/quadrant-chart/index.js +1 -0
  241. package/dist/weapp/quadrant-chart/index.json +1 -0
  242. package/dist/weapp/quadrant-chart/index.wxml +1 -0
  243. package/dist/weapp/quadrant-chart/index.wxss +1 -0
  244. package/dist/weapp/scatter-chart/index.js +1 -0
  245. package/dist/weapp/scatter-chart/index.json +1 -0
  246. package/dist/weapp/scatter-chart/index.wxml +1 -0
  247. package/dist/weapp/scatter-chart/index.wxss +1 -0
  248. package/dist/weapp/types.d.ts +295 -0
  249. package/package.json +21 -1
@@ -1,2 +1,2 @@
1
- const e=require("./scale.cjs"),t=require("./color.cjs"),n=require("./data.cjs"),r=require("./spatial.cjs");var i=e=>{if(typeof e==`object`&&e&&!(`length`in e)){let t=e.x;return t&&t.length?t[0]:void 0}let t=e;for(let e=0;e<Math.min(t.length,8);e++){let n=t[e];if(Array.isArray(n))return n[0];if(n&&typeof n==`object`)return n.x}},a=e=>{for(let t of e){let e=i(t);if(e instanceof Date)return`time`;if(typeof e==`string`)return`category`}return`linear`},o=(e,t,n,r)=>({type:t,reverse:!!e?.reverse,categories:n,title:e?.title,format:e?.format,grid:e?.grid??r,visible:e?.visible??!0,tickCount:e?.tickCount}),s=e=>{let t=1/0,n=-1/0;for(let r=0;r<e.length;r++){let i=e[r];Number.isFinite(i)&&(i<t&&(t=i),i>n&&(n=i))}return[t,n]},c=e=>{let t=1/0;for(let n of e){let e=n.sorted?n.x:Float64Array.from(n.x).sort();for(let r=1;r<n.count;r++){let n=e[r]-e[r-1];n>0&&n<t&&(t=n)}}return t},l=(r,i,l,u,d)=>{let f=r.series,p=f.map(e=>e.data),m=r.xAxis?.type??a(p),h=m===`category`?[...r.xAxis?.categories??n.collectCategories(p)]:[],g=new Map(h.map((e,t)=>[e,t])),_=n.xResolver(m,e=>g.get(e)??NaN),v=`${m}|${h.join(``)}`,y=new Set,b=f.map((e,r)=>{let a=e.id??`#${r}`;for(;y.has(a);)a+=`'`;y.add(a);let o=u.get(a);(!o||o.data!==e.data||o.resolverKey!==v)&&(o={data:e.data,resolverKey:v,cols:n.normalizeData(e.data,_)},u.set(a,o));let s=e.type??`line`,c=e.color?t.resolveColor(e.color,d,i.palette[r%i.palette.length]):i.palette[r%i.palette.length],f=o.cols,p=null;if(s===`scatter`&&f.colors){let e=new Map;p=f.colors.map(n=>{if(n===void 0)return;let r=e.get(n);return r||e.set(n,r=t.resolveColor(n,d,c)),r})}let m=e.id??String(r);return{index:r,key:a,id:m,name:e.name??`Series ${r+1}`,type:s,color:c,colorCss:t.toCss(c),lineWidth:e.lineWidth??2,pointSize:e.pointSize??8,opacity:e.opacity??(s===`area`?.28:s===`scatter`?.78:1),hidden:!!e.hidden||l.has(m),showLabels:!!e.showLabels,cols:f,barOffset:0,barHalfWidth:0,barBase:null,barTop:null,pointColors:p}}),x=b.filter(e=>!e.hidden),S=b.length>0&&b.every(e=>e.type===`scatter`),C=x.filter(e=>e.type===`bar`),w=m===`category`?1:(()=>{let e=c(C.map(e=>e.cols));return Number.isFinite(e)?e:1})();if(C.length){let e=new Map;for(let t of C){let n=f[t.index].stack??`\u0000${t.key}`;e.has(n)||e.set(n,e.size)}let t=w*(e.size>1?.78:.62),n=t/e.size,r=new Map;for(let i of C){let a=f[i.index].stack??`\u0000${i.key}`,o=e.get(a)??0;i.barOffset=-t/2+n*(o+.5),i.barHalfWidth=n/2*(e.size>1?.86:1);let s=r.get(a);s||r.set(a,s=new Map);let{x:c,y:l,count:u}=i.cols;i.barBase=new Float64Array(u),i.barTop=new Float64Array(u);for(let e=0;e<u;e++){let t=l[e];if(!Number.isFinite(t)){i.barBase[e]=NaN,i.barTop[e]=NaN;continue}let n=s.get(c[e])??[0,0],r=t>=0?n[0]:n[1];i.barBase[e]=r,i.barTop[e]=r+t,t>=0?n[0]+=t:n[1]+=t,s.set(c[e],n)}}}let T=r.xAxis,E;if(m===`category`)E=[-.5,Math.max(1,h.length)-.5];else{let t=[];for(let e of x)t.push(e.cols.xMin,e.cols.xMax),e.type===`bar`&&t.push(e.cols.xMin-w/2,e.cols.xMax+w/2);if(E=e.ensureSpan(...s(t),m===`time`?[Date.now()-864e5,Date.now()]:[0,1]),S){let e=(E[1]-E[0])*.04;E=[E[0]-e,E[1]+e]}(T?.nice??(S&&m===`linear`))&&m===`linear`&&(E=e.niceDomain(E[0],E[1],T?.tickCount??6))}T?.min!==void 0&&(E[0]=T.min),T?.max!==void 0&&(E[1]=T.max),E=e.ensureSpan(E[0],E[1]);let D=r.yAxis,O=[];for(let e of x)e.type===`bar`&&e.barBase&&e.barTop?O.push(...s(e.barBase),...s(e.barTop)):O.push(e.cols.yMin,e.cols.yMax);(C.length||D?.zero)&&O.push(0);let k=e.ensureSpan(...s(O));if(S){let e=(k[1]-k[0])*.06;k=[k[0]-e,k[1]+e]}(D?.nice??!0)&&(D?.type??`linear`)===`linear`&&(k=e.niceDomain(k[0],k[1],D?.tickCount??5)),C.length&&!D?.zero&&k[0]<0&&s(O)[0]>=0&&(k[0]=0),D?.min!==void 0&&(k[0]=D.min),D?.max!==void 0&&(k[1]=D.max),k=e.ensureSpan(k[0],k[1]);let A=r.interaction===!1?!1:r.interaction===!0||r.interaction===void 0?!0:r.interaction.zoom??!0,j=A===!1?{x:!1,y:!1}:A===!0?{x:!0,y:S}:{x:A.includes(`x`),y:A.includes(`y`)},M=typeof r.tooltip==`object`?r.tooltip:void 0;return{series:b,x:o(T,m,h,!1),y:o(D,D?.type===`time`?`time`:`linear`,[],!0),base:{x:E,y:k},allScatter:S,zoom:j,tooltipMode:M?.mode??(S?`nearest`:`axis`),baseline:Math.min(Math.max(0,k[0]),k[1]),minSpan:{x:m===`category`?1:(E[1]-E[0])*1e-7,y:(k[1]-k[0])*1e-7}}},u=new WeakMap,d=e=>{let t=u.get(e.cols);return t||(t=new r.GridIndex(e.cols.x,e.cols.y,e.cols.count),u.set(e.cols,t)),t};exports.buildModel=l,exports.detectXType=a,exports.gridOf=d;
1
+ const e=require("./data.cjs"),t=require("./color.cjs"),n=require("./scale.cjs"),r=require("./spatial.cjs");var i=e=>{if(typeof e==`object`&&e&&!(`length`in e)){let t=e.x;return t&&t.length?t[0]:void 0}let t=e;for(let e=0;e<Math.min(t.length,8);e++){let n=t[e];if(Array.isArray(n))return n[0];if(n&&typeof n==`object`)return n.x}},a=e=>{for(let t of e){let e=i(t);if(e instanceof Date)return`time`;if(typeof e==`string`)return`category`}return`linear`},o=(e,t,n,r)=>({type:t,reverse:!!e?.reverse,categories:n,title:e?.title,format:e?.format,grid:e?.grid??r,visible:e?.visible??!0,tickCount:e?.tickCount}),s=e=>{let t=1/0,n=-1/0;for(let r=0;r<e.length;r++){let i=e[r];Number.isFinite(i)&&(i<t&&(t=i),i>n&&(n=i))}return[t,n]},c=e=>{let t=1/0;for(let n of e){let e=n.sorted?n.x:Float64Array.from(n.x).sort();for(let r=1;r<n.count;r++){let n=e[r]-e[r-1];n>0&&n<t&&(t=n)}}return t},l=(r,i,l,u,d=null)=>{let f=d??i.resolve??((e,n)=>t.resolveStaticColor(e,{},n)),p=r.series,m=p.map(e=>e.data),h=r.xAxis?.type??a(m),g=h===`category`?[...r.xAxis?.categories??e.collectCategories(m)]:[],_=new Map(g.map((e,t)=>[e,t])),v=e.xResolver(h,e=>_.get(e)??NaN),y=`${h}|${g.join(``)}`,b=new Set,x=p.map((n,r)=>{let a=n.id??`#${r}`;for(;b.has(a);)a+=`'`;b.add(a);let o=u.get(a);(!o||o.data!==n.data||o.resolverKey!==y)&&(o={data:n.data,resolverKey:y,cols:e.normalizeData(n.data,v)},u.set(a,o));let s=n.type??`line`,c=n.color?f(n.color,i.palette[r%i.palette.length]):i.palette[r%i.palette.length],d=o.cols,p=null;if(s===`scatter`&&d.colors){let e=new Map;p=d.colors.map(t=>{if(t===void 0)return;let n=e.get(t);return n||e.set(t,n=f(t,c)),n})}let m=n.id??String(r);return{index:r,key:a,id:m,name:n.name??`Series ${r+1}`,type:s,color:c,colorCss:t.toCss(c),lineWidth:n.lineWidth??2,pointSize:n.pointSize??8,opacity:n.opacity??(s===`area`?.28:s===`scatter`?.78:1),hidden:!!n.hidden||l.has(m),showLabels:!!n.showLabels,cols:d,barOffset:0,barHalfWidth:0,barBase:null,barTop:null,pointColors:p}}),S=x.filter(e=>!e.hidden),C=x.length>0&&x.every(e=>e.type===`scatter`),w=S.filter(e=>e.type===`bar`),T=h===`category`?1:(()=>{let e=c(w.map(e=>e.cols));return Number.isFinite(e)?e:1})();if(w.length){let e=new Map;for(let t of w){let n=p[t.index].stack??`\u0000${t.key}`;e.has(n)||e.set(n,e.size)}let t=T*(e.size>1?.78:.62),n=t/e.size,r=new Map;for(let i of w){let a=p[i.index].stack??`\u0000${i.key}`,o=e.get(a)??0;i.barOffset=-t/2+n*(o+.5),i.barHalfWidth=n/2*(e.size>1?.86:1);let s=r.get(a);s||r.set(a,s=new Map);let{x:c,y:l,count:u}=i.cols;i.barBase=new Float64Array(u),i.barTop=new Float64Array(u);for(let e=0;e<u;e++){let t=l[e];if(!Number.isFinite(t)){i.barBase[e]=NaN,i.barTop[e]=NaN;continue}let n=s.get(c[e])??[0,0],r=t>=0?n[0]:n[1];i.barBase[e]=r,i.barTop[e]=r+t,t>=0?n[0]+=t:n[1]+=t,s.set(c[e],n)}}}let E=r.xAxis,D;if(h===`category`)D=[-.5,Math.max(1,g.length)-.5];else{let e=[];for(let t of S)e.push(t.cols.xMin,t.cols.xMax),t.type===`bar`&&e.push(t.cols.xMin-T/2,t.cols.xMax+T/2);if(D=n.ensureSpan(...s(e),h===`time`?[Date.now()-864e5,Date.now()]:[0,1]),C){let e=(D[1]-D[0])*.04;D=[D[0]-e,D[1]+e]}(E?.nice??(C&&h===`linear`))&&h===`linear`&&(D=n.niceDomain(D[0],D[1],E?.tickCount??6))}E?.min!==void 0&&(D[0]=E.min),E?.max!==void 0&&(D[1]=E.max),D=n.ensureSpan(D[0],D[1]);let O=r.yAxis,k=[];for(let e of S)e.type===`bar`&&e.barBase&&e.barTop?k.push(...s(e.barBase),...s(e.barTop)):k.push(e.cols.yMin,e.cols.yMax);(w.length||O?.zero)&&k.push(0);let A=n.ensureSpan(...s(k));if(C){let e=(A[1]-A[0])*.06;A=[A[0]-e,A[1]+e]}(O?.nice??!0)&&(O?.type??`linear`)===`linear`&&(A=n.niceDomain(A[0],A[1],O?.tickCount??5)),w.length&&!O?.zero&&A[0]<0&&s(k)[0]>=0&&(A[0]=0),O?.min!==void 0&&(A[0]=O.min),O?.max!==void 0&&(A[1]=O.max),A=n.ensureSpan(A[0],A[1]);let j=r.interaction===!1?!1:r.interaction===!0||r.interaction===void 0?!0:r.interaction.zoom??!0,M=j===!1?{x:!1,y:!1}:j===!0?{x:!0,y:C}:{x:j.includes(`x`),y:j.includes(`y`)},N=typeof r.tooltip==`object`?r.tooltip:void 0;return{series:x,x:o(E,h,g,!1),y:o(O,O?.type===`time`?`time`:`linear`,[],!0),base:{x:D,y:A},allScatter:C,zoom:M,tooltipMode:N?.mode??(C?`nearest`:`axis`),baseline:Math.min(Math.max(0,A[0]),A[1]),minSpan:{x:h===`category`?1:(D[1]-D[0])*1e-7,y:(A[1]-A[0])*1e-7}}},u=new WeakMap,d=e=>{let t=u.get(e.cols);return t||(t=new r.GridIndex(e.cols.x,e.cols.y,e.cols.count),u.set(e.cols,t)),t};exports.buildModel=l,exports.detectXType=a,exports.gridOf=d;
2
2
  //# sourceMappingURL=model.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.cjs","names":["collectCategories","xResolver","normalizeData","resolveColor","toCss","ensureSpan","niceDomain","GridIndex","require_scale","require_color","require_data","require_spatial","firstX","data","xs","list","i","item","detectXType","datas","x","axisModel","options","gridDefault","extent","min","max","values","v","smallestStep","step","c","cols","d","buildModel","input","s","xType","categories","categoryMap","resolveX","name","resolverKey","usedKeys","series","key","index","entry","cache","type","color","element","theme","pointColors","resolved","rgba","id","hidden","visible","allScatter","bars","band","slots","stack","group","slotWidth","sums","slot","totals","count","y","t","base","xOpts","xRange","pad","yOpts","yValues","yRange","zoomOption","zoomAxes","tooltip","grids","gridOf","grid"],"sources":["../../../../charts/src/engine/model.ts"],"sourcesContent":["// Options -> chart model: normalized data, colors, bar layout and the full\n// ranges of the axes. Pure (no DOM besides color resolution).\n\nimport { resolveColor, toCss, type Rgba } from \"./color\";\nimport {\n collectCategories,\n normalizeData,\n xResolver,\n type SeriesColumns,\n} from \"./data\";\nimport { ensureSpan, niceDomain } from \"./scale\";\nimport { GridIndex } from \"./spatial\";\nimport type { ChartTheme } from \"./theme\";\nimport type {\n ChartAxisOptions,\n ChartAxisType,\n ChartOptions,\n ChartSeriesData,\n ChartSeriesType,\n} from \"./types\";\nimport type { Range } from \"./viewport\";\n\nexport interface AxisModel {\n type: ChartAxisType;\n reverse: boolean;\n categories: string[];\n title?: string;\n format?: (value: number) => string;\n grid: boolean;\n visible: boolean;\n tickCount?: number;\n}\n\nexport interface SeriesModel {\n index: number;\n /** Key of the GPU resources and of the data cache */\n key: string;\n id: string;\n name: string;\n type: ChartSeriesType;\n color: Rgba;\n colorCss: string;\n lineWidth: number;\n pointSize: number;\n opacity: number;\n hidden: boolean;\n showLabels: boolean;\n cols: SeriesColumns;\n /** Bars: x offset of the series inside a group and half of the bar width */\n barOffset: number;\n barHalfWidth: number;\n /** Bars: bottom / top of every bar (stacks included) */\n barBase: Float64Array | null;\n barTop: Float64Array | null;\n /** Scatter: resolved per-point colors */\n pointColors: (Rgba | undefined)[] | null;\n}\n\nexport interface ChartModel {\n series: SeriesModel[];\n x: AxisModel;\n y: AxisModel;\n /** Full ranges (zoomed out) */\n base: { x: Range; y: Range };\n allScatter: boolean;\n zoom: { x: boolean; y: boolean };\n tooltipMode: \"nearest\" | \"axis\";\n /** Y value the areas are filled to */\n baseline: number;\n /** Smallest zoomed spans */\n minSpan: { x: number; y: number };\n}\n\nexport interface DataCacheEntry {\n data: ChartSeriesData;\n resolverKey: string;\n cols: SeriesColumns;\n}\n\nexport type DataCache = Map<string, DataCacheEntry>;\n\nconst firstX = (data: ChartSeriesData): unknown => {\n if (typeof data === \"object\" && data !== null && !(\"length\" in data)) {\n const xs = (data as { x?: ArrayLike<unknown> }).x;\n return xs && xs.length ? xs[0] : undefined;\n }\n const list = data as ArrayLike<unknown>;\n for (let i = 0; i < Math.min(list.length, 8); i++) {\n const item = list[i];\n if (Array.isArray(item)) return item[0];\n if (item && typeof item === \"object\") return (item as { x?: unknown }).x;\n }\n return undefined;\n};\n\n/** Axis type when not given: dates -> time, strings -> category */\nexport const detectXType = (\n datas: readonly ChartSeriesData[],\n): ChartAxisType => {\n for (const data of datas) {\n const x = firstX(data);\n if (x instanceof Date) return \"time\";\n if (typeof x === \"string\") return \"category\";\n }\n return \"linear\";\n};\n\nconst axisModel = (\n options: ChartAxisOptions | undefined,\n type: ChartAxisType,\n categories: string[],\n gridDefault: boolean,\n): AxisModel => ({\n type,\n reverse: !!options?.reverse,\n categories,\n title: options?.title,\n format: options?.format,\n grid: options?.grid ?? gridDefault,\n visible: options?.visible ?? true,\n tickCount: options?.tickCount,\n});\n\nconst extent = (values: ArrayLike<number>): Range => {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n return [min, max];\n};\n\n/** Smallest positive gap between consecutive x values (bar width on numeric axes) */\nconst smallestStep = (cols: SeriesColumns[]): number => {\n let step = Infinity;\n for (const c of cols) {\n const xs = c.sorted ? c.x : Float64Array.from(c.x).sort();\n for (let i = 1; i < c.count; i++) {\n const d = xs[i] - xs[i - 1];\n if (d > 0 && d < step) step = d;\n }\n }\n return step;\n};\n\nexport const buildModel = (\n options: ChartOptions,\n theme: ChartTheme,\n hidden: ReadonlySet<string>,\n cache: DataCache,\n element: Element | null,\n): ChartModel => {\n const input = options.series;\n const datas = input.map((s) => s.data);\n const xType = options.xAxis?.type ?? detectXType(datas);\n const categories =\n xType === \"category\"\n ? [...(options.xAxis?.categories ?? collectCategories(datas))]\n : [];\n const categoryMap = new Map(categories.map((c, i) => [c, i]));\n const resolveX = xResolver(xType, (name) => categoryMap.get(name) ?? NaN);\n const resolverKey = `${xType}|${categories.join(\"\\u0001\")}`;\n\n const usedKeys = new Set<string>();\n const series: SeriesModel[] = input.map((s, index) => {\n let key = s.id ?? `#${index}`;\n while (usedKeys.has(key)) key += \"'\";\n usedKeys.add(key);\n let entry = cache.get(key);\n if (!entry || entry.data !== s.data || entry.resolverKey !== resolverKey) {\n entry = {\n data: s.data,\n resolverKey,\n cols: normalizeData(s.data, resolveX),\n };\n cache.set(key, entry);\n }\n const type = s.type ?? \"line\";\n const color = s.color\n ? resolveColor(\n s.color,\n element,\n theme.palette[index % theme.palette.length],\n )\n : theme.palette[index % theme.palette.length];\n const cols = entry.cols;\n let pointColors: (Rgba | undefined)[] | null = null;\n if (type === \"scatter\" && cols.colors) {\n const resolved = new Map<string, Rgba>();\n pointColors = cols.colors.map((c) => {\n if (c === undefined) return undefined;\n let rgba = resolved.get(c);\n if (!rgba) resolved.set(c, (rgba = resolveColor(c, element, color)));\n return rgba;\n });\n }\n const id = s.id ?? String(index);\n return {\n index,\n key,\n id,\n name: s.name ?? `Series ${index + 1}`,\n type,\n color,\n colorCss: toCss(color),\n lineWidth: s.lineWidth ?? 2,\n pointSize: s.pointSize ?? 8,\n opacity:\n s.opacity ?? (type === \"area\" ? 0.28 : type === \"scatter\" ? 0.78 : 1),\n hidden: !!s.hidden || hidden.has(id),\n showLabels: !!s.showLabels,\n cols,\n barOffset: 0,\n barHalfWidth: 0,\n barBase: null,\n barTop: null,\n pointColors,\n };\n });\n\n const visible = series.filter((s) => !s.hidden);\n const allScatter =\n series.length > 0 && series.every((s) => s.type === \"scatter\");\n\n // Bars: groups (one slot per stack) and stacking\n const bars = visible.filter((s) => s.type === \"bar\");\n const band =\n xType === \"category\"\n ? 1\n : (() => {\n const step = smallestStep(bars.map((s) => s.cols));\n return Number.isFinite(step) ? step : 1;\n })();\n if (bars.length) {\n const slots = new Map<string, number>();\n for (const s of bars) {\n const stack = input[s.index].stack ?? `\\u0000${s.key}`;\n if (!slots.has(stack)) slots.set(stack, slots.size);\n }\n const group = band * (slots.size > 1 ? 0.78 : 0.62);\n const slotWidth = group / slots.size;\n const sums = new Map<string, Map<number, [number, number]>>();\n for (const s of bars) {\n const stack = input[s.index].stack ?? `\\u0000${s.key}`;\n const slot = slots.get(stack) ?? 0;\n s.barOffset = -group / 2 + slotWidth * (slot + 0.5);\n s.barHalfWidth = (slotWidth / 2) * (slots.size > 1 ? 0.86 : 1);\n let totals = sums.get(stack);\n if (!totals) sums.set(stack, (totals = new Map()));\n const { x, y, count } = s.cols;\n s.barBase = new Float64Array(count);\n s.barTop = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n const v = y[i];\n if (!Number.isFinite(v)) {\n s.barBase[i] = NaN;\n s.barTop[i] = NaN;\n continue;\n }\n const t = totals.get(x[i]) ?? [0, 0];\n const base = v >= 0 ? t[0] : t[1];\n s.barBase[i] = base;\n s.barTop[i] = base + v;\n if (v >= 0) t[0] += v;\n else t[1] += v;\n totals.set(x[i], t);\n }\n }\n }\n\n // X range\n const xOpts = options.xAxis;\n let xRange: Range;\n if (xType === \"category\") {\n xRange = [-0.5, Math.max(1, categories.length) - 0.5];\n } else {\n const values: number[] = [];\n for (const s of visible) {\n values.push(s.cols.xMin, s.cols.xMax);\n if (s.type === \"bar\") {\n values.push(s.cols.xMin - band / 2, s.cols.xMax + band / 2);\n }\n }\n xRange = ensureSpan(\n ...extent(values),\n xType === \"time\" ? [Date.now() - 86400000, Date.now()] : [0, 1],\n );\n if (allScatter) {\n const pad = (xRange[1] - xRange[0]) * 0.04;\n xRange = [xRange[0] - pad, xRange[1] + pad];\n }\n const nice = xOpts?.nice ?? (allScatter && xType === \"linear\");\n if (nice && xType === \"linear\") {\n xRange = niceDomain(xRange[0], xRange[1], xOpts?.tickCount ?? 6);\n }\n }\n if (xOpts?.min !== undefined) xRange[0] = xOpts.min;\n if (xOpts?.max !== undefined) xRange[1] = xOpts.max;\n xRange = ensureSpan(xRange[0], xRange[1]);\n\n // Y range\n const yOpts = options.yAxis;\n const yValues: number[] = [];\n for (const s of visible) {\n if (s.type === \"bar\" && s.barBase && s.barTop) {\n yValues.push(...extent(s.barBase), ...extent(s.barTop));\n } else {\n yValues.push(s.cols.yMin, s.cols.yMax);\n }\n }\n if (bars.length || yOpts?.zero) yValues.push(0);\n let yRange = ensureSpan(...extent(yValues));\n if (allScatter) {\n const pad = (yRange[1] - yRange[0]) * 0.06;\n yRange = [yRange[0] - pad, yRange[1] + pad];\n }\n if ((yOpts?.nice ?? true) && (yOpts?.type ?? \"linear\") === \"linear\") {\n yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);\n }\n if (bars.length && !yOpts?.zero) {\n // bars start at zero: no padding below / above it\n if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;\n }\n if (yOpts?.min !== undefined) yRange[0] = yOpts.min;\n if (yOpts?.max !== undefined) yRange[1] = yOpts.max;\n yRange = ensureSpan(yRange[0], yRange[1]);\n\n const zoomOption =\n options.interaction === false\n ? false\n : options.interaction === true || options.interaction === undefined\n ? true\n : (options.interaction.zoom ?? true);\n const zoomAxes =\n zoomOption === false\n ? { x: false, y: false }\n : zoomOption === true\n ? { x: true, y: allScatter }\n : { x: zoomOption.includes(\"x\"), y: zoomOption.includes(\"y\") };\n\n const tooltip =\n typeof options.tooltip === \"object\" ? options.tooltip : undefined;\n\n return {\n series,\n x: axisModel(xOpts, xType, categories, false),\n y: axisModel(yOpts, yOpts?.type === \"time\" ? \"time\" : \"linear\", [], true),\n base: { x: xRange, y: yRange },\n allScatter,\n zoom: zoomAxes,\n tooltipMode: tooltip?.mode ?? (allScatter ? \"nearest\" : \"axis\"),\n baseline: Math.min(Math.max(0, yRange[0]), yRange[1]),\n minSpan: {\n x: xType === \"category\" ? 1 : (xRange[1] - xRange[0]) * 1e-7,\n y: (yRange[1] - yRange[0]) * 1e-7,\n },\n };\n};\n\nconst grids = new WeakMap<SeriesColumns, GridIndex>();\n\n/** Spatial index of a scatter series, built on first use and kept with its data */\nexport const gridOf = (s: SeriesModel): GridIndex => {\n let grid = grids.get(s.cols);\n if (!grid) {\n grid = new GridIndex(s.cols.x, s.cols.y, s.cols.count);\n grids.set(s.cols, grid);\n }\n return grid;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"model.cjs","names":["resolveStaticColor","collectCategories","xResolver","normalizeData","toCss","ensureSpan","niceDomain","GridIndex","require_data","require_color","require_scale","require_spatial","firstX","data","xs","list","i","item","detectXType","datas","x","axisModel","options","gridDefault","extent","min","max","values","v","smallestStep","step","c","cols","d","buildModel","resolve","resolver","theme","value","fallback","input","s","xType","categories","categoryMap","resolveX","name","resolverKey","usedKeys","series","key","index","entry","cache","type","color","pointColors","resolved","rgba","id","hidden","visible","allScatter","bars","band","slots","stack","group","slotWidth","sums","slot","totals","count","y","t","base","xOpts","xRange","pad","yOpts","yValues","yRange","zoomOption","zoomAxes","tooltip","grids","gridOf","grid"],"sources":["../../../../charts/src/engine/model.ts"],"sourcesContent":["// Options -> chart model: normalized data, colors, bar layout and the full\n// ranges of the axes. Pure (colors go through the theme's resolver).\n\nimport {\n resolveStaticColor,\n toCss,\n type ColorResolver,\n type Rgba,\n} from \"./color\";\nimport {\n collectCategories,\n normalizeData,\n xResolver,\n type SeriesColumns,\n} from \"./data\";\nimport { ensureSpan, niceDomain } from \"./scale\";\nimport { GridIndex } from \"./spatial\";\nimport type { ChartTheme } from \"./theme\";\nimport type {\n ChartAxisOptions,\n ChartAxisType,\n ChartOptions,\n ChartSeriesData,\n ChartSeriesType,\n} from \"./types\";\nimport type { Range } from \"./viewport\";\n\nexport interface AxisModel {\n type: ChartAxisType;\n reverse: boolean;\n categories: string[];\n title?: string;\n format?: (value: number) => string;\n grid: boolean;\n visible: boolean;\n tickCount?: number;\n}\n\nexport interface SeriesModel {\n index: number;\n /** Key of the GPU resources and of the data cache */\n key: string;\n id: string;\n name: string;\n type: ChartSeriesType;\n color: Rgba;\n colorCss: string;\n lineWidth: number;\n pointSize: number;\n opacity: number;\n hidden: boolean;\n showLabels: boolean;\n cols: SeriesColumns;\n /** Bars: x offset of the series inside a group and half of the bar width */\n barOffset: number;\n barHalfWidth: number;\n /** Bars: bottom / top of every bar (stacks included) */\n barBase: Float64Array | null;\n barTop: Float64Array | null;\n /** Scatter: resolved per-point colors */\n pointColors: (Rgba | undefined)[] | null;\n}\n\nexport interface ChartModel {\n series: SeriesModel[];\n x: AxisModel;\n y: AxisModel;\n /** Full ranges (zoomed out) */\n base: { x: Range; y: Range };\n allScatter: boolean;\n zoom: { x: boolean; y: boolean };\n tooltipMode: \"nearest\" | \"axis\";\n /** Y value the areas are filled to */\n baseline: number;\n /** Smallest zoomed spans */\n minSpan: { x: number; y: number };\n}\n\nexport interface DataCacheEntry {\n data: ChartSeriesData;\n resolverKey: string;\n cols: SeriesColumns;\n}\n\nexport type DataCache = Map<string, DataCacheEntry>;\n\nconst firstX = (data: ChartSeriesData): unknown => {\n if (typeof data === \"object\" && data !== null && !(\"length\" in data)) {\n const xs = (data as { x?: ArrayLike<unknown> }).x;\n return xs && xs.length ? xs[0] : undefined;\n }\n const list = data as ArrayLike<unknown>;\n for (let i = 0; i < Math.min(list.length, 8); i++) {\n const item = list[i];\n if (Array.isArray(item)) return item[0];\n if (item && typeof item === \"object\") return (item as { x?: unknown }).x;\n }\n return undefined;\n};\n\n/** Axis type when not given: dates -> time, strings -> category */\nexport const detectXType = (\n datas: readonly ChartSeriesData[],\n): ChartAxisType => {\n for (const data of datas) {\n const x = firstX(data);\n if (x instanceof Date) return \"time\";\n if (typeof x === \"string\") return \"category\";\n }\n return \"linear\";\n};\n\nconst axisModel = (\n options: ChartAxisOptions | undefined,\n type: ChartAxisType,\n categories: string[],\n gridDefault: boolean,\n): AxisModel => ({\n type,\n reverse: !!options?.reverse,\n categories,\n title: options?.title,\n format: options?.format,\n grid: options?.grid ?? gridDefault,\n visible: options?.visible ?? true,\n tickCount: options?.tickCount,\n});\n\nconst extent = (values: ArrayLike<number>): Range => {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n return [min, max];\n};\n\n/** Smallest positive gap between consecutive x values (bar width on numeric axes) */\nconst smallestStep = (cols: SeriesColumns[]): number => {\n let step = Infinity;\n for (const c of cols) {\n const xs = c.sorted ? c.x : Float64Array.from(c.x).sort();\n for (let i = 1; i < c.count; i++) {\n const d = xs[i] - xs[i - 1];\n if (d > 0 && d < step) step = d;\n }\n }\n return step;\n};\n\nexport const buildModel = (\n options: ChartOptions,\n theme: ChartTheme,\n hidden: ReadonlySet<string>,\n cache: DataCache,\n resolver: ColorResolver | null = null,\n): ChartModel => {\n const resolve: ColorResolver =\n resolver ??\n theme.resolve ??\n ((value, fallback) => resolveStaticColor(value, {}, fallback));\n const input = options.series;\n const datas = input.map((s) => s.data);\n const xType = options.xAxis?.type ?? detectXType(datas);\n const categories =\n xType === \"category\"\n ? [...(options.xAxis?.categories ?? collectCategories(datas))]\n : [];\n const categoryMap = new Map(categories.map((c, i) => [c, i]));\n const resolveX = xResolver(xType, (name) => categoryMap.get(name) ?? NaN);\n const resolverKey = `${xType}|${categories.join(\"\\u0001\")}`;\n\n const usedKeys = new Set<string>();\n const series: SeriesModel[] = input.map((s, index) => {\n let key = s.id ?? `#${index}`;\n while (usedKeys.has(key)) key += \"'\";\n usedKeys.add(key);\n let entry = cache.get(key);\n if (!entry || entry.data !== s.data || entry.resolverKey !== resolverKey) {\n entry = {\n data: s.data,\n resolverKey,\n cols: normalizeData(s.data, resolveX),\n };\n cache.set(key, entry);\n }\n const type = s.type ?? \"line\";\n const color = s.color\n ? resolve(s.color, theme.palette[index % theme.palette.length])\n : theme.palette[index % theme.palette.length];\n const cols = entry.cols;\n let pointColors: (Rgba | undefined)[] | null = null;\n if (type === \"scatter\" && cols.colors) {\n const resolved = new Map<string, Rgba>();\n pointColors = cols.colors.map((c) => {\n if (c === undefined) return undefined;\n let rgba = resolved.get(c);\n if (!rgba) resolved.set(c, (rgba = resolve(c, color)));\n return rgba;\n });\n }\n const id = s.id ?? String(index);\n return {\n index,\n key,\n id,\n name: s.name ?? `Series ${index + 1}`,\n type,\n color,\n colorCss: toCss(color),\n lineWidth: s.lineWidth ?? 2,\n pointSize: s.pointSize ?? 8,\n opacity:\n s.opacity ?? (type === \"area\" ? 0.28 : type === \"scatter\" ? 0.78 : 1),\n hidden: !!s.hidden || hidden.has(id),\n showLabels: !!s.showLabels,\n cols,\n barOffset: 0,\n barHalfWidth: 0,\n barBase: null,\n barTop: null,\n pointColors,\n };\n });\n\n const visible = series.filter((s) => !s.hidden);\n const allScatter =\n series.length > 0 && series.every((s) => s.type === \"scatter\");\n\n // Bars: groups (one slot per stack) and stacking\n const bars = visible.filter((s) => s.type === \"bar\");\n const band =\n xType === \"category\"\n ? 1\n : (() => {\n const step = smallestStep(bars.map((s) => s.cols));\n return Number.isFinite(step) ? step : 1;\n })();\n if (bars.length) {\n const slots = new Map<string, number>();\n for (const s of bars) {\n const stack = input[s.index].stack ?? `\\u0000${s.key}`;\n if (!slots.has(stack)) slots.set(stack, slots.size);\n }\n const group = band * (slots.size > 1 ? 0.78 : 0.62);\n const slotWidth = group / slots.size;\n const sums = new Map<string, Map<number, [number, number]>>();\n for (const s of bars) {\n const stack = input[s.index].stack ?? `\\u0000${s.key}`;\n const slot = slots.get(stack) ?? 0;\n s.barOffset = -group / 2 + slotWidth * (slot + 0.5);\n s.barHalfWidth = (slotWidth / 2) * (slots.size > 1 ? 0.86 : 1);\n let totals = sums.get(stack);\n if (!totals) sums.set(stack, (totals = new Map()));\n const { x, y, count } = s.cols;\n s.barBase = new Float64Array(count);\n s.barTop = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n const v = y[i];\n if (!Number.isFinite(v)) {\n s.barBase[i] = NaN;\n s.barTop[i] = NaN;\n continue;\n }\n const t = totals.get(x[i]) ?? [0, 0];\n const base = v >= 0 ? t[0] : t[1];\n s.barBase[i] = base;\n s.barTop[i] = base + v;\n if (v >= 0) t[0] += v;\n else t[1] += v;\n totals.set(x[i], t);\n }\n }\n }\n\n // X range\n const xOpts = options.xAxis;\n let xRange: Range;\n if (xType === \"category\") {\n xRange = [-0.5, Math.max(1, categories.length) - 0.5];\n } else {\n const values: number[] = [];\n for (const s of visible) {\n values.push(s.cols.xMin, s.cols.xMax);\n if (s.type === \"bar\") {\n values.push(s.cols.xMin - band / 2, s.cols.xMax + band / 2);\n }\n }\n xRange = ensureSpan(\n ...extent(values),\n xType === \"time\" ? [Date.now() - 86400000, Date.now()] : [0, 1],\n );\n if (allScatter) {\n const pad = (xRange[1] - xRange[0]) * 0.04;\n xRange = [xRange[0] - pad, xRange[1] + pad];\n }\n const nice = xOpts?.nice ?? (allScatter && xType === \"linear\");\n if (nice && xType === \"linear\") {\n xRange = niceDomain(xRange[0], xRange[1], xOpts?.tickCount ?? 6);\n }\n }\n if (xOpts?.min !== undefined) xRange[0] = xOpts.min;\n if (xOpts?.max !== undefined) xRange[1] = xOpts.max;\n xRange = ensureSpan(xRange[0], xRange[1]);\n\n // Y range\n const yOpts = options.yAxis;\n const yValues: number[] = [];\n for (const s of visible) {\n if (s.type === \"bar\" && s.barBase && s.barTop) {\n yValues.push(...extent(s.barBase), ...extent(s.barTop));\n } else {\n yValues.push(s.cols.yMin, s.cols.yMax);\n }\n }\n if (bars.length || yOpts?.zero) yValues.push(0);\n let yRange = ensureSpan(...extent(yValues));\n if (allScatter) {\n const pad = (yRange[1] - yRange[0]) * 0.06;\n yRange = [yRange[0] - pad, yRange[1] + pad];\n }\n if ((yOpts?.nice ?? true) && (yOpts?.type ?? \"linear\") === \"linear\") {\n yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);\n }\n if (bars.length && !yOpts?.zero) {\n // bars start at zero: no padding below / above it\n if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;\n }\n if (yOpts?.min !== undefined) yRange[0] = yOpts.min;\n if (yOpts?.max !== undefined) yRange[1] = yOpts.max;\n yRange = ensureSpan(yRange[0], yRange[1]);\n\n const zoomOption =\n options.interaction === false\n ? false\n : options.interaction === true || options.interaction === undefined\n ? true\n : (options.interaction.zoom ?? true);\n const zoomAxes =\n zoomOption === false\n ? { x: false, y: false }\n : zoomOption === true\n ? { x: true, y: allScatter }\n : { x: zoomOption.includes(\"x\"), y: zoomOption.includes(\"y\") };\n\n const tooltip =\n typeof options.tooltip === \"object\" ? options.tooltip : undefined;\n\n return {\n series,\n x: axisModel(xOpts, xType, categories, false),\n y: axisModel(yOpts, yOpts?.type === \"time\" ? \"time\" : \"linear\", [], true),\n base: { x: xRange, y: yRange },\n allScatter,\n zoom: zoomAxes,\n tooltipMode: tooltip?.mode ?? (allScatter ? \"nearest\" : \"axis\"),\n baseline: Math.min(Math.max(0, yRange[0]), yRange[1]),\n minSpan: {\n x: xType === \"category\" ? 1 : (xRange[1] - xRange[0]) * 1e-7,\n y: (yRange[1] - yRange[0]) * 1e-7,\n },\n };\n};\n\nconst grids = new WeakMap<SeriesColumns, GridIndex>();\n\n/** Spatial index of a scatter series, built on first use and kept with its data */\nexport const gridOf = (s: SeriesModel): GridIndex => {\n let grid = grids.get(s.cols);\n if (!grid) {\n grid = new GridIndex(s.cols.x, s.cols.y, s.cols.count);\n grids.set(s.cols, grid);\n }\n return grid;\n};\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Rgba } from './color.cjs';
1
+ import { ColorResolver, Rgba } from './color.cjs';
2
2
  import { SeriesColumns } from './data.cjs';
3
3
  import { GridIndex } from './spatial.cjs';
4
4
  import { ChartTheme } from './theme.cjs';
@@ -69,6 +69,6 @@ export interface DataCacheEntry {
69
69
  export type DataCache = Map<string, DataCacheEntry>;
70
70
  /** Axis type when not given: dates -> time, strings -> category */
71
71
  export declare const detectXType: (datas: readonly ChartSeriesData[]) => ChartAxisType;
72
- export declare const buildModel: (options: ChartOptions, theme: ChartTheme, hidden: ReadonlySet<string>, cache: DataCache, element: Element | null) => ChartModel;
72
+ export declare const buildModel: (options: ChartOptions, theme: ChartTheme, hidden: ReadonlySet<string>, cache: DataCache, resolver?: ColorResolver | null) => ChartModel;
73
73
  /** Spatial index of a scatter series, built on first use and kept with its data */
74
74
  export declare const gridOf: (s: SeriesModel) => GridIndex;
@@ -1,4 +1,4 @@
1
- import { Rgba } from './color.js';
1
+ import { ColorResolver, Rgba } from './color.js';
2
2
  import { SeriesColumns } from './data.js';
3
3
  import { GridIndex } from './spatial.js';
4
4
  import { ChartTheme } from './theme.js';
@@ -69,6 +69,6 @@ export interface DataCacheEntry {
69
69
  export type DataCache = Map<string, DataCacheEntry>;
70
70
  /** Axis type when not given: dates -> time, strings -> category */
71
71
  export declare const detectXType: (datas: readonly ChartSeriesData[]) => ChartAxisType;
72
- export declare const buildModel: (options: ChartOptions, theme: ChartTheme, hidden: ReadonlySet<string>, cache: DataCache, element: Element | null) => ChartModel;
72
+ export declare const buildModel: (options: ChartOptions, theme: ChartTheme, hidden: ReadonlySet<string>, cache: DataCache, resolver?: ColorResolver | null) => ChartModel;
73
73
  /** Spatial index of a scatter series, built on first use and kept with its data */
74
74
  export declare const gridOf: (s: SeriesModel) => GridIndex;
@@ -1,6 +1,6 @@
1
- import { ensureSpan as e, niceDomain as t } from "./scale.js";
2
- import { resolveColor as n, toCss as r } from "./color.js";
3
- import { collectCategories as i, normalizeData as a, xResolver as o } from "./data.js";
1
+ import { collectCategories as e, normalizeData as t, xResolver as n } from "./data.js";
2
+ import { resolveStaticColor as r, toCss as i } from "./color.js";
3
+ import { ensureSpan as a, niceDomain as o } from "./scale.js";
4
4
  import { GridIndex as s } from "./spatial.js";
5
5
  //#region src/engine/model.ts
6
6
  var c = (e) => {
@@ -47,60 +47,60 @@ var c = (e) => {
47
47
  }
48
48
  }
49
49
  return t;
50
- }, p = (s, c, p, m, h) => {
51
- let g = s.series, _ = g.map((e) => e.data), v = s.xAxis?.type ?? l(_), y = v === "category" ? [...s.xAxis?.categories ?? i(_)] : [], b = new Map(y.map((e, t) => [e, t])), x = o(v, (e) => b.get(e) ?? NaN), S = `${v}|${y.join("")}`, C = /* @__PURE__ */ new Set(), w = g.map((e, t) => {
52
- let i = e.id ?? `#${t}`;
53
- for (; C.has(i);) i += "'";
54
- C.add(i);
55
- let o = m.get(i);
56
- (!o || o.data !== e.data || o.resolverKey !== S) && (o = {
50
+ }, p = (s, c, p, m, h = null) => {
51
+ let g = h ?? c.resolve ?? ((e, t) => r(e, {}, t)), _ = s.series, v = _.map((e) => e.data), y = s.xAxis?.type ?? l(v), b = y === "category" ? [...s.xAxis?.categories ?? e(v)] : [], x = new Map(b.map((e, t) => [e, t])), S = n(y, (e) => x.get(e) ?? NaN), C = `${y}|${b.join("")}`, w = /* @__PURE__ */ new Set(), T = _.map((e, n) => {
52
+ let r = e.id ?? `#${n}`;
53
+ for (; w.has(r);) r += "'";
54
+ w.add(r);
55
+ let a = m.get(r);
56
+ (!a || a.data !== e.data || a.resolverKey !== C) && (a = {
57
57
  data: e.data,
58
- resolverKey: S,
59
- cols: a(e.data, x)
60
- }, m.set(i, o));
61
- let s = e.type ?? "line", l = e.color ? n(e.color, h, c.palette[t % c.palette.length]) : c.palette[t % c.palette.length], u = o.cols, d = null;
62
- if (s === "scatter" && u.colors) {
58
+ resolverKey: C,
59
+ cols: t(e.data, S)
60
+ }, m.set(r, a));
61
+ let o = e.type ?? "line", s = e.color ? g(e.color, c.palette[n % c.palette.length]) : c.palette[n % c.palette.length], l = a.cols, u = null;
62
+ if (o === "scatter" && l.colors) {
63
63
  let e = /* @__PURE__ */ new Map();
64
- d = u.colors.map((t) => {
64
+ u = l.colors.map((t) => {
65
65
  if (t === void 0) return;
66
- let r = e.get(t);
67
- return r || e.set(t, r = n(t, h, l)), r;
66
+ let n = e.get(t);
67
+ return n || e.set(t, n = g(t, s)), n;
68
68
  });
69
69
  }
70
- let f = e.id ?? String(t);
70
+ let d = e.id ?? String(n);
71
71
  return {
72
- index: t,
73
- key: i,
74
- id: f,
75
- name: e.name ?? `Series ${t + 1}`,
76
- type: s,
77
- color: l,
78
- colorCss: r(l),
72
+ index: n,
73
+ key: r,
74
+ id: d,
75
+ name: e.name ?? `Series ${n + 1}`,
76
+ type: o,
77
+ color: s,
78
+ colorCss: i(s),
79
79
  lineWidth: e.lineWidth ?? 2,
80
80
  pointSize: e.pointSize ?? 8,
81
- opacity: e.opacity ?? (s === "area" ? .28 : s === "scatter" ? .78 : 1),
82
- hidden: !!e.hidden || p.has(f),
81
+ opacity: e.opacity ?? (o === "area" ? .28 : o === "scatter" ? .78 : 1),
82
+ hidden: !!e.hidden || p.has(d),
83
83
  showLabels: !!e.showLabels,
84
- cols: u,
84
+ cols: l,
85
85
  barOffset: 0,
86
86
  barHalfWidth: 0,
87
87
  barBase: null,
88
88
  barTop: null,
89
- pointColors: d
89
+ pointColors: u
90
90
  };
91
- }), T = w.filter((e) => !e.hidden), E = w.length > 0 && w.every((e) => e.type === "scatter"), D = T.filter((e) => e.type === "bar"), O = v === "category" ? 1 : (() => {
92
- let e = f(D.map((e) => e.cols));
91
+ }), E = T.filter((e) => !e.hidden), D = T.length > 0 && T.every((e) => e.type === "scatter"), O = E.filter((e) => e.type === "bar"), k = y === "category" ? 1 : (() => {
92
+ let e = f(O.map((e) => e.cols));
93
93
  return Number.isFinite(e) ? e : 1;
94
94
  })();
95
- if (D.length) {
95
+ if (O.length) {
96
96
  let e = /* @__PURE__ */ new Map();
97
- for (let t of D) {
98
- let n = g[t.index].stack ?? `\u0000${t.key}`;
97
+ for (let t of O) {
98
+ let n = _[t.index].stack ?? `\u0000${t.key}`;
99
99
  e.has(n) || e.set(n, e.size);
100
100
  }
101
- let t = O * (e.size > 1 ? .78 : .62), n = t / e.size, r = /* @__PURE__ */ new Map();
102
- for (let i of D) {
103
- let a = g[i.index].stack ?? `\u0000${i.key}`, o = e.get(a) ?? 0;
101
+ let t = k * (e.size > 1 ? .78 : .62), n = t / e.size, r = /* @__PURE__ */ new Map();
102
+ for (let i of O) {
103
+ let a = _[i.index].stack ?? `\u0000${i.key}`, o = e.get(a) ?? 0;
104
104
  i.barOffset = -t / 2 + n * (o + .5), i.barHalfWidth = n / 2 * (e.size > 1 ? .86 : 1);
105
105
  let s = r.get(a);
106
106
  s || r.set(a, s = /* @__PURE__ */ new Map());
@@ -117,52 +117,52 @@ var c = (e) => {
117
117
  }
118
118
  }
119
119
  }
120
- let k = s.xAxis, A;
121
- if (v === "category") A = [-.5, Math.max(1, y.length) - .5];
120
+ let A = s.xAxis, j;
121
+ if (y === "category") j = [-.5, Math.max(1, b.length) - .5];
122
122
  else {
123
- let n = [];
124
- for (let e of T) n.push(e.cols.xMin, e.cols.xMax), e.type === "bar" && n.push(e.cols.xMin - O / 2, e.cols.xMax + O / 2);
125
- if (A = e(...d(n), v === "time" ? [Date.now() - 864e5, Date.now()] : [0, 1]), E) {
126
- let e = (A[1] - A[0]) * .04;
127
- A = [A[0] - e, A[1] + e];
123
+ let e = [];
124
+ for (let t of E) e.push(t.cols.xMin, t.cols.xMax), t.type === "bar" && e.push(t.cols.xMin - k / 2, t.cols.xMax + k / 2);
125
+ if (j = a(...d(e), y === "time" ? [Date.now() - 864e5, Date.now()] : [0, 1]), D) {
126
+ let e = (j[1] - j[0]) * .04;
127
+ j = [j[0] - e, j[1] + e];
128
128
  }
129
- (k?.nice ?? (E && v === "linear")) && v === "linear" && (A = t(A[0], A[1], k?.tickCount ?? 6));
129
+ (A?.nice ?? (D && y === "linear")) && y === "linear" && (j = o(j[0], j[1], A?.tickCount ?? 6));
130
130
  }
131
- k?.min !== void 0 && (A[0] = k.min), k?.max !== void 0 && (A[1] = k.max), A = e(A[0], A[1]);
132
- let j = s.yAxis, M = [];
133
- for (let e of T) e.type === "bar" && e.barBase && e.barTop ? M.push(...d(e.barBase), ...d(e.barTop)) : M.push(e.cols.yMin, e.cols.yMax);
134
- (D.length || j?.zero) && M.push(0);
135
- let N = e(...d(M));
136
- if (E) {
137
- let e = (N[1] - N[0]) * .06;
138
- N = [N[0] - e, N[1] + e];
131
+ A?.min !== void 0 && (j[0] = A.min), A?.max !== void 0 && (j[1] = A.max), j = a(j[0], j[1]);
132
+ let M = s.yAxis, N = [];
133
+ for (let e of E) e.type === "bar" && e.barBase && e.barTop ? N.push(...d(e.barBase), ...d(e.barTop)) : N.push(e.cols.yMin, e.cols.yMax);
134
+ (O.length || M?.zero) && N.push(0);
135
+ let P = a(...d(N));
136
+ if (D) {
137
+ let e = (P[1] - P[0]) * .06;
138
+ P = [P[0] - e, P[1] + e];
139
139
  }
140
- (j?.nice ?? !0) && (j?.type ?? "linear") === "linear" && (N = t(N[0], N[1], j?.tickCount ?? 5)), D.length && !j?.zero && N[0] < 0 && d(M)[0] >= 0 && (N[0] = 0), j?.min !== void 0 && (N[0] = j.min), j?.max !== void 0 && (N[1] = j.max), N = e(N[0], N[1]);
141
- let P = s.interaction === !1 ? !1 : s.interaction === !0 || s.interaction === void 0 ? !0 : s.interaction.zoom ?? !0, F = P === !1 ? {
140
+ (M?.nice ?? !0) && (M?.type ?? "linear") === "linear" && (P = o(P[0], P[1], M?.tickCount ?? 5)), O.length && !M?.zero && P[0] < 0 && d(N)[0] >= 0 && (P[0] = 0), M?.min !== void 0 && (P[0] = M.min), M?.max !== void 0 && (P[1] = M.max), P = a(P[0], P[1]);
141
+ let F = s.interaction === !1 ? !1 : s.interaction === !0 || s.interaction === void 0 ? !0 : s.interaction.zoom ?? !0, I = F === !1 ? {
142
142
  x: !1,
143
143
  y: !1
144
- } : P === !0 ? {
144
+ } : F === !0 ? {
145
145
  x: !0,
146
- y: E
146
+ y: D
147
147
  } : {
148
- x: P.includes("x"),
149
- y: P.includes("y")
150
- }, I = typeof s.tooltip == "object" ? s.tooltip : void 0;
148
+ x: F.includes("x"),
149
+ y: F.includes("y")
150
+ }, L = typeof s.tooltip == "object" ? s.tooltip : void 0;
151
151
  return {
152
- series: w,
153
- x: u(k, v, y, !1),
154
- y: u(j, j?.type === "time" ? "time" : "linear", [], !0),
152
+ series: T,
153
+ x: u(A, y, b, !1),
154
+ y: u(M, M?.type === "time" ? "time" : "linear", [], !0),
155
155
  base: {
156
- x: A,
157
- y: N
156
+ x: j,
157
+ y: P
158
158
  },
159
- allScatter: E,
160
- zoom: F,
161
- tooltipMode: I?.mode ?? (E ? "nearest" : "axis"),
162
- baseline: Math.min(Math.max(0, N[0]), N[1]),
159
+ allScatter: D,
160
+ zoom: I,
161
+ tooltipMode: L?.mode ?? (D ? "nearest" : "axis"),
162
+ baseline: Math.min(Math.max(0, P[0]), P[1]),
163
163
  minSpan: {
164
- x: v === "category" ? 1 : (A[1] - A[0]) * 1e-7,
165
- y: (N[1] - N[0]) * 1e-7
164
+ x: y === "category" ? 1 : (j[1] - j[0]) * 1e-7,
165
+ y: (P[1] - P[0]) * 1e-7
166
166
  }
167
167
  };
168
168
  }, m = /* @__PURE__ */ new WeakMap(), h = (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","names":["firstX","data","xs","list","i","item","detectXType","datas","x","axisModel","options","gridDefault","extent","min","max","values","v","smallestStep","step","c","cols","d","buildModel","input","s","xType","categories","collectCategories","categoryMap","resolveX","xResolver","name","resolverKey","usedKeys","series","key","index","entry","cache","normalizeData","type","color","resolveColor","element","theme","pointColors","resolved","rgba","id","toCss","hidden","visible","allScatter","bars","band","slots","stack","group","slotWidth","sums","slot","totals","count","y","t","base","xOpts","xRange","ensureSpan","pad","niceDomain","yOpts","yValues","yRange","zoomOption","zoomAxes","tooltip","grids","gridOf","grid","GridIndex"],"sources":["../../../../charts/src/engine/model.ts"],"sourcesContent":["// Options -> chart model: normalized data, colors, bar layout and the full\n// ranges of the axes. Pure (no DOM besides color resolution).\n\nimport { resolveColor, toCss, type Rgba } from \"./color\";\nimport {\n collectCategories,\n normalizeData,\n xResolver,\n type SeriesColumns,\n} from \"./data\";\nimport { ensureSpan, niceDomain } from \"./scale\";\nimport { GridIndex } from \"./spatial\";\nimport type { ChartTheme } from \"./theme\";\nimport type {\n ChartAxisOptions,\n ChartAxisType,\n ChartOptions,\n ChartSeriesData,\n ChartSeriesType,\n} from \"./types\";\nimport type { Range } from \"./viewport\";\n\nexport interface AxisModel {\n type: ChartAxisType;\n reverse: boolean;\n categories: string[];\n title?: string;\n format?: (value: number) => string;\n grid: boolean;\n visible: boolean;\n tickCount?: number;\n}\n\nexport interface SeriesModel {\n index: number;\n /** Key of the GPU resources and of the data cache */\n key: string;\n id: string;\n name: string;\n type: ChartSeriesType;\n color: Rgba;\n colorCss: string;\n lineWidth: number;\n pointSize: number;\n opacity: number;\n hidden: boolean;\n showLabels: boolean;\n cols: SeriesColumns;\n /** Bars: x offset of the series inside a group and half of the bar width */\n barOffset: number;\n barHalfWidth: number;\n /** Bars: bottom / top of every bar (stacks included) */\n barBase: Float64Array | null;\n barTop: Float64Array | null;\n /** Scatter: resolved per-point colors */\n pointColors: (Rgba | undefined)[] | null;\n}\n\nexport interface ChartModel {\n series: SeriesModel[];\n x: AxisModel;\n y: AxisModel;\n /** Full ranges (zoomed out) */\n base: { x: Range; y: Range };\n allScatter: boolean;\n zoom: { x: boolean; y: boolean };\n tooltipMode: \"nearest\" | \"axis\";\n /** Y value the areas are filled to */\n baseline: number;\n /** Smallest zoomed spans */\n minSpan: { x: number; y: number };\n}\n\nexport interface DataCacheEntry {\n data: ChartSeriesData;\n resolverKey: string;\n cols: SeriesColumns;\n}\n\nexport type DataCache = Map<string, DataCacheEntry>;\n\nconst firstX = (data: ChartSeriesData): unknown => {\n if (typeof data === \"object\" && data !== null && !(\"length\" in data)) {\n const xs = (data as { x?: ArrayLike<unknown> }).x;\n return xs && xs.length ? xs[0] : undefined;\n }\n const list = data as ArrayLike<unknown>;\n for (let i = 0; i < Math.min(list.length, 8); i++) {\n const item = list[i];\n if (Array.isArray(item)) return item[0];\n if (item && typeof item === \"object\") return (item as { x?: unknown }).x;\n }\n return undefined;\n};\n\n/** Axis type when not given: dates -> time, strings -> category */\nexport const detectXType = (\n datas: readonly ChartSeriesData[],\n): ChartAxisType => {\n for (const data of datas) {\n const x = firstX(data);\n if (x instanceof Date) return \"time\";\n if (typeof x === \"string\") return \"category\";\n }\n return \"linear\";\n};\n\nconst axisModel = (\n options: ChartAxisOptions | undefined,\n type: ChartAxisType,\n categories: string[],\n gridDefault: boolean,\n): AxisModel => ({\n type,\n reverse: !!options?.reverse,\n categories,\n title: options?.title,\n format: options?.format,\n grid: options?.grid ?? gridDefault,\n visible: options?.visible ?? true,\n tickCount: options?.tickCount,\n});\n\nconst extent = (values: ArrayLike<number>): Range => {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n return [min, max];\n};\n\n/** Smallest positive gap between consecutive x values (bar width on numeric axes) */\nconst smallestStep = (cols: SeriesColumns[]): number => {\n let step = Infinity;\n for (const c of cols) {\n const xs = c.sorted ? c.x : Float64Array.from(c.x).sort();\n for (let i = 1; i < c.count; i++) {\n const d = xs[i] - xs[i - 1];\n if (d > 0 && d < step) step = d;\n }\n }\n return step;\n};\n\nexport const buildModel = (\n options: ChartOptions,\n theme: ChartTheme,\n hidden: ReadonlySet<string>,\n cache: DataCache,\n element: Element | null,\n): ChartModel => {\n const input = options.series;\n const datas = input.map((s) => s.data);\n const xType = options.xAxis?.type ?? detectXType(datas);\n const categories =\n xType === \"category\"\n ? [...(options.xAxis?.categories ?? collectCategories(datas))]\n : [];\n const categoryMap = new Map(categories.map((c, i) => [c, i]));\n const resolveX = xResolver(xType, (name) => categoryMap.get(name) ?? NaN);\n const resolverKey = `${xType}|${categories.join(\"\\u0001\")}`;\n\n const usedKeys = new Set<string>();\n const series: SeriesModel[] = input.map((s, index) => {\n let key = s.id ?? `#${index}`;\n while (usedKeys.has(key)) key += \"'\";\n usedKeys.add(key);\n let entry = cache.get(key);\n if (!entry || entry.data !== s.data || entry.resolverKey !== resolverKey) {\n entry = {\n data: s.data,\n resolverKey,\n cols: normalizeData(s.data, resolveX),\n };\n cache.set(key, entry);\n }\n const type = s.type ?? \"line\";\n const color = s.color\n ? resolveColor(\n s.color,\n element,\n theme.palette[index % theme.palette.length],\n )\n : theme.palette[index % theme.palette.length];\n const cols = entry.cols;\n let pointColors: (Rgba | undefined)[] | null = null;\n if (type === \"scatter\" && cols.colors) {\n const resolved = new Map<string, Rgba>();\n pointColors = cols.colors.map((c) => {\n if (c === undefined) return undefined;\n let rgba = resolved.get(c);\n if (!rgba) resolved.set(c, (rgba = resolveColor(c, element, color)));\n return rgba;\n });\n }\n const id = s.id ?? String(index);\n return {\n index,\n key,\n id,\n name: s.name ?? `Series ${index + 1}`,\n type,\n color,\n colorCss: toCss(color),\n lineWidth: s.lineWidth ?? 2,\n pointSize: s.pointSize ?? 8,\n opacity:\n s.opacity ?? (type === \"area\" ? 0.28 : type === \"scatter\" ? 0.78 : 1),\n hidden: !!s.hidden || hidden.has(id),\n showLabels: !!s.showLabels,\n cols,\n barOffset: 0,\n barHalfWidth: 0,\n barBase: null,\n barTop: null,\n pointColors,\n };\n });\n\n const visible = series.filter((s) => !s.hidden);\n const allScatter =\n series.length > 0 && series.every((s) => s.type === \"scatter\");\n\n // Bars: groups (one slot per stack) and stacking\n const bars = visible.filter((s) => s.type === \"bar\");\n const band =\n xType === \"category\"\n ? 1\n : (() => {\n const step = smallestStep(bars.map((s) => s.cols));\n return Number.isFinite(step) ? step : 1;\n })();\n if (bars.length) {\n const slots = new Map<string, number>();\n for (const s of bars) {\n const stack = input[s.index].stack ?? `\\u0000${s.key}`;\n if (!slots.has(stack)) slots.set(stack, slots.size);\n }\n const group = band * (slots.size > 1 ? 0.78 : 0.62);\n const slotWidth = group / slots.size;\n const sums = new Map<string, Map<number, [number, number]>>();\n for (const s of bars) {\n const stack = input[s.index].stack ?? `\\u0000${s.key}`;\n const slot = slots.get(stack) ?? 0;\n s.barOffset = -group / 2 + slotWidth * (slot + 0.5);\n s.barHalfWidth = (slotWidth / 2) * (slots.size > 1 ? 0.86 : 1);\n let totals = sums.get(stack);\n if (!totals) sums.set(stack, (totals = new Map()));\n const { x, y, count } = s.cols;\n s.barBase = new Float64Array(count);\n s.barTop = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n const v = y[i];\n if (!Number.isFinite(v)) {\n s.barBase[i] = NaN;\n s.barTop[i] = NaN;\n continue;\n }\n const t = totals.get(x[i]) ?? [0, 0];\n const base = v >= 0 ? t[0] : t[1];\n s.barBase[i] = base;\n s.barTop[i] = base + v;\n if (v >= 0) t[0] += v;\n else t[1] += v;\n totals.set(x[i], t);\n }\n }\n }\n\n // X range\n const xOpts = options.xAxis;\n let xRange: Range;\n if (xType === \"category\") {\n xRange = [-0.5, Math.max(1, categories.length) - 0.5];\n } else {\n const values: number[] = [];\n for (const s of visible) {\n values.push(s.cols.xMin, s.cols.xMax);\n if (s.type === \"bar\") {\n values.push(s.cols.xMin - band / 2, s.cols.xMax + band / 2);\n }\n }\n xRange = ensureSpan(\n ...extent(values),\n xType === \"time\" ? [Date.now() - 86400000, Date.now()] : [0, 1],\n );\n if (allScatter) {\n const pad = (xRange[1] - xRange[0]) * 0.04;\n xRange = [xRange[0] - pad, xRange[1] + pad];\n }\n const nice = xOpts?.nice ?? (allScatter && xType === \"linear\");\n if (nice && xType === \"linear\") {\n xRange = niceDomain(xRange[0], xRange[1], xOpts?.tickCount ?? 6);\n }\n }\n if (xOpts?.min !== undefined) xRange[0] = xOpts.min;\n if (xOpts?.max !== undefined) xRange[1] = xOpts.max;\n xRange = ensureSpan(xRange[0], xRange[1]);\n\n // Y range\n const yOpts = options.yAxis;\n const yValues: number[] = [];\n for (const s of visible) {\n if (s.type === \"bar\" && s.barBase && s.barTop) {\n yValues.push(...extent(s.barBase), ...extent(s.barTop));\n } else {\n yValues.push(s.cols.yMin, s.cols.yMax);\n }\n }\n if (bars.length || yOpts?.zero) yValues.push(0);\n let yRange = ensureSpan(...extent(yValues));\n if (allScatter) {\n const pad = (yRange[1] - yRange[0]) * 0.06;\n yRange = [yRange[0] - pad, yRange[1] + pad];\n }\n if ((yOpts?.nice ?? true) && (yOpts?.type ?? \"linear\") === \"linear\") {\n yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);\n }\n if (bars.length && !yOpts?.zero) {\n // bars start at zero: no padding below / above it\n if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;\n }\n if (yOpts?.min !== undefined) yRange[0] = yOpts.min;\n if (yOpts?.max !== undefined) yRange[1] = yOpts.max;\n yRange = ensureSpan(yRange[0], yRange[1]);\n\n const zoomOption =\n options.interaction === false\n ? false\n : options.interaction === true || options.interaction === undefined\n ? true\n : (options.interaction.zoom ?? true);\n const zoomAxes =\n zoomOption === false\n ? { x: false, y: false }\n : zoomOption === true\n ? { x: true, y: allScatter }\n : { x: zoomOption.includes(\"x\"), y: zoomOption.includes(\"y\") };\n\n const tooltip =\n typeof options.tooltip === \"object\" ? options.tooltip : undefined;\n\n return {\n series,\n x: axisModel(xOpts, xType, categories, false),\n y: axisModel(yOpts, yOpts?.type === \"time\" ? \"time\" : \"linear\", [], true),\n base: { x: xRange, y: yRange },\n allScatter,\n zoom: zoomAxes,\n tooltipMode: tooltip?.mode ?? (allScatter ? \"nearest\" : \"axis\"),\n baseline: Math.min(Math.max(0, yRange[0]), yRange[1]),\n minSpan: {\n x: xType === \"category\" ? 1 : (xRange[1] - xRange[0]) * 1e-7,\n y: (yRange[1] - yRange[0]) * 1e-7,\n },\n };\n};\n\nconst grids = new WeakMap<SeriesColumns, GridIndex>();\n\n/** Spatial index of a scatter series, built on first use and kept with its data */\nexport const gridOf = (s: SeriesModel): GridIndex => {\n let grid = grids.get(s.cols);\n if (!grid) {\n grid = new GridIndex(s.cols.x, s.cols.y, s.cols.count);\n grids.set(s.cols, grid);\n }\n return grid;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"model.js","names":["firstX","data","xs","list","i","item","detectXType","datas","x","axisModel","options","gridDefault","extent","min","max","values","v","smallestStep","step","c","cols","d","buildModel","resolve","resolver","theme","resolveStaticColor","value","fallback","input","s","xType","categories","collectCategories","categoryMap","resolveX","xResolver","name","resolverKey","usedKeys","series","key","index","entry","cache","normalizeData","type","color","pointColors","resolved","rgba","id","toCss","hidden","visible","allScatter","bars","band","slots","stack","group","slotWidth","sums","slot","totals","count","y","t","base","xOpts","xRange","ensureSpan","pad","niceDomain","yOpts","yValues","yRange","zoomOption","zoomAxes","tooltip","grids","gridOf","grid","GridIndex"],"sources":["../../../../charts/src/engine/model.ts"],"sourcesContent":["// Options -> chart model: normalized data, colors, bar layout and the full\n// ranges of the axes. Pure (colors go through the theme's resolver).\n\nimport {\n resolveStaticColor,\n toCss,\n type ColorResolver,\n type Rgba,\n} from \"./color\";\nimport {\n collectCategories,\n normalizeData,\n xResolver,\n type SeriesColumns,\n} from \"./data\";\nimport { ensureSpan, niceDomain } from \"./scale\";\nimport { GridIndex } from \"./spatial\";\nimport type { ChartTheme } from \"./theme\";\nimport type {\n ChartAxisOptions,\n ChartAxisType,\n ChartOptions,\n ChartSeriesData,\n ChartSeriesType,\n} from \"./types\";\nimport type { Range } from \"./viewport\";\n\nexport interface AxisModel {\n type: ChartAxisType;\n reverse: boolean;\n categories: string[];\n title?: string;\n format?: (value: number) => string;\n grid: boolean;\n visible: boolean;\n tickCount?: number;\n}\n\nexport interface SeriesModel {\n index: number;\n /** Key of the GPU resources and of the data cache */\n key: string;\n id: string;\n name: string;\n type: ChartSeriesType;\n color: Rgba;\n colorCss: string;\n lineWidth: number;\n pointSize: number;\n opacity: number;\n hidden: boolean;\n showLabels: boolean;\n cols: SeriesColumns;\n /** Bars: x offset of the series inside a group and half of the bar width */\n barOffset: number;\n barHalfWidth: number;\n /** Bars: bottom / top of every bar (stacks included) */\n barBase: Float64Array | null;\n barTop: Float64Array | null;\n /** Scatter: resolved per-point colors */\n pointColors: (Rgba | undefined)[] | null;\n}\n\nexport interface ChartModel {\n series: SeriesModel[];\n x: AxisModel;\n y: AxisModel;\n /** Full ranges (zoomed out) */\n base: { x: Range; y: Range };\n allScatter: boolean;\n zoom: { x: boolean; y: boolean };\n tooltipMode: \"nearest\" | \"axis\";\n /** Y value the areas are filled to */\n baseline: number;\n /** Smallest zoomed spans */\n minSpan: { x: number; y: number };\n}\n\nexport interface DataCacheEntry {\n data: ChartSeriesData;\n resolverKey: string;\n cols: SeriesColumns;\n}\n\nexport type DataCache = Map<string, DataCacheEntry>;\n\nconst firstX = (data: ChartSeriesData): unknown => {\n if (typeof data === \"object\" && data !== null && !(\"length\" in data)) {\n const xs = (data as { x?: ArrayLike<unknown> }).x;\n return xs && xs.length ? xs[0] : undefined;\n }\n const list = data as ArrayLike<unknown>;\n for (let i = 0; i < Math.min(list.length, 8); i++) {\n const item = list[i];\n if (Array.isArray(item)) return item[0];\n if (item && typeof item === \"object\") return (item as { x?: unknown }).x;\n }\n return undefined;\n};\n\n/** Axis type when not given: dates -> time, strings -> category */\nexport const detectXType = (\n datas: readonly ChartSeriesData[],\n): ChartAxisType => {\n for (const data of datas) {\n const x = firstX(data);\n if (x instanceof Date) return \"time\";\n if (typeof x === \"string\") return \"category\";\n }\n return \"linear\";\n};\n\nconst axisModel = (\n options: ChartAxisOptions | undefined,\n type: ChartAxisType,\n categories: string[],\n gridDefault: boolean,\n): AxisModel => ({\n type,\n reverse: !!options?.reverse,\n categories,\n title: options?.title,\n format: options?.format,\n grid: options?.grid ?? gridDefault,\n visible: options?.visible ?? true,\n tickCount: options?.tickCount,\n});\n\nconst extent = (values: ArrayLike<number>): Range => {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n return [min, max];\n};\n\n/** Smallest positive gap between consecutive x values (bar width on numeric axes) */\nconst smallestStep = (cols: SeriesColumns[]): number => {\n let step = Infinity;\n for (const c of cols) {\n const xs = c.sorted ? c.x : Float64Array.from(c.x).sort();\n for (let i = 1; i < c.count; i++) {\n const d = xs[i] - xs[i - 1];\n if (d > 0 && d < step) step = d;\n }\n }\n return step;\n};\n\nexport const buildModel = (\n options: ChartOptions,\n theme: ChartTheme,\n hidden: ReadonlySet<string>,\n cache: DataCache,\n resolver: ColorResolver | null = null,\n): ChartModel => {\n const resolve: ColorResolver =\n resolver ??\n theme.resolve ??\n ((value, fallback) => resolveStaticColor(value, {}, fallback));\n const input = options.series;\n const datas = input.map((s) => s.data);\n const xType = options.xAxis?.type ?? detectXType(datas);\n const categories =\n xType === \"category\"\n ? [...(options.xAxis?.categories ?? collectCategories(datas))]\n : [];\n const categoryMap = new Map(categories.map((c, i) => [c, i]));\n const resolveX = xResolver(xType, (name) => categoryMap.get(name) ?? NaN);\n const resolverKey = `${xType}|${categories.join(\"\\u0001\")}`;\n\n const usedKeys = new Set<string>();\n const series: SeriesModel[] = input.map((s, index) => {\n let key = s.id ?? `#${index}`;\n while (usedKeys.has(key)) key += \"'\";\n usedKeys.add(key);\n let entry = cache.get(key);\n if (!entry || entry.data !== s.data || entry.resolverKey !== resolverKey) {\n entry = {\n data: s.data,\n resolverKey,\n cols: normalizeData(s.data, resolveX),\n };\n cache.set(key, entry);\n }\n const type = s.type ?? \"line\";\n const color = s.color\n ? resolve(s.color, theme.palette[index % theme.palette.length])\n : theme.palette[index % theme.palette.length];\n const cols = entry.cols;\n let pointColors: (Rgba | undefined)[] | null = null;\n if (type === \"scatter\" && cols.colors) {\n const resolved = new Map<string, Rgba>();\n pointColors = cols.colors.map((c) => {\n if (c === undefined) return undefined;\n let rgba = resolved.get(c);\n if (!rgba) resolved.set(c, (rgba = resolve(c, color)));\n return rgba;\n });\n }\n const id = s.id ?? String(index);\n return {\n index,\n key,\n id,\n name: s.name ?? `Series ${index + 1}`,\n type,\n color,\n colorCss: toCss(color),\n lineWidth: s.lineWidth ?? 2,\n pointSize: s.pointSize ?? 8,\n opacity:\n s.opacity ?? (type === \"area\" ? 0.28 : type === \"scatter\" ? 0.78 : 1),\n hidden: !!s.hidden || hidden.has(id),\n showLabels: !!s.showLabels,\n cols,\n barOffset: 0,\n barHalfWidth: 0,\n barBase: null,\n barTop: null,\n pointColors,\n };\n });\n\n const visible = series.filter((s) => !s.hidden);\n const allScatter =\n series.length > 0 && series.every((s) => s.type === \"scatter\");\n\n // Bars: groups (one slot per stack) and stacking\n const bars = visible.filter((s) => s.type === \"bar\");\n const band =\n xType === \"category\"\n ? 1\n : (() => {\n const step = smallestStep(bars.map((s) => s.cols));\n return Number.isFinite(step) ? step : 1;\n })();\n if (bars.length) {\n const slots = new Map<string, number>();\n for (const s of bars) {\n const stack = input[s.index].stack ?? `\\u0000${s.key}`;\n if (!slots.has(stack)) slots.set(stack, slots.size);\n }\n const group = band * (slots.size > 1 ? 0.78 : 0.62);\n const slotWidth = group / slots.size;\n const sums = new Map<string, Map<number, [number, number]>>();\n for (const s of bars) {\n const stack = input[s.index].stack ?? `\\u0000${s.key}`;\n const slot = slots.get(stack) ?? 0;\n s.barOffset = -group / 2 + slotWidth * (slot + 0.5);\n s.barHalfWidth = (slotWidth / 2) * (slots.size > 1 ? 0.86 : 1);\n let totals = sums.get(stack);\n if (!totals) sums.set(stack, (totals = new Map()));\n const { x, y, count } = s.cols;\n s.barBase = new Float64Array(count);\n s.barTop = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n const v = y[i];\n if (!Number.isFinite(v)) {\n s.barBase[i] = NaN;\n s.barTop[i] = NaN;\n continue;\n }\n const t = totals.get(x[i]) ?? [0, 0];\n const base = v >= 0 ? t[0] : t[1];\n s.barBase[i] = base;\n s.barTop[i] = base + v;\n if (v >= 0) t[0] += v;\n else t[1] += v;\n totals.set(x[i], t);\n }\n }\n }\n\n // X range\n const xOpts = options.xAxis;\n let xRange: Range;\n if (xType === \"category\") {\n xRange = [-0.5, Math.max(1, categories.length) - 0.5];\n } else {\n const values: number[] = [];\n for (const s of visible) {\n values.push(s.cols.xMin, s.cols.xMax);\n if (s.type === \"bar\") {\n values.push(s.cols.xMin - band / 2, s.cols.xMax + band / 2);\n }\n }\n xRange = ensureSpan(\n ...extent(values),\n xType === \"time\" ? [Date.now() - 86400000, Date.now()] : [0, 1],\n );\n if (allScatter) {\n const pad = (xRange[1] - xRange[0]) * 0.04;\n xRange = [xRange[0] - pad, xRange[1] + pad];\n }\n const nice = xOpts?.nice ?? (allScatter && xType === \"linear\");\n if (nice && xType === \"linear\") {\n xRange = niceDomain(xRange[0], xRange[1], xOpts?.tickCount ?? 6);\n }\n }\n if (xOpts?.min !== undefined) xRange[0] = xOpts.min;\n if (xOpts?.max !== undefined) xRange[1] = xOpts.max;\n xRange = ensureSpan(xRange[0], xRange[1]);\n\n // Y range\n const yOpts = options.yAxis;\n const yValues: number[] = [];\n for (const s of visible) {\n if (s.type === \"bar\" && s.barBase && s.barTop) {\n yValues.push(...extent(s.barBase), ...extent(s.barTop));\n } else {\n yValues.push(s.cols.yMin, s.cols.yMax);\n }\n }\n if (bars.length || yOpts?.zero) yValues.push(0);\n let yRange = ensureSpan(...extent(yValues));\n if (allScatter) {\n const pad = (yRange[1] - yRange[0]) * 0.06;\n yRange = [yRange[0] - pad, yRange[1] + pad];\n }\n if ((yOpts?.nice ?? true) && (yOpts?.type ?? \"linear\") === \"linear\") {\n yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);\n }\n if (bars.length && !yOpts?.zero) {\n // bars start at zero: no padding below / above it\n if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;\n }\n if (yOpts?.min !== undefined) yRange[0] = yOpts.min;\n if (yOpts?.max !== undefined) yRange[1] = yOpts.max;\n yRange = ensureSpan(yRange[0], yRange[1]);\n\n const zoomOption =\n options.interaction === false\n ? false\n : options.interaction === true || options.interaction === undefined\n ? true\n : (options.interaction.zoom ?? true);\n const zoomAxes =\n zoomOption === false\n ? { x: false, y: false }\n : zoomOption === true\n ? { x: true, y: allScatter }\n : { x: zoomOption.includes(\"x\"), y: zoomOption.includes(\"y\") };\n\n const tooltip =\n typeof options.tooltip === \"object\" ? options.tooltip : undefined;\n\n return {\n series,\n x: axisModel(xOpts, xType, categories, false),\n y: axisModel(yOpts, yOpts?.type === \"time\" ? \"time\" : \"linear\", [], true),\n base: { x: xRange, y: yRange },\n allScatter,\n zoom: zoomAxes,\n tooltipMode: tooltip?.mode ?? (allScatter ? \"nearest\" : \"axis\"),\n baseline: Math.min(Math.max(0, yRange[0]), yRange[1]),\n minSpan: {\n x: xType === \"category\" ? 1 : (xRange[1] - xRange[0]) * 1e-7,\n y: (yRange[1] - yRange[0]) * 1e-7,\n },\n };\n};\n\nconst grids = new WeakMap<SeriesColumns, GridIndex>();\n\n/** Spatial index of a scatter series, built on first use and kept with its data */\nexport const gridOf = (s: SeriesModel): GridIndex => {\n let grid = grids.get(s.cols);\n if (!grid) {\n grid = new GridIndex(s.cols.x, s.cols.y, s.cols.count);\n grids.set(s.cols, grid);\n }\n return grid;\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("./color.cjs");var t=(e,t=e.fontSize,n=400)=>`${n} ${t}px ${e.fontFamily}`,n=e=>Math.round(e)+.5,r=(e,t)=>{let{plot:n}=t,r=e.x0===void 0?-1/0:t.xToPx(e.x0),i=e.x1===void 0?1/0:t.xToPx(e.x1),a=e.y0===void 0?1/0:t.yToPx(e.y0),o=e.y1===void 0?-1/0:t.yToPx(e.y1),s=Math.max(n.x,Math.min(r,i)),c=Math.min(n.x+n.width,Math.max(r,i)),l=Math.max(n.y,Math.min(a,o)),u=Math.min(n.y+n.height,Math.max(a,o));return{x:s,y:l,width:c-s,height:u-l}},i=(i,a)=>{let{scales:o,theme:s,x:c,y:l,xTicks:u,yTicks:d}=a,{plot:f}=o;i.clearRect(0,0,a.width,a.height),i.save(),i.beginPath(),i.rect(f.x,f.y,f.width,f.height),i.clip();for(let t of a.annotations){if(t.type!==`rect`)continue;let n=r(t,o);n.width<=0||n.height<=0||(i.fillStyle=e.toCss(t.color,t.opacity),i.fillRect(n.x,n.y,n.width,n.height))}if(i.restore(),i.lineWidth=1,i.strokeStyle=e.toCss(s.grid),i.beginPath(),l.grid)for(let e of d.values){let t=n(o.yToPx(e));t<f.y-1||t>f.y+f.height+1||(i.moveTo(f.x,t),i.lineTo(f.x+f.width,t))}if(c.grid)for(let e of u.values){let t=n(o.xToPx(e));t<f.x-1||t>f.x+f.width+1||(i.moveTo(t,f.y),i.lineTo(t,f.y+f.height))}i.stroke();let p=Math.ceil(s.fontSize*1.4);if(i.font=t(s),i.fillStyle=e.toCss(s.textMuted),c.visible){i.strokeStyle=e.toCss(s.axis),i.beginPath();let r=n(f.y+f.height);i.moveTo(f.x,r),i.lineTo(f.x+f.width,r),i.stroke(),i.textBaseline=`top`,i.textAlign=`center`;let l=-1/0,d=u.values.map((e,t)=>({px:o.xToPx(e),text:u.labels[t]})).sort((e,t)=>e.px-t.px);for(let{px:e,text:t}of d){if(e<f.x-.5||e>f.x+f.width+.5)continue;let n=i.measureText(t).width,r=Math.max(0,Math.min(a.width-n,e-n/2));r<l+6||(l=r+n,i.fillText(t,r+n/2,f.y+f.height+7))}c.title&&(i.font=t(s,s.fontSize+1,500),i.fillStyle=e.toCss(s.text,.8),i.fillText(c.title,f.x+f.width/2,f.y+f.height+p+10))}l.visible&&(i.font=t(s),i.fillStyle=e.toCss(s.textMuted),i.textAlign=`right`,i.textBaseline=`middle`,d.values.forEach((e,t)=>{let n=o.yToPx(e);n<f.y-.5||n>f.y+f.height+.5||i.fillText(d.labels[t],f.x-8,n)}),l.title&&(i.save(),i.font=t(s,s.fontSize+1,500),i.fillStyle=e.toCss(s.text,.8),i.translate(p/2+4,f.y+f.height/2),i.rotate(-Math.PI/2),i.textAlign=`center`,i.fillText(l.title,0,0),i.restore()))},a=(e,t)=>e.x<t.x+t.width&&t.x<e.x+e.width&&e.y<t.y+t.height&&t.y<e.y+e.height,o=(e,t)=>e.x>=t.x&&e.y>=t.y&&e.x+e.width<=t.x+t.width&&e.y+e.height<=t.y+t.height,s=(e,t,n,r,i,a)=>{e.lineWidth=3,e.lineJoin=`round`,e.strokeStyle=a,e.strokeText(t,n,r),e.fillStyle=i,e.fillText(t,n,r)},c=(e,t,n,r,i=[])=>{let s=[];for(let c of e){let e=n(c.text),l=c.r+4,u=[{x:c.x+l,y:c.y-r/2,width:e,height:r},{x:c.x-l-e,y:c.y-r/2,width:e,height:r},{x:c.x-e/2,y:c.y-l-r,width:e,height:r},{x:c.x-e/2,y:c.y+l,width:e,height:r}].find(e=>o(e,t)&&!i.some(t=>a(t,e)));u&&(i.push(u),s.push({label:c,box:u}))}return s},l=(i,a)=>{let{scales:o,theme:l}=a,{plot:u}=o;i.clearRect(0,0,a.width,a.height),i.save(),i.beginPath(),i.rect(u.x,u.y,u.width,u.height),i.clip();let d=e.toCss(l.background,.9),f=[],p=l.fontSize+4;for(let r of a.annotations){if(r.type!==`line`)continue;let a=e.toCss(r.color);if(i.strokeStyle=a,i.lineWidth=r.width,i.setLineDash(r.dash),i.beginPath(),r.axis===`y`){let e=n(o.yToPx(r.value));i.moveTo(u.x,e),i.lineTo(u.x+u.width,e),i.stroke(),r.label&&(i.setLineDash([]),i.font=t(l,l.fontSize,500),i.textAlign=`right`,i.textBaseline=`bottom`,s(i,r.label,u.x+u.width-6,e-3,a,d))}else{let e=n(o.xToPx(r.value));i.moveTo(e,u.y),i.lineTo(e,u.y+u.height),i.stroke(),r.label&&(i.setLineDash([]),i.font=t(l,l.fontSize,500),i.textAlign=`left`,i.textBaseline=`top`,s(i,r.label,e+5,u.y+5,a,d))}}i.setLineDash([]),i.font=t(l,l.fontSize+1,600);for(let t of a.annotations){if(t.type!==`rect`||!t.label)continue;let n=r(t,o);if(n.width<=0||n.height<=0)continue;let a=i.measureText(t.label).width,s=t.labelPosition,c=s.endsWith(`left`)?n.x+10:s.endsWith(`right`)?n.x+n.width-10-a:n.x+(n.width-a)/2,l=s.startsWith(`top`)?n.y+10:s.startsWith(`bottom`)?n.y+n.height-10-p:n.y+(n.height-p)/2;i.textAlign=`left`,i.textBaseline=`top`,i.fillStyle=e.toCss(t.labelColor),i.fillText(t.label,c,l),f.push({x:c,y:l,width:a,height:p})}if(a.pointLabels.length){i.font=t(l),i.textAlign=`left`,i.textBaseline=`middle`;let n=e.toCss(l.text,.85),r=c(a.pointLabels,u,e=>i.measureText(e).width,p-2,f);for(let{label:e,box:t}of r)s(i,e.text,t.x,t.y+t.height/2,n,d)}i.restore()};exports.drawBackground=i,exports.drawForeground=l,exports.font=t,exports.placeLabels=c;
1
+ const e=require("./color.cjs");var t=(e,t=e.fontSize,n=400)=>`${n} ${t}px ${e.fontFamily}`,n=e=>Math.round(e)+.5,r=(e,t,n,r)=>{let{plot:i}=t,a=e.x===void 0?i.x+i.width/2:t.xToPx(e.x),o=e.y===void 0?i.y+i.height/2:t.yToPx(e.y),s=a-n/2,c=o-r/2;return e.anchor===`top`?c=o+6:e.anchor===`bottom`?c=o-6-r:e.anchor===`left`?s=a+6:e.anchor===`right`&&(s=a-6-n),s=Math.max(i.x+6,Math.min(s,i.x+i.width-6-n)),c=Math.max(i.y+2,Math.min(c,i.y+i.height-2-r)),{x:s,y:c,width:n,height:r}},i=(e,t)=>{let{plot:n}=t,r=e.x0===void 0?-1/0:t.xToPx(e.x0),i=e.x1===void 0?1/0:t.xToPx(e.x1),a=e.y0===void 0?1/0:t.yToPx(e.y0),o=e.y1===void 0?-1/0:t.yToPx(e.y1),s=Math.max(n.x,Math.min(r,i)),c=Math.min(n.x+n.width,Math.max(r,i)),l=Math.max(n.y,Math.min(a,o)),u=Math.min(n.y+n.height,Math.max(a,o));return{x:s,y:l,width:c-s,height:u-l}},a=(r,a)=>{let{scales:o,theme:s,x:c,y:l,xTicks:u,yTicks:d}=a,{plot:f}=o;r.clearRect(0,0,a.width,a.height),r.save(),r.beginPath(),r.rect(f.x,f.y,f.width,f.height),r.clip();for(let t of a.annotations){if(t.type!==`rect`)continue;let n=i(t,o);n.width<=0||n.height<=0||(r.fillStyle=e.toCss(t.color,t.opacity),r.fillRect(n.x,n.y,n.width,n.height))}if(r.restore(),r.lineWidth=1,r.strokeStyle=e.toCss(s.grid),r.beginPath(),l.grid)for(let e of d.values){let t=n(o.yToPx(e));t<f.y-1||t>f.y+f.height+1||(r.moveTo(f.x,t),r.lineTo(f.x+f.width,t))}if(c.grid)for(let e of u.values){let t=n(o.xToPx(e));t<f.x-1||t>f.x+f.width+1||(r.moveTo(t,f.y),r.lineTo(t,f.y+f.height))}r.stroke();let p=Math.ceil(s.fontSize*1.4);if(r.font=t(s),r.fillStyle=e.toCss(s.textMuted),c.visible){r.strokeStyle=e.toCss(s.axis),r.beginPath();let i=n(f.y+f.height);r.moveTo(f.x,i),r.lineTo(f.x+f.width,i),r.stroke(),r.textBaseline=`top`,r.textAlign=`center`;let l=-1/0,d=u.values.map((e,t)=>({px:o.xToPx(e),text:u.labels[t]})).sort((e,t)=>e.px-t.px);for(let{px:e,text:t}of d){if(e<f.x-.5||e>f.x+f.width+.5)continue;let n=r.measureText(t).width,i=Math.max(0,Math.min(a.width-n,e-n/2));i<l+6||(l=i+n,r.fillText(t,i+n/2,f.y+f.height+7))}c.title&&(r.font=t(s,s.fontSize+1,500),r.fillStyle=e.toCss(s.text,.8),r.fillText(c.title,f.x+f.width/2,f.y+f.height+p+10))}l.visible&&(r.font=t(s),r.fillStyle=e.toCss(s.textMuted),r.textAlign=`right`,r.textBaseline=`middle`,d.values.forEach((e,t)=>{let n=o.yToPx(e);n<f.y-.5||n>f.y+f.height+.5||r.fillText(d.labels[t],f.x-8,n)}),l.title&&(r.save(),r.font=t(s,s.fontSize+1,500),r.fillStyle=e.toCss(s.text,.8),r.translate(p/2+4,f.y+f.height/2),r.rotate(-Math.PI/2),r.textAlign=`center`,r.fillText(l.title,0,0),r.restore()))},o=(e,t)=>e.x<t.x+t.width&&t.x<e.x+e.width&&e.y<t.y+t.height&&t.y<e.y+e.height,s=(e,t)=>e.x>=t.x&&e.y>=t.y&&e.x+e.width<=t.x+t.width&&e.y+e.height<=t.y+t.height,c=(e,t,n,r,i,a)=>{e.lineWidth=3,e.lineJoin=`round`,e.strokeStyle=a,e.strokeText(t,n,r),e.fillStyle=i,e.fillText(t,n,r)},l=(e,t,n,r,i=[])=>{let a=[];for(let c of e){let e=n(c.text),l=c.r+4,u=[{x:c.x+l,y:c.y-r/2,width:e,height:r},{x:c.x-l-e,y:c.y-r/2,width:e,height:r},{x:c.x-e/2,y:c.y-l-r,width:e,height:r},{x:c.x-e/2,y:c.y+l,width:e,height:r}].find(e=>s(e,t)&&!i.some(t=>o(t,e)));u&&(i.push(u),a.push({label:c,box:u}))}return a},u=(a,o)=>{let{scales:s,theme:u}=o,{plot:d}=s;o.clear!==!1&&a.clearRect(0,0,o.width,o.height),a.save(),a.beginPath(),a.rect(d.x,d.y,d.width,d.height),a.clip();let f=e.toCss(u.background,.9),p=[],m=u.fontSize+4;for(let r of o.annotations){if(r.type!==`line`)continue;let i=e.toCss(r.color);if(a.strokeStyle=i,a.lineWidth=r.width,a.setLineDash(r.dash),a.beginPath(),r.axis===`y`){let e=n(s.yToPx(r.value));a.moveTo(d.x,e),a.lineTo(d.x+d.width,e),a.stroke(),r.label&&(a.setLineDash([]),a.font=t(u,u.fontSize,500),a.textAlign=`right`,a.textBaseline=`bottom`,c(a,r.label,d.x+d.width-6,e-3,i,f))}else{let e=n(s.xToPx(r.value));a.moveTo(e,d.y),a.lineTo(e,d.y+d.height),a.stroke(),r.label&&(a.setLineDash([]),a.font=t(u,u.fontSize,500),a.textAlign=`left`,a.textBaseline=`top`,c(a,r.label,e+5,d.y+5,i,f))}}a.setLineDash([]),a.font=t(u,u.fontSize+1,600);for(let t of o.annotations){if(t.type!==`rect`||!t.label)continue;let n=i(t,s);if(n.width<=0||n.height<=0)continue;let r=a.measureText(t.label).width,o=t.labelPosition,c=o.endsWith(`left`)?n.x+10:o.endsWith(`right`)?n.x+n.width-10-r:n.x+(n.width-r)/2,l=o.startsWith(`top`)?n.y+10:o.startsWith(`bottom`)?n.y+n.height-10-m:n.y+(n.height-m)/2;a.textAlign=`left`,a.textBaseline=`top`,a.fillStyle=e.toCss(t.labelColor),a.fillText(t.label,c,l),p.push({x:c,y:l,width:r,height:m})}for(let n of o.annotations){if(n.type!==`text`||!n.text)continue;a.font=t(u,u.fontSize,n.weight);let i=r(n,s,a.measureText(n.text).width,m);a.textAlign=`left`,a.textBaseline=`middle`,c(a,n.text,i.x,i.y+i.height/2,e.toCss(n.color),f),p.push(i)}if(o.pointLabels.length){a.font=t(u),a.textAlign=`left`,a.textBaseline=`middle`;let n=e.toCss(u.text,.85),r=l(o.pointLabels,d,e=>a.measureText(e).width,m-2,p);for(let{label:e,box:t}of r)c(a,e.text,t.x,t.y+t.height/2,n,f)}a.restore()};exports.drawBackground=a,exports.drawForeground=u,exports.font=t,exports.placeLabels=l,exports.textBox=r;
2
2
  //# sourceMappingURL=overlay.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.cjs","names":["toCss","require_color","font","theme","weight","size","crisp","v","rectOf","s","xa","a","xb","ya","yb","left","plot","right","top","bottom","drawBackground","input","scales","ctx","r","y","yTicks","py","x","xTicks","px","line","base","lastRight","order","i","b","w","text","overlaps","inside","haloText","halo","color","placeLabels","placed","label","labels","measure","gap","box","height","c","occupied","o","drawForeground","labelHeight","pos","tx","ty","textColor","t"],"sources":["../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport type { Rect, Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\nconst rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n const xa = a.x0 === undefined ? -Infinity : s.xToPx(a.x0);\n const xb = a.x1 === undefined ? Infinity : s.xToPx(a.x1);\n const ya = a.y0 === undefined ? Infinity : s.yToPx(a.y0);\n const yb = a.y1 === undefined ? -Infinity : s.yToPx(a.y1);\n const left = Math.max(plot.x, Math.min(xa, xb));\n const right = Math.min(plot.x + plot.width, Math.max(xa, xb));\n const top = Math.max(plot.y, Math.min(ya, yb));\n const bottom = Math.min(plot.y + plot.height, Math.max(ya, yb));\n return { x: left, y: top, width: right - left, height: bottom - top };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, x, y, xTicks, yTicks } = input;\n const { plot } = scales;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of yTicks.values) {\n const py = crisp(scales.yToPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of xTicks.values) {\n const px = crisp(scales.xToPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = xTicks.values\n .map((v, i) => ({ px: scales.xToPx(v), text: xTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n yTicks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(yTicks.labels[i], plot.x - 8, py);\n });\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const candidates: Rect[] = [\n { x: label.x + gap, y: label.y - height / 2, width: w, height },\n { x: label.x - gap - w, y: label.y - height / 2, width: w, height },\n { x: label.x - w / 2, y: label.y - gap - height, width: w, height },\n { x: label.x - w / 2, y: label.y + gap, width: w, height },\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n if (a.axis === \"y\") {\n const py = crisp(scales.yToPx(a.value));\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(scales.xToPx(a.value));\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"overlay.cjs","names":["toCss","require_color","font","theme","weight","size","crisp","v","textBox","s","px","a","plot","py","x","width","y","height","rectOf","xa","xb","ya","yb","left","right","top","bottom","drawBackground","input","scales","ctx","r","yTicks","xTicks","line","base","lastRight","order","i","b","w","text","overlaps","inside","haloText","halo","color","placeLabels","placed","label","labels","measure","gap","box","c","occupied","o","drawForeground","labelHeight","pos","tx","ty","textColor","t"],"sources":["../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport type { Rect, Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const px = a.x === undefined ? plot.x + plot.width / 2 : s.xToPx(a.x);\n const py = a.y === undefined ? plot.y + plot.height / 2 : s.yToPx(a.y);\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\nconst rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n const xa = a.x0 === undefined ? -Infinity : s.xToPx(a.x0);\n const xb = a.x1 === undefined ? Infinity : s.xToPx(a.x1);\n const ya = a.y0 === undefined ? Infinity : s.yToPx(a.y0);\n const yb = a.y1 === undefined ? -Infinity : s.yToPx(a.y1);\n const left = Math.max(plot.x, Math.min(xa, xb));\n const right = Math.min(plot.x + plot.width, Math.max(xa, xb));\n const top = Math.max(plot.y, Math.min(ya, yb));\n const bottom = Math.min(plot.y + plot.height, Math.max(ya, yb));\n return { x: left, y: top, width: right - left, height: bottom - top };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, x, y, xTicks, yTicks } = input;\n const { plot } = scales;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of yTicks.values) {\n const py = crisp(scales.yToPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of xTicks.values) {\n const px = crisp(scales.xToPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = xTicks.values\n .map((v, i) => ({ px: scales.xToPx(v), text: xTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n yTicks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(yTicks.labels[i], plot.x - 8, py);\n });\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const candidates: Rect[] = [\n { x: label.x + gap, y: label.y - height / 2, width: w, height },\n { x: label.x - gap - w, y: label.y - height / 2, width: w, height },\n { x: label.x - w / 2, y: label.y - gap - height, width: w, height },\n { x: label.x - w / 2, y: label.y + gap, width: w, height },\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n if (a.axis === \"y\") {\n const py = crisp(scales.yToPx(a.value));\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(scales.xToPx(a.value));\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":"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"}