material-plus-ui 1.8.0 → 1.9.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 (125) hide show
  1. package/README.md +8 -4
  2. package/dist/a2ui/catalog.d.ts +104 -0
  3. package/dist/a2ui/catalog.js +1 -0
  4. package/dist/a2ui/components/MPA2uiAudioPlayer.d.ts +1 -0
  5. package/dist/a2ui/components/MPA2uiAudioPlayer.js +2 -0
  6. package/dist/a2ui/components/MPA2uiButton.d.ts +1 -0
  7. package/dist/a2ui/components/MPA2uiButton.js +2 -0
  8. package/dist/a2ui/components/MPA2uiCard.d.ts +1 -0
  9. package/dist/a2ui/components/MPA2uiCard.js +2 -0
  10. package/dist/a2ui/components/MPA2uiCheckBox.d.ts +1 -0
  11. package/dist/a2ui/components/MPA2uiCheckBox.js +2 -0
  12. package/dist/a2ui/components/MPA2uiChoicePicker.d.ts +1 -0
  13. package/dist/a2ui/components/MPA2uiChoicePicker.js +2 -0
  14. package/dist/a2ui/components/MPA2uiColumn.d.ts +1 -0
  15. package/dist/a2ui/components/MPA2uiColumn.js +2 -0
  16. package/dist/a2ui/components/MPA2uiDateTimeInput.d.ts +1 -0
  17. package/dist/a2ui/components/MPA2uiDateTimeInput.js +2 -0
  18. package/dist/a2ui/components/MPA2uiDivider.d.ts +1 -0
  19. package/dist/a2ui/components/MPA2uiDivider.js +2 -0
  20. package/dist/a2ui/components/MPA2uiIcon.d.ts +1 -0
  21. package/dist/a2ui/components/MPA2uiIcon.js +2 -0
  22. package/dist/a2ui/components/MPA2uiImage.d.ts +1 -0
  23. package/dist/a2ui/components/MPA2uiImage.js +2 -0
  24. package/dist/a2ui/components/MPA2uiList.d.ts +1 -0
  25. package/dist/a2ui/components/MPA2uiList.js +2 -0
  26. package/dist/a2ui/components/MPA2uiModal.d.ts +1 -0
  27. package/dist/a2ui/components/MPA2uiModal.js +2 -0
  28. package/dist/a2ui/components/MPA2uiRow.d.ts +1 -0
  29. package/dist/a2ui/components/MPA2uiRow.js +2 -0
  30. package/dist/a2ui/components/MPA2uiSlider.d.ts +1 -0
  31. package/dist/a2ui/components/MPA2uiSlider.js +2 -0
  32. package/dist/a2ui/components/MPA2uiTabs.d.ts +1 -0
  33. package/dist/a2ui/components/MPA2uiTabs.js +2 -0
  34. package/dist/a2ui/components/MPA2uiText.d.ts +1 -0
  35. package/dist/a2ui/components/MPA2uiText.js +2 -0
  36. package/dist/a2ui/components/MPA2uiTextField.d.ts +1 -0
  37. package/dist/a2ui/components/MPA2uiTextField.js +2 -0
  38. package/dist/a2ui/components/MPA2uiVideo.d.ts +1 -0
  39. package/dist/a2ui/components/MPA2uiVideo.js +2 -0
  40. package/dist/a2ui/extended/MPA2uiBarChart.d.ts +1 -0
  41. package/dist/a2ui/extended/MPA2uiBarChart.js +2 -0
  42. package/dist/a2ui/extended/MPA2uiDataTable.d.ts +1 -0
  43. package/dist/a2ui/extended/MPA2uiDataTable.js +2 -0
  44. package/dist/a2ui/extended/MPA2uiLineChart.d.ts +1 -0
  45. package/dist/a2ui/extended/MPA2uiLineChart.js +2 -0
  46. package/dist/a2ui/extended/MPA2uiPieChart.d.ts +1 -0
  47. package/dist/a2ui/extended/MPA2uiPieChart.js +2 -0
  48. package/dist/a2ui/extended/MPA2uiStatistic.d.ts +1 -0
  49. package/dist/a2ui/extended/MPA2uiStatistic.js +2 -0
  50. package/dist/a2ui/extended/api.d.ts +1436 -0
  51. package/dist/a2ui/extended/api.js +1 -0
  52. package/dist/a2ui/extended/chart.d.ts +26 -0
  53. package/dist/a2ui/extended/chart.js +1 -0
  54. package/dist/a2ui/index.d.ts +103 -0
  55. package/dist/a2ui/index.js +1 -0
  56. package/dist/a2ui/internal/children.d.ts +28 -0
  57. package/dist/a2ui/internal/children.js +1 -0
  58. package/dist/a2ui/internal/common.d.ts +113 -0
  59. package/dist/a2ui/internal/common.js +1 -0
  60. package/dist/a2ui/internal/icons.d.ts +3 -0
  61. package/dist/a2ui/internal/icons.js +1 -0
  62. package/dist/components/alert/MPAlert.d.ts +1 -1
  63. package/dist/components/animate-grow/MPAnimateGrow.d.ts +1 -1
  64. package/dist/components/animate-slide/MPAnimateSlide.d.ts +1 -1
  65. package/dist/components/animate-zoom/MPAnimateZoom.d.ts +2 -2
  66. package/dist/components/area-chart/MPAreaChart.d.ts +18 -3
  67. package/dist/components/area-chart/MPAreaChart.js +1 -1
  68. package/dist/components/avatar/MPAvatar.d.ts +1 -1
  69. package/dist/components/bar-chart/MPBarChart.d.ts +15 -5
  70. package/dist/components/bar-chart/MPBarChart.js +1 -1
  71. package/dist/components/blockquote/MPBlockquote.d.ts +1 -1
  72. package/dist/components/box/MPBox.d.ts +1 -1
  73. package/dist/components/chip/MPChip.d.ts +1 -1
  74. package/dist/components/empty/MPEmpty.d.ts +1 -1
  75. package/dist/components/heatmap-chart/MPHeatmapChart.d.ts +12 -3
  76. package/dist/components/heatmap-chart/MPHeatmapChart.js +1 -1
  77. package/dist/components/line-chart/MPLineChart.d.ts +20 -2
  78. package/dist/components/line-chart/MPLineChart.js +1 -1
  79. package/dist/components/pie-chart/MPPieChart.d.ts +23 -1
  80. package/dist/components/pie-chart/MPPieChart.js +1 -1
  81. package/dist/components/scatter-chart/MPScatterChart.d.ts +5 -1
  82. package/dist/components/sparkline/MPSparkline.d.ts +14 -1
  83. package/dist/components/sparkline/MPSparkline.js +1 -1
  84. package/dist/components/timeline-chart/MPTimelineChart.d.ts +6 -2
  85. package/dist/components/typography/MPTypography.d.ts +1 -1
  86. package/dist/internal/ChartChrome.d.ts +63 -13
  87. package/dist/internal/ChartChrome.js +1 -1
  88. package/dist/internal/ChartFrame.d.ts +24 -4
  89. package/dist/internal/ChartFrame.js +1 -1
  90. package/dist/internal/chart.d.ts +91 -3
  91. package/dist/internal/chart.js +1 -1
  92. package/dist/internal/i18n.d.ts +4 -0
  93. package/dist/internal/messages/chart.d.ts +1 -1
  94. package/dist/internal/messages/chart.js +1 -1
  95. package/dist/locales/ar.js +1 -1
  96. package/dist/locales/de.js +1 -1
  97. package/dist/locales/es.js +1 -1
  98. package/dist/locales/fr.js +1 -1
  99. package/dist/locales/hi.js +1 -1
  100. package/dist/locales/id.js +1 -1
  101. package/dist/locales/it.js +1 -1
  102. package/dist/locales/ja.js +1 -1
  103. package/dist/locales/ko.js +1 -1
  104. package/dist/locales/nl.js +1 -1
  105. package/dist/locales/pl.js +1 -1
  106. package/dist/locales/pt.js +1 -1
  107. package/dist/locales/ru.js +1 -1
  108. package/dist/locales/th.js +1 -1
  109. package/dist/locales/tr.js +1 -1
  110. package/dist/locales/vi.js +1 -1
  111. package/dist/locales/zh-hans.js +1 -1
  112. package/dist/locales/zh-hant.js +1 -1
  113. package/dist/styles/area-chart.css +1 -1
  114. package/dist/styles/bar-chart.css +1 -1
  115. package/dist/styles/gauge-chart.css +1 -1
  116. package/dist/styles/heatmap-chart.css +1 -1
  117. package/dist/styles/line-chart.css +1 -1
  118. package/dist/styles/pie-chart.css +1 -1
  119. package/dist/styles/scatter-chart.css +1 -1
  120. package/dist/styles/sparkline.css +1 -1
  121. package/dist/styles/statistic.css +1 -1
  122. package/dist/styles/timeline-chart.css +1 -1
  123. package/dist/styles.css +1 -1
  124. package/dist/types.d.ts +208 -1
  125. package/package.json +25 -4
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as t from"react";import{useMPElementSize as n}from"../../hooks/useMPElementSize.js";import{useMPLocale as a,useMPMessages as r}from"../../internal/locale.js";import{useMPSize as o}from"../../internal/config.js";import{CHART as i}from"../../internal/messages/chart.js";import{TABLE as m}from"../../internal/messages/table.js";import{ChartShell as s,ChartTable as c,ChartTooltipPanel as h}from"../../internal/ChartChrome.js";import{CHART_FONT_SIZE as u,MARK_GAP as d,PLOT_HEIGHT as f,RAMP_STEPS as p,formatCategory as x,formatStatistic as g,rampFill as v,rampInk as y,rampStep as w,textWidth as b,toValues as k,truncate as M}from"../../internal/chart.js";export function MPHeatmapChart({series:j,categories:A,xAxis:N,yAxis:S,min:$,max:_,valueLabels:z=!1,height:B,format:C,locale:P,label:D,legend:R,tooltip:L,empty:E,size:F,className:I,style:W,...H}){const K=o(F),U=a(P),X=r(i,U),Y=r(m,U),q=t.useRef(null),G=n(q),J=t.useId(),[O,Q]=t.useState(null),T=t.useMemo(()=>k(j),[j]),V=T.reduce((e,l)=>Math.max(e,l.length),0),Z=t.useCallback(e=>g(e,U,C,!0),[C,U]),ee=j.map((e,l)=>e.name??String(l+1)),le=Array.from({length:V},(e,l)=>N?.tickFormat?String(N.tickFormat(A?.[l]??l,l)):x(A?.[l]??l,U)),te=T.flat().filter(e=>null!==e.value),ne=$??(te.length>0?Math.min(...te.map(e=>e.value)):0),ae=_??(te.length>0?Math.max(...te.map(e=>e.value)):0),re=ae-ne||1,oe=u[K],ie=G.width,me="number"==typeof B?B:void 0===B?f[K]:G.height,se=ee.reduce((e,l)=>Math.max(e,b(l,oe)),0),ce=S?.hidden?0:S?.thickness??Math.min(140,se+10),he=N?.hidden?0:N?.thickness??oe+12,ue=ce,de=0,fe=Math.max(0,ie-ce),pe=Math.max(0,me-he),xe=V>0?fe/V:0,ge=T.length>0?pe/T.length:0,ve=(e,l)=>{Q(t=>{const n=t??{row:0,column:0};return{row:Math.min(T.length-1,Math.max(0,n.row+(t?e:0))),column:Math.min(V-1,Math.max(0,n.column+(t?l:0)))}})},ye=O?T[O.row]?.[O.column]??null:null,we=O&&ye&&null!==ye.value?[{seriesIndex:O.row,name:ee[O.row],color:v(w((ye.value-ne)/re)),value:ye.value,formatted:Z(ye.value),label:ye.label}]:[],be=!1===L?{mode:"none"}:!0===L||void 0===L?{}:L,ke=!1!==R&&te.length>0,Me=0===V||0===T.length||0===te.length,je=Array.from({length:V},(e,l)=>T.map(e=>e[l]??{value:null}));return e(s,{...H,size:K,className:["mp-heatmap-chart",I??""].filter(Boolean).join(" "),style:W,plotRef:q,name:D??X.label,describedBy:Me?void 0:J,interactive:!Me,height:B,legendSide:"bottom",plotProps:{onPointerMove:Me||"none"===be.mode?void 0:e=>Q(((e,l)=>{const t=q.current;if(!t||xe<=0||ge<=0)return null;const n=t.getBoundingClientRect(),a=Math.floor((e-n.left-ue)/xe),r=Math.floor((l-n.top-de)/ge);return a<0||a>=V||r<0||r>=T.length?null:{row:r,column:a}})(e.clientX,e.clientY)),onPointerLeave:()=>Q(null),onKeyDown:Me||"none"===be.mode?void 0:e=>{if("ArrowRight"===e.key)ve(0,1);else if("ArrowLeft"===e.key)ve(0,-1);else if("ArrowDown"===e.key)ve(1,0);else if("ArrowUp"===e.key)ve(-1,0);else{if("Escape"!==e.key)return;Q(null)}e.preventDefault()},onBlur:()=>Q(null)},tooltip:O&&we.length>0&&"none"!==be.mode?e(h,{heading:`${ee[O.row]} · ${le[O.column]}`,items:we,x:ue+(O.column+.5)*xe,y:de+(O.row+.5)*ge,flip:O.column>V/2,size:K}):null,legend:ke?l("div",{className:"mp-chart__legend flex items-center justify-center gap-2",children:[e("span",{className:"text-mp-on-surface-variant text-mp-label-small tabular-nums",children:Z(ne)}),e("span",{className:"flex","aria-hidden":"true",children:Array.from({length:p},(l,t)=>e("span",{className:"block h-3 w-6 first:rounded-s-mp-xs last:rounded-e-mp-xs",style:{background:v(t)}},t))}),e("span",{className:"text-mp-on-surface-variant text-mp-label-small tabular-nums",children:Z(ae)})]}):null,status:{heading:O?`${ee[O.row]} · ${le[O.column]}`:void 0,items:we},table:Me?null:e(c,{id:J,caption:D??X.table,corner:S?.label??X.category,categories:ee,names:le,values:je,format:Z,locale:U,empty:Y.empty}),children:Me?e("div",{className:"text-mp-on-surface-variant text-mp-body-small flex h-full items-center justify-center",children:E??Y.empty}):ie>0&&me>0?l("svg",{width:ie,height:me,viewBox:`0 0 ${ie} ${me}`,"aria-hidden":"true",className:"block overflow-visible",children:[e("g",{className:"mp-heatmap-chart__cells",children:T.map((t,n)=>Array.from({length:V},(a,r)=>{const o=t[r],i=O?.row===n&&O?.column===r,m=ue+r*xe,s=de+n*ge,c=Math.max(0,xe-d),h=Math.max(0,ge-d);if(!o||null===o.value)return e("rect",{x:m+d/2,y:s+d/2,width:c,height:h,fill:"none",stroke:"var(--_mp-color-outline-variant)",strokeWidth:1,strokeDasharray:"2 2",rx:2},r);const u=w((o.value-ne)/re);return l("g",{children:[e("rect",{x:m+d/2,y:s+d/2,width:c,height:h,fill:o.color??v(u),rx:2,stroke:i?"var(--_mp-color-on-surface)":"none",strokeWidth:i?2:0}),z&&c>b(Z(o.value),oe)+8&&h>oe+4?e("text",{x:m+xe/2,y:s+ge/2,textAnchor:"middle",dominantBaseline:"central",fill:y(u),fontSize:oe,children:Z(o.value)}):null]},r)}))}),S?.hidden?null:ee.map((l,t)=>e("text",{x:ue-8,y:de+(t+.5)*ge,textAnchor:"end",dominantBaseline:"central",fill:"var(--_mp-color-on-surface-variant)",fontSize:oe,children:M(l,ce-10,oe)},`r${t}`)),N?.hidden?null:le.map((l,t)=>e("text",{x:ue+(t+.5)*xe,y:de+pe+oe+4,textAnchor:"middle",fill:"var(--_mp-color-on-surface-variant)",fontSize:oe,children:M(l,xe-2,oe)},`c${t}`))]}):null})}
2
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useMPElementSize as a}from"../../hooks/useMPElementSize.js";import{useMPLocale as n,useMPMessages as r}from"../../internal/locale.js";import{useMPSize as o}from"../../internal/config.js";import{CHART as i}from"../../internal/messages/chart.js";import{TABLE as m}from"../../internal/messages/table.js";import{ChartShell as s,ChartTable as c,ChartTooltipPanel as h}from"../../internal/ChartChrome.js";import{CHART_FONT_SIZE as u,MARK_GAP as d,PLOT_HEIGHT as f,RAMP_STEPS as p,formatCategory as x,formatStatistic as g,rampFill as v,rampInk as y,rampStep as w,textWidth as M,tickTurn as b,toValues as k,truncate as j,turnedBand as A,turnedRoom as $}from"../../internal/chart.js";export function MPHeatmapChart({series:N,categories:B,xAxis:S,yAxis:_,min:z,max:P,valueLabels:C=!1,height:D,format:L,locale:R,label:I,legend:E,tooltip:F,empty:W,size:H,className:K,style:U,...X}){const Y=o(H),q=n(R),G=r(i,q),J=r(m,q),O=l.useRef(null),Q=a(O),T=l.useId(),[V,Z]=l.useState(null),ee=l.useMemo(()=>k(N),[N]),te=ee.reduce((e,t)=>Math.max(e,t.length),0),le=l.useCallback(e=>g(e,q,L,!0),[L,q]),ae=N.map((e,t)=>e.name??String(t+1)),ne=Array.from({length:te},(e,t)=>S?.tickFormat?String(S.tickFormat(B?.[t]??t,t)):x(B?.[t]??t,q)),re=ee.flat().filter(e=>null!==e.value),oe=z??(re.length>0?Math.min(...re.map(e=>e.value)):0),ie=P??(re.length>0?Math.max(...re.map(e=>e.value)):0),me=ie-oe||1,se=u[Y],ce=Q.width,he="number"==typeof D?D:void 0===D?f[Y]:Q.height,ue=ae.reduce((e,t)=>Math.max(e,M(t,se)),0),de=_?.hidden?0:_?.thickness??Math.min(140,ue+10),fe=Math.max(0,ce-de),pe=te>0?fe/te:0,xe=S?.hidden?0:b(S?.tickLabels??"auto",ne,se,pe),ge=Math.min(120,.5*he),ve=ne.map((e,t)=>j(e,xe>0?Math.min($(xe,ge,se),xe>=90?1/0:(de+pe*(t+.5))/Math.cos(xe*Math.PI/180)):pe-2,se)),ye=ve.reduce((e,t)=>Math.max(e,M(t,se)),0),we=S?.hidden?0:S?.thickness??(xe>0?8+A(xe,ye,se)+4:se+12),Me=de,be=0,ke=Math.max(0,he-we),je=ee.length>0?ke/ee.length:0,Ae=(e,t)=>{Z(l=>{const a=l??{row:0,column:0};return{row:Math.min(ee.length-1,Math.max(0,a.row+(l?e:0))),column:Math.min(te-1,Math.max(0,a.column+(l?t:0)))}})},$e=V?ee[V.row]?.[V.column]??null:null,Ne=V&&$e&&null!==$e.value?[{seriesIndex:V.row,name:ae[V.row],color:v(w(($e.value-oe)/me)),value:$e.value,formatted:le($e.value),label:$e.label}]:[],Be=!1===F?{mode:"none"}:!0===F||void 0===F?{}:F,Se=!1!==E&&re.length>0,_e=0===te||0===ee.length||0===re.length,ze=Array.from({length:te},(e,t)=>ee.map(e=>e[t]??{value:null}));return e(s,{...X,size:Y,className:["mp-heatmap-chart",K??""].filter(Boolean).join(" "),style:U,plotRef:O,name:I??G.label,describedBy:_e?void 0:T,interactive:!_e,height:D,legendSide:"bottom",plotProps:{onPointerMove:_e||"none"===Be.mode?void 0:e=>Z(((e,t)=>{const l=O.current;if(!l||pe<=0||je<=0)return null;const a=l.getBoundingClientRect(),n=Math.floor((e-a.left-Me)/pe),r=Math.floor((t-a.top-be)/je);return n<0||n>=te||r<0||r>=ee.length?null:{row:r,column:n}})(e.clientX,e.clientY)),onPointerLeave:()=>Z(null),onKeyDown:_e||"none"===Be.mode?void 0:e=>{if("ArrowRight"===e.key)Ae(0,1);else if("ArrowLeft"===e.key)Ae(0,-1);else if("ArrowDown"===e.key)Ae(1,0);else if("ArrowUp"===e.key)Ae(-1,0);else{if("Escape"!==e.key)return;Z(null)}e.preventDefault()},onBlur:()=>Z(null)},tooltip:V&&Ne.length>0&&"none"!==Be.mode?e(h,{heading:`${ae[V.row]} · ${ne[V.column]}`,items:Ne,x:Me+(V.column+.5)*pe,y:be+(V.row+.5)*je,flip:V.column>te/2,size:Y}):null,legend:Se?t("div",{className:"mp-chart__legend flex items-center justify-center gap-2",children:[e("span",{className:"text-mp-on-surface-variant text-mp-label-small tabular-nums",children:le(oe)}),e("span",{className:"flex","aria-hidden":"true",children:Array.from({length:p},(t,l)=>e("span",{className:"block h-3 w-6 first:rounded-s-mp-xs last:rounded-e-mp-xs",style:{background:v(l)}},l))}),e("span",{className:"text-mp-on-surface-variant text-mp-label-small tabular-nums",children:le(ie)})]}):null,status:{heading:V?`${ae[V.row]} · ${ne[V.column]}`:void 0,items:Ne},table:_e?null:e(c,{id:T,caption:I??G.table,corner:_?.label??G.category,categories:ae,names:ne,values:ze,format:le,locale:q,empty:J.empty}),children:_e?e("div",{className:"text-mp-on-surface-variant text-mp-body-small flex h-full items-center justify-center",children:W??J.empty}):ce>0&&he>0?t("svg",{width:ce,height:he,viewBox:`0 0 ${ce} ${he}`,"aria-hidden":"true",className:"block overflow-visible",children:[e("g",{className:"mp-heatmap-chart__cells",children:ee.map((l,a)=>Array.from({length:te},(n,r)=>{const o=l[r],i=V?.row===a&&V?.column===r,m=Me+r*pe,s=be+a*je,c=Math.max(0,pe-d),h=Math.max(0,je-d);if(!o||null===o.value)return e("rect",{x:m+d/2,y:s+d/2,width:c,height:h,fill:"none",stroke:"var(--_mp-color-outline-variant)",strokeWidth:1,strokeDasharray:"2 2",rx:2},r);const u=w((o.value-oe)/me);return t("g",{children:[e("rect",{x:m+d/2,y:s+d/2,width:c,height:h,fill:o.color??v(u),rx:2,stroke:i?"var(--_mp-color-on-surface)":"none",strokeWidth:i?2:0}),C&&c>M(le(o.value),se)+8&&h>se+4?e("text",{x:m+pe/2,y:s+je/2,textAnchor:"middle",dominantBaseline:"central",fill:y(u),fontSize:se,children:le(o.value)}):null]},r)}))}),_?.hidden?null:ae.map((t,l)=>e("text",{x:Me-8,y:be+(l+.5)*je,textAnchor:"end",dominantBaseline:"central",fill:"var(--_mp-color-on-surface-variant)",fontSize:se,children:j(t,de-10,se)},`r${l}`)),S?.hidden?null:ve.map((t,l)=>{const a=Me+(l+.5)*pe,n=be+ke;return e("text",{x:a,y:xe>0?n+8:n+se+4,textAnchor:xe>0?"end":"middle",dominantBaseline:xe>0?"central":void 0,transform:xe>0?`rotate(${-xe} ${a} ${n+8})`:void 0,fill:"var(--_mp-color-on-surface-variant)",fontSize:se,children:t},`c${l}`)})]}):null})}
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { type CartesianChartProps } from '../../internal/ChartFrame.js';
3
- import type { MPChartCurve, MPChartValueLabels } from '../../types.js';
3
+ import type { MPChartCurve, MPChartGaps, MPChartValueLabels } from '../../types.js';
4
4
  export interface MPLineChartProps extends CartesianChartProps {
5
5
  /**
6
6
  * How the line gets from one point to the next.
@@ -16,6 +16,16 @@ export interface MPLineChartProps extends CartesianChartProps {
16
16
  * @default 'auto'
17
17
  */
18
18
  markers?: boolean | 'auto';
19
+ /**
20
+ * What the line does where a series has no value.
21
+ *
22
+ * `break` stops and restarts, `connect` joins the two sides with a dashed
23
+ * run, and `zero` draws the missing reading at zero and widens the axis to
24
+ * hold it. The hover panel and the table still report a gap as a gap in all
25
+ * three.
26
+ * @default 'break'
27
+ */
28
+ gaps?: MPChartGaps;
19
29
  /**
20
30
  * Which values are written onto the line itself.
21
31
  * @default 'none'
@@ -55,6 +65,14 @@ export interface MPLineChartProps extends CartesianChartProps {
55
65
  * nobody has, and it is the one kind of invented data a reader never questions
56
66
  * — it looks exactly like the rest of the line.
57
67
  *
68
+ * `gaps` is there for the two cases where the default is the wrong reading.
69
+ * `connect` joins the two sides and draws the joining run **dashed**, so the
70
+ * line carries on and the picture still says which part of it was measured.
71
+ * `zero` draws the missing reading at zero and widens the axis to hold it,
72
+ * which is right where a gap means "none of it happened" and wrong where it
73
+ * means "nobody was counting". The table behind the chart reports a gap as a
74
+ * gap whichever is chosen.
75
+ *
58
76
  * ## The hover layer is not optional
59
77
  *
60
78
  * A chart in a browser is a thing a reader interrogates, so the crosshair and
@@ -63,4 +81,4 @@ export interface MPLineChartProps extends CartesianChartProps {
63
81
  * gridline is answering it badly. The arrow keys walk the same columns, and a
64
82
  * clipped live region says each one out loud.
65
83
  */
66
- export declare function MPLineChart({ curve, markers, valueLabels, ...frame }: MPLineChartProps): React.JSX.Element;
84
+ export declare function MPLineChart({ curve, markers, gaps, valueLabels, ...frame }: MPLineChartProps): React.JSX.Element;
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import{CartesianFrame as l}from"../../internal/ChartFrame.js";import{LINE_WIDTH as t,MARKER_RADIUS as n,linePath as a}from"../../internal/chart.js";export function MPLineChart({curve:o="linear",markers:i="auto",valueLabels:u="none",...s}){return e(l,{...s,inset:!0,includeZero:!1,headroom:"none"===u?0:14,children:({plot:l,values:s,visible:c,colors:m,point:h,size:d,hovered:f,activeIndex:p,format:x})=>{const v=t[d],k=n[d],j=s.reduce((e,r)=>Math.max(e,r.length),0),y=j>1?l.width/(j-1):l.width,g="auto"===i?y>=6*k:i;return e("g",{className:"mp-line-chart__marks",children:s.map((t,n)=>{if(!c[n])return null;const i=t.map((e,r)=>null===e.value?null:h(r,e.value)),s=m[n];return r("g",{opacity:null!==f&&f!==n?.25:1,children:[e("path",{d:a(i,o),fill:"none",stroke:s,strokeWidth:v,strokeLinecap:"round",strokeLinejoin:"round"}),i.map((r,l)=>{if(!r)return null;const t=p===l;return g||t?e("circle",{cx:r.x,cy:r.y,r:t?k+1:k,fill:s,stroke:"var(--_mp-color-surface)",strokeWidth:2},l):null}),"none"===u?null:t.map((r,n)=>{const a=i[n];if(!a||null===r.value)return null;const o=t.filter(e=>null!==e.value),s=o.map(e=>e.value);if(!("all"===u||"last"===u&&r===o[o.length-1]||"extremes"===u&&(r.value===Math.min(...s)||r.value===Math.max(...s))))return null;const c=a.x>l.left+l.width-24?"end":a.x<l.left+24?"start":"middle";return e("text",{x:a.x,y:a.y-k-5,textAnchor:c,fill:"var(--_mp-color-on-surface)",fontSize:"xs"===d||"sm"===d?10:11,children:r.label??x(r.value)},n)})]},n)})})}})}
2
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import{CartesianFrame as t}from"../../internal/ChartFrame.js";import{BRIDGE_DASH as l,LINE_WIDTH as n,MARKER_RADIUS as a,bridgePath as o,linePath as i}from"../../internal/chart.js";export function MPLineChart({curve:s="linear",markers:u="auto",gaps:c="break",valueLabels:m="none",...h}){return e(t,{...h,inset:!0,includeZero:"zero"===c,headroom:"none"===m?0:14,children:({plot:t,values:h,visible:d,colors:p,labelInk:f,point:x,size:v,hovered:k,activeIndex:j,format:y})=>{const b=n[v],g=a[v],L=h.reduce((e,r)=>Math.max(e,r.length),0),z=L>1?t.width/(L-1):t.width,M="auto"===u?z>=6*g:u;return e("g",{className:"mp-line-chart__marks",children:h.map((n,a)=>{if(!d[a])return null;const u=n.map((e,r)=>null===e.value?"zero"===c?x(r,0):null:x(r,e.value)),h=p[a];return r("g",{opacity:null!==k&&k!==a?.25:1,children:[e("path",{d:i(u,s),fill:"none",stroke:h,strokeWidth:b,strokeLinecap:"round",strokeLinejoin:"round"}),"connect"===c?e("path",{d:o(u),fill:"none",stroke:h,strokeWidth:b,strokeDasharray:`${b*l} ${b*l}`,strokeLinecap:"round"}):null,u.map((r,t)=>{if(!r)return null;const l=j===t;return M||l?e("circle",{cx:r.x,cy:r.y,r:l?g+1:g,fill:h,stroke:"var(--_mp-color-surface)",strokeWidth:2},t):null}),"none"===m?null:n.map((r,l)=>{const o=u[l];if(!o||null===r.value)return null;const i=n.filter(e=>null!==e.value),s=i.map(e=>e.value);if(!("all"===m||"last"===m&&r===i[i.length-1]||"extremes"===m&&(r.value===Math.min(...s)||r.value===Math.max(...s))))return null;const c=o.x>t.left+t.width-24?"end":o.x<t.left+24?"start":"middle";return e("text",{x:o.x,y:o.y-g-5,textAnchor:c,fill:f(a),fontSize:"xs"===v||"sm"===v?10:11,children:r.label??y(r.value)},l)})]},a)})})}})}
@@ -28,6 +28,28 @@ export interface MPPieChartProps extends ChartBaseProps {
28
28
  * @default 0
29
29
  */
30
30
  startAngle?: number;
31
+ /**
32
+ * How much of the radius the hole takes, from `0` to `0.9`.
33
+ *
34
+ * Read by `donut` and `semi` only: `pie` is the word for a shape with no hole
35
+ * in it, and a filled disc with a `hole` would be a donut under another name.
36
+ *
37
+ * Thinner than about `0.4` and the ring stops reading as a ring; past `0.8`
38
+ * the slices are a hairline and their angles stop being comparable at all.
39
+ * The default leaves a hole wide enough for a figure and a word.
40
+ * @default 0.62
41
+ */
42
+ hole?: number;
43
+ /**
44
+ * How much page shows between two slices, in pixels. `0` lets them touch.
45
+ *
46
+ * It is drawn as a stroke in the surface's colour rather than by narrowing
47
+ * each sweep, so every slice keeps the angle its share earned however wide
48
+ * the gap is set. Past about a tenth of the radius the strokes start eating
49
+ * the small slices, which is the point at which a pie is the wrong chart.
50
+ * @default 2
51
+ */
52
+ gap?: number;
31
53
  /**
32
54
  * What goes in the hole. A ring with nothing in the middle is a pie with a
33
55
  * bite taken out of it — the total, or the one figure the chart is about, is
@@ -74,4 +96,4 @@ export interface MPPieChartProps extends ChartBaseProps {
74
96
  * A chart that is refiltered or resorted keeps every category the colour it had
75
97
  * — which is the whole reason a legend is worth reading twice.
76
98
  */
77
- export declare function MPPieChart({ data, categories, shape, startAngle, center, valueLabels, height, format, locale: localeProp, label, legend, tooltip, empty, size: sizeProp, className, style, ...rest }: MPPieChartProps): React.JSX.Element;
99
+ export declare function MPPieChart({ data, categories, shape, startAngle, hole, gap, center, valueLabels, height, format, locale: localeProp, label, legend, tooltip, empty, labelColor, size: sizeProp, className, style, ...rest }: MPPieChartProps): React.JSX.Element;
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useMPElementSize as n}from"../../hooks/useMPElementSize.js";import{useMPLocale as o,useMPMessages as r}from"../../internal/locale.js";import{useMPSize as a}from"../../internal/config.js";import{numberFormatter as i}from"../../internal/intl.js";import{CHART as s}from"../../internal/messages/chart.js";import{TABLE as m}from"../../internal/messages/table.js";import{ChartLegend as c,ChartShell as h,ChartTable as u,ChartTooltipPanel as d,useVisibility as f}from"../../internal/ChartChrome.js";import{CHART_FONT_SIZE as p,MARK_GAP as v,PLOT_HEIGHT as g,arcPath as y,categoryAt as x,formatCategory as b,formatStatistic as M,polarPoint as j,seriesColor as P,toValues as k}from"../../internal/chart.js";const w={style:"percent",maximumFractionDigits:1};export function MPPieChart({data:I,categories:z,shape:A="pie",startAngle:B=0,center:N,valueLabels:C="none",height:D,format:L,locale:R,label:S,legend:$,tooltip:_,empty:E,size:F,className:K,style:O,...U}){const W=a(F),X=o(R),Y=r(s,X),q=r(m,X),G=l.useRef(null),H=n(G),J=l.useId(),Q=l.useMemo(()=>k([{data:I}])[0],[I]),T=f(l.useMemo(()=>Q.map(()=>({})),[Q])),[V,Z]=l.useState(null),ee=l.useCallback(e=>M(e,X,L,!0),[L,X]),te=l.useMemo(()=>Q.map((e,t)=>b(x(t,z,[Q]),X)),[Q,z,X]),le=l.useMemo(()=>Q.map((e,t)=>e.color??P(t,void 0)),[Q]),ne=Q.map((e,t)=>T.visible[t]&&null!==e.value&&e.value>0?e.value:0),oe=ne.reduce((e,t)=>e+t,0),re=H.width,ae="number"==typeof D?D:void 0===D?g[W]:H.height,ie=p[W],se="semi"===A,me=re/2,ce=se?ae-ie-4:ae/2,he=Math.max(0,se?Math.min(re/2,ae-ie-8)-2:Math.min(re,ae)/2-2),ue="pie"===A?0:.62*he,de=se?Math.PI:2*Math.PI;let fe=se?-Math.PI/2:B*Math.PI/180;const pe=ne.map(e=>{const t=fe;return fe+=oe>0?e/oe*de:0,{from:t,to:fe,share:e}}),ve=e=>{const t=pe.map((e,t)=>e.share>0?t:-1).filter(e=>e>=0);if(0===t.length)return;const l=null===V?e>0?-1:0:t.indexOf(V);Z(t[(l+e+t.length)%t.length])},ge=e=>oe>0?i(X,w).format(e/oe):"",ye=null===V?null:pe[V],xe=ye&&ye.share>0?[{seriesIndex:V,color:le[V],value:ye.share,formatted:`${ee(ye.share)} · ${ge(ye.share)}`,label:Q[V]?.label}]:[],be=ye&&ye.share>0?te[V]:void 0,Me=ye?j(me,ce,.75*he,(ye.from+ye.to)/2):null,je=!1===_?{mode:"none"}:!0===_||void 0===_?{}:_,Pe=!1===$?{interactive:!1}:!0===$||void 0===$?{}:$,ke=!1!==$&&Q.length>1,we=oe<=0,Ie=[Q];return t(h,{...U,size:W,className:["mp-pie-chart",K??""].filter(Boolean).join(" "),style:O,plotRef:G,name:S??Y.label,describedBy:we?void 0:J,interactive:!we,height:D,legendSide:Pe.side??"bottom",plotProps:{onPointerMove:we||"none"===je.mode?void 0:e=>Z(((e,t)=>{const l=G.current;if(!l||oe<=0)return null;const n=l.getBoundingClientRect(),o=e-n.left-me,r=t-n.top-ce,a=Math.hypot(o,r);if(a>he+8||a<ue)return null;const i=Math.atan2(o,-r),s=pe.findIndex(({from:e,to:t,share:l})=>!(l<=0)&&(i-e+4*Math.PI)%(2*Math.PI)<t-e);return-1===s?null:s})(e.clientX,e.clientY)),onPointerLeave:()=>Z(null),onKeyDown:we||"none"===je.mode?void 0:e=>{if("ArrowRight"===e.key||"ArrowDown"===e.key)ve(1);else if("ArrowLeft"===e.key||"ArrowUp"===e.key)ve(-1);else{if("Escape"!==e.key)return;Z(null)}e.preventDefault()},onBlur:()=>Z(null)},tooltip:Me&&xe.length>0&&"none"!==je.mode?e(d,{heading:be,items:xe,x:Me.x,y:Me.y,flip:Me.x>me,size:W}):null,legend:ke?e(c,{names:te,colors:le,options:Pe,visibility:T,size:W}):null,status:{heading:be,items:xe},table:we?null:e(u,{id:J,caption:S??Y.table,corner:Y.category,categories:te,names:[S??Y.table],values:Ie,format:ee,locale:X,empty:q.empty}),children:[we?e("div",{className:"text-mp-on-surface-variant text-mp-body-small flex h-full items-center justify-center",children:E??q.empty}):re>0&&ae>0?e("svg",{width:re,height:ae,viewBox:`0 0 ${re} ${ae}`,"aria-hidden":"true",className:"block overflow-visible",children:t("g",{className:"mp-pie-chart__slices",children:[pe.map((t,l)=>{if(t.share<=0)return null;return e("path",{d:y(me,ce,V===l?he+3:he,ue,t.from,t.to),fill:le[l],stroke:"var(--_mp-color-surface)",strokeWidth:v,strokeLinejoin:"round",opacity:null===T.hovered||T.hovered===l?1:.35},l)}),"all"===C?pe.map((t,l)=>{const n=ge(t.share),o=t.to-t.from,r=j(me,ce,ue>0?(he+ue)/2:.68*he,(t.from+t.to)/2),a=o*(ue>0?(he+ue)/2:.68*he);return t.share<=0||a<n.length*ie*.6+8?null:e("text",{x:r.x,y:r.y,textAnchor:"middle",dominantBaseline:"central",fill:"var(--_mp-color-on-surface)",fontSize:ie,children:n},l)}):null]})}):null,null==N||"pie"===A||we?null:e("div",{className:"pointer-events-none absolute flex flex-col items-center justify-center text-center",style:{left:me-ue,top:ce-ue,width:2*ue,height:se?ue:2*ue},children:N})]})}
2
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useMPElementSize as n}from"../../hooks/useMPElementSize.js";import{useMPLocale as o,useMPMessages as r}from"../../internal/locale.js";import{useMPSize as a}from"../../internal/config.js";import{numberFormatter as i}from"../../internal/intl.js";import{CHART as s}from"../../internal/messages/chart.js";import{TABLE as m}from"../../internal/messages/table.js";import{ChartLegend as c,ChartShell as h,ChartTable as u,ChartTooltipPanel as p,useVisibility as d}from"../../internal/ChartChrome.js";import{CHART_FONT_SIZE as f,MARK_GAP as v,PLOT_HEIGHT as g,arcPath as y,categoryAt as x,formatCategory as M,formatStatistic as b,polarPoint as j,seriesColor as k,toValues as P}from"../../internal/chart.js";const w={style:"percent",maximumFractionDigits:1};export function MPPieChart({data:I,categories:N,shape:z="pie",startAngle:A=0,hole:B=.62,gap:C=v,center:D,valueLabels:L="none",height:R,format:S,locale:$,label:_,legend:E,tooltip:F,empty:K,labelColor:O="ink",size:U,className:W,style:X,...Y}){const q=a(U),G=o($),H=r(s,G),J=r(m,G),Q=l.useRef(null),T=n(Q),V=l.useId(),Z=l.useMemo(()=>P([{data:I}])[0],[I]),ee=d(l.useMemo(()=>Z.map(()=>({})),[Z])),[te,le]=l.useState(null),ne=l.useCallback(e=>b(e,G,S,!0),[S,G]),oe=l.useMemo(()=>Z.map((e,t)=>M(x(t,N,[Z]),G)),[Z,N,G]),re=l.useMemo(()=>Z.map((e,t)=>e.color??k(t,void 0)),[Z]),ae=Z.map((e,t)=>ee.visible[t]&&null!==e.value&&e.value>0?e.value:0),ie=ae.reduce((e,t)=>e+t,0),se=T.width,me="number"==typeof R?R:void 0===R?g[q]:T.height,ce=f[q],he="semi"===z,ue=se/2,pe=he?me-ce-4:me/2,de=Math.max(0,he?Math.min(se/2,me-ce-8)-2:Math.min(se,me)/2-2),fe="pie"===z?0:de*Math.min(.9,Math.max(0,B)),ve=he?Math.PI:2*Math.PI;let ge=he?-Math.PI/2:A*Math.PI/180;const ye=ae.map(e=>{const t=ge;return ge+=ie>0?e/ie*ve:0,{from:t,to:ge,share:e}}),xe=e=>{const t=ye.map((e,t)=>e.share>0?t:-1).filter(e=>e>=0);if(0===t.length)return;const l=null===te?e>0?-1:0:t.indexOf(te);le(t[(l+e+t.length)%t.length])},Me=e=>ie>0?i(G,w).format(e/ie):"",be=null===te?null:ye[te],je=be&&be.share>0?[{seriesIndex:te,color:re[te],value:be.share,formatted:`${ne(be.share)} · ${Me(be.share)}`,label:Z[te]?.label}]:[],ke=be&&be.share>0?oe[te]:void 0,Pe=be?j(ue,pe,.75*de,(be.from+be.to)/2):null,we=!1===F?{mode:"none"}:!0===F||void 0===F?{}:F,Ie=!1===E?{interactive:!1}:!0===E||void 0===E?{}:E,Ne=!1!==E&&Z.length>1,ze=ie<=0,Ae=[Z];return t(h,{...Y,size:q,className:["mp-pie-chart",W??""].filter(Boolean).join(" "),style:X,plotRef:Q,name:_??H.label,describedBy:ze?void 0:V,interactive:!ze,height:R,legendSide:Ie.side??"bottom",plotProps:{onPointerMove:ze||"none"===we.mode?void 0:e=>le(((e,t)=>{const l=Q.current;if(!l||ie<=0)return null;const n=l.getBoundingClientRect(),o=e-n.left-ue,r=t-n.top-pe,a=Math.hypot(o,r);if(a>de+8||a<fe)return null;const i=Math.atan2(o,-r),s=ye.findIndex(({from:e,to:t,share:l})=>!(l<=0)&&(i-e+4*Math.PI)%(2*Math.PI)<t-e);return-1===s?null:s})(e.clientX,e.clientY)),onPointerLeave:()=>le(null),onKeyDown:ze||"none"===we.mode?void 0:e=>{if("ArrowRight"===e.key||"ArrowDown"===e.key)xe(1);else if("ArrowLeft"===e.key||"ArrowUp"===e.key)xe(-1);else{if("Escape"!==e.key)return;le(null)}e.preventDefault()},onBlur:()=>le(null)},tooltip:Pe&&je.length>0&&"none"!==we.mode?e(p,{heading:ke,items:je,x:Pe.x,y:Pe.y,flip:Pe.x>ue,size:q}):null,legend:Ne?e(c,{names:oe,colors:re,options:Ie,visibility:ee,size:q,colorNames:"series"===O}):null,status:{heading:ke,items:je},table:ze?null:e(u,{id:V,caption:_??H.table,corner:H.category,categories:oe,names:[_??H.table],values:Ae,format:ne,locale:G,empty:J.empty}),children:[ze?e("div",{className:"text-mp-on-surface-variant text-mp-body-small flex h-full items-center justify-center",children:K??J.empty}):se>0&&me>0?e("svg",{width:se,height:me,viewBox:`0 0 ${se} ${me}`,"aria-hidden":"true",className:"block overflow-visible",children:t("g",{className:"mp-pie-chart__slices",children:[ye.map((t,l)=>{if(t.share<=0)return null;return e("path",{d:y(ue,pe,te===l?de+3:de,fe,t.from,t.to),fill:re[l],stroke:"var(--_mp-color-surface)",strokeWidth:Math.max(0,C),strokeLinejoin:"round",opacity:null===ee.hovered||ee.hovered===l?1:.35},l)}),"all"===L?ye.map((t,l)=>{const n=Me(t.share),o=t.to-t.from,r=j(ue,pe,fe>0?(de+fe)/2:.68*de,(t.from+t.to)/2),a=o*(fe>0?(de+fe)/2:.68*de);return t.share<=0||a<n.length*ce*.6+8?null:e("text",{x:r.x,y:r.y,textAnchor:"middle",dominantBaseline:"central",fill:"var(--_mp-color-on-surface)",fontSize:ce,children:n},l)}):null]})}):null,null==D||"pie"===z||ze?null:e("div",{className:"pointer-events-none absolute flex flex-col items-center justify-center text-center",style:{left:ue-fe,top:pe-fe,width:2*fe,height:he?fe:2*fe},children:D})]})}
@@ -1,6 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { type CartesianChartProps } from '../../internal/ChartFrame.js';
3
- export interface MPScatterChartProps extends CartesianChartProps {
3
+ /**
4
+ * No `zoom`: what a drag would cut is a row of category slots, and a scatter
5
+ * has two value axes and no row. Crop it with `xAxis` and `yAxis` instead.
6
+ */
7
+ export interface MPScatterChartProps extends Omit<CartesianChartProps, 'zoom'> {
4
8
  /**
5
9
  * Sizes each mark by its point's `z`, so a third number rides along.
6
10
  *
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type { MPChartCurve, MPColor, MPSize } from '../../types.js';
2
+ import type { MPChartCurve, MPChartGaps, MPColor, MPSize } from '../../types.js';
3
3
  /** What the series is drawn as. */
4
4
  export type MPSparklineShape = 'line' | 'area' | 'bar';
5
5
  export interface MPSparklineProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'children'> {
@@ -12,6 +12,19 @@ export interface MPSparklineProps extends Omit<React.ComponentPropsWithoutRef<'d
12
12
  shape?: MPSparklineShape;
13
13
  /** How the line between two points is drawn. @default 'linear' */
14
14
  curve?: MPChartCurve;
15
+ /**
16
+ * What the shape does where the series has no value.
17
+ *
18
+ * `break` stops and starts again, `connect` joins the two sides with a dashed
19
+ * run, and `zero` reads the missing point as a zero and opens the scale to
20
+ * hold it. The sentence this mark is read out as counts the readings it
21
+ * actually has, whichever is chosen.
22
+ *
23
+ * `bar` has no line to join, so it takes `zero` and reads `connect` as
24
+ * `break`.
25
+ * @default 'break'
26
+ */
27
+ gaps?: MPChartGaps;
15
28
  /**
16
29
  * Marks the newest point.
17
30
  *
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{numberFormatter as i}from"../../internal/intl.js";import{useMPLocale as l,useMPMessages as o}from"../../internal/locale.js";import{useMPSize as a}from"../../internal/config.js";import{fillMessage as s}from"../../internal/i18n.js";import{SPARKLINE as m}from"../../internal/messages/sparkline.js";import{TABLE as c}from"../../internal/messages/table.js";import{cssLength as p}from"../../internal/length.js";import{areaPath as f,barPath as h,extentOf as u,linePath as d,seriesColor as g}from"../../internal/chart.js";const b={xs:16,sm:24,md:32,lg:44,xl:56},k={xs:1.25,sm:1.5,md:2,lg:2.5,xl:3};export const MPSparkline=/*@__PURE__*/n.forwardRef(function({data:x,shape:j="line",curve:y="linear",endDot:v=!0,baseline:w,min:M,max:N,width:F="100%",height:L,color:$,label:z,locale:B,size:E,className:R,style:W,...A},D){const P=a(E),S=l(B),q=o(m,S),C=o(c,S),G=L??b[P],H=k[P],I=g(0,$),J=100,K=G,O="bar"===j?0:H/2,Q=u(x,M,N),T=Q.max-Q.min,U=e=>K-O-(e-Q.min)/T*(K-2*O),V=x.length>1?J/(x.length-1):0,X=x.map((e,t)=>null!==e&&Number.isFinite(e)?{x:x.length>1?t*V:50,y:U(e)}:null),Y=w??Q.min,Z=[...X].reverse().find(e=>null!==e)??null,_=n.useMemo(()=>{if(void 0!==z)return z;const e=x.filter(e=>null!==e&&Number.isFinite(e));if(0===e.length)return C.empty;const t=i(S);return s(q.summary,{count:t.format(e.length),first:t.format(e[0]),last:t.format(e[e.length-1])})},[z,x,S,q.summary,C.empty]);return e("div",{ref:D,"data-mp-size":P,className:["mp-sparkline block",R??""].filter(Boolean).join(" "),style:{width:p(F),...W},...A,children:r("svg",{role:"img","aria-label":_,viewBox:`0 0 100 ${K}`,preserveAspectRatio:"none",width:"100%",height:G,style:{display:"block",overflow:"visible"},children:["bar"===j?x.map((t,r)=>{if(null===t||!Number.isFinite(t))return null;const n=J/x.length,i=Math.max(.5,n-2),l=U(Y),o=U(t);return e("path",{d:h(r*n+(n-i)/2,Math.min(o,l),i,Math.abs(l-o),i/3,t>=Y?"top":"bottom"),fill:I,opacity:v&&r===x.length-1?1:.55},r)}):r(t,{children:["area"===j?e("path",{d:f(X,U(Y),y),fill:I,opacity:.16}):null,e("path",{d:d(X,y),fill:"none",stroke:I,strokeWidth:H,strokeLinecap:"round",strokeLinejoin:"round",vectorEffect:"non-scaling-stroke",opacity:.55})]}),v&&Z&&"bar"!==j?e("path",{d:`M${Z.x} ${Z.y}h0`,stroke:I,strokeWidth:2.5*H,strokeLinecap:"round",vectorEffect:"non-scaling-stroke"}):null]})})});
2
+ import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{numberFormatter as i}from"../../internal/intl.js";import{useMPLocale as l,useMPMessages as o}from"../../internal/locale.js";import{useMPSize as a}from"../../internal/config.js";import{fillMessage as s}from"../../internal/i18n.js";import{SPARKLINE as m}from"../../internal/messages/sparkline.js";import{TABLE as c}from"../../internal/messages/table.js";import{cssLength as p}from"../../internal/length.js";import{BRIDGE_DASH as f,areaPath as h,barPath as u,bridgePath as d,extentOf as g,linePath as k,seriesColor as b,withoutGaps as y}from"../../internal/chart.js";const x={xs:16,sm:24,md:32,lg:44,xl:56},j={xs:1.25,sm:1.5,md:2,lg:2.5,xl:3};export const MPSparkline=/*@__PURE__*/n.forwardRef(function({data:v,shape:w="line",curve:M="linear",gaps:N="break",endDot:F=!0,baseline:$,min:L,max:z,width:E="100%",height:W,color:B,label:D,locale:R,size:A,className:P,style:S,...q},C){const G=a(A),H=l(R),I=o(m,H),J=o(c,H),K=W??x[G],O=j[G],Q=b(0,B),T=100,U=K,V="bar"===w?0:O/2,X="zero"===N?v.map(e=>null!==e&&Number.isFinite(e)?e:0):v,Y=g(X,L,z),Z=Y.max-Y.min,_=e=>U-V-(e-Y.min)/Z*(U-2*V),ee=v.length>1?T/(v.length-1):0,te=X.map((e,t)=>null!==e&&Number.isFinite(e)?{x:v.length>1?t*ee:50,y:_(e)}:null),re="connect"===N&&"bar"!==w,ne=$??Y.min,ie=[...te].reverse().find(e=>null!==e)??null,le=n.useMemo(()=>{if(void 0!==D)return D;const e=v.filter(e=>null!==e&&Number.isFinite(e));if(0===e.length)return J.empty;const t=i(H);return s(I.summary,{count:t.format(e.length),first:t.format(e[0]),last:t.format(e[e.length-1])})},[D,v,H,I.summary,J.empty]);return e("div",{ref:C,"data-mp-size":G,className:["mp-sparkline block",P??""].filter(Boolean).join(" "),style:{width:p(E),...S},...q,children:r("svg",{role:"img","aria-label":le,viewBox:`0 0 100 ${U}`,preserveAspectRatio:"none",width:"100%",height:K,style:{display:"block",overflow:"visible"},children:["bar"===w?X.map((t,r)=>{if(null===t||!Number.isFinite(t))return null;const n=T/v.length,i=Math.max(.5,n-2),l=_(ne),o=_(t);return e("path",{d:u(r*n+(n-i)/2,Math.min(o,l),i,Math.abs(l-o),i/3,t>=ne?"top":"bottom"),fill:Q,opacity:F&&r===v.length-1?1:.55},r)}):r(t,{children:["area"===w?e("path",{d:h(re?y(te):te,_(ne),M),fill:Q,opacity:.16}):null,e("path",{d:k(te,M),fill:"none",stroke:Q,strokeWidth:O,strokeLinecap:"round",strokeLinejoin:"round",vectorEffect:"non-scaling-stroke",opacity:.55}),re?e("path",{d:d(te),fill:"none",stroke:Q,strokeWidth:O,strokeDasharray:`${O*f} ${O*f}`,strokeLinecap:"round",vectorEffect:"non-scaling-stroke",opacity:.55}):null]}),F&&ie&&"bar"!==w?e("path",{d:`M${ie.x} ${ie.y}h0`,stroke:Q,strokeWidth:2.5*O,strokeLinecap:"round",vectorEffect:"non-scaling-stroke"}):null]})})});
@@ -1,8 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { type ChartBaseProps } from '../../internal/ChartChrome.js';
3
3
  import type { MPChartAxis, MPTimelineSeries } from '../../types.js';
4
- /** No `legend`: the rows are the axis, so there is nothing for one to identify. */
5
- export interface MPTimelineChartProps extends Omit<ChartBaseProps, 'legend'> {
4
+ /**
5
+ * No `legend`: the rows are the axis, so there is nothing for one to identify.
6
+ * No `labelColor` either — with no legend to ink, the only text left is a span's
7
+ * own label, and that is written **on** the bar rather than beside it.
8
+ */
9
+ export interface MPTimelineChartProps extends Omit<ChartBaseProps, 'legend' | 'labelColor'> {
6
10
  /** The rows, top to bottom. Each carries its own spans. */
7
11
  series: readonly MPTimelineSeries[];
8
12
  /** The row axis. */
@@ -83,7 +83,7 @@ export interface MPTypographyProps extends Omit<React.ComponentPropsWithoutRef<'
83
83
  * `transition="fade"` is the whole of what most callers want; the object form
84
84
  * takes a duration, an edge to come from, or a scale to start at. Anything
85
85
  * that has to run again — on scroll, on hover, under your own control — is an
86
- * [MPAnimateFade](../motion/animate-fade) and its siblings.
86
+ * [MPAnimateFade](../transitions/animate-fade) and its siblings.
87
87
  */
88
88
  transition?: MPTransition;
89
89
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { type ChartValue } from './chart.js';
3
- import type { MPChartCategory, MPChartLegend, MPChartTooltip, MPChartTooltipItem, MPSide, MPSize } from '../types.js';
3
+ import type { MPChartCategory, MPChartLabelColor, MPChartLegend, MPChartTooltip, MPChartTooltipItem, MPSide, MPSize } from '../types.js';
4
4
  /**
5
5
  * Everything a chart draws that is not the data.
6
6
  *
@@ -52,6 +52,22 @@ export interface ChartBaseProps extends Omit<React.ComponentPropsWithoutRef<'div
52
52
  tooltip?: boolean | MPChartTooltip;
53
53
  /** What to draw when there is nothing to draw. */
54
54
  empty?: React.ReactNode;
55
+ /**
56
+ * What ink the text naming a series is written in — the legend's entries, and
57
+ * the values written onto the marks.
58
+ *
59
+ * `'series'` matches each name to the mark it names, which is the fastest way
60
+ * to pair a long legend with a crowded plot. It is not the default because it
61
+ * is a trade: the eight chart slots are fitted to 3:1 against the surface,
62
+ * which is the bar for a *mark*, and small text wants 4.5:1. Reach for it on
63
+ * a chart whose legend is doing real work, and leave it alone where the
64
+ * swatch beside the name is already enough.
65
+ *
66
+ * Labels drawn **on** a fill — a pie's shares, a heatmap's cells — ignore it
67
+ * and keep the ink that reads against what they sit on.
68
+ * @default 'ink'
69
+ */
70
+ labelColor?: MPChartLabelColor;
55
71
  /** @default 'md' */
56
72
  size?: MPSize;
57
73
  }
@@ -88,24 +104,39 @@ interface LegendProps {
88
104
  size: MPSize;
89
105
  values?: readonly (string | undefined)[];
90
106
  swatch?: (index: number, color: string) => React.ReactNode;
107
+ /** Writes each name in its own series' colour rather than in ordinary ink. */
108
+ colorNames?: boolean;
91
109
  }
92
110
  /**
93
111
  * The identity channel that does not depend on being able to see a colour.
94
112
  *
95
- * A swatch and a word, and the swatch is the only thing on the row wearing the
96
- * series' colour — the name beside it stays in ordinary ink. That is the rule
97
- * for every piece of text in a chart: a label written in the mark's colour is a
98
- * label the reader has to decode before they can read it, and it fails outright
99
- * in forced colours.
113
+ * A swatch and a word. The swatch carries the series' colour and the name
114
+ * beside it stays in ordinary ink, because a label written in the mark's colour
115
+ * is one more thing between the reader and the word — `colorNames` is the
116
+ * caller saying they want that trade anyway, and it is off unless they do.
100
117
  *
101
118
  * Interactive by default, and each entry is a real `<button>` with
102
119
  * `aria-pressed`. A legend that filters is a control, and a control that is a
103
120
  * `<div>` with an `onClick` is one a keyboard cannot reach.
121
+ *
122
+ * ## Off and quiet are two states, and they look different
123
+ *
124
+ * A series the reader has switched off is drawn at Material's disabled
125
+ * opacity — swatch and name together, the same treatment a disabled control
126
+ * gets, because that is what it is. A series merely standing back while another
127
+ * is hovered is quieter than usual and no more, so the two cannot be mistaken
128
+ * for each other at a glance. Opacity survives greyscale and forced colours,
129
+ * which a change of hue would not, and `aria-pressed` carries the same fact to
130
+ * a reader who is not looking at all.
104
131
  */
105
- export declare function ChartLegend({ names, colors, options, visibility, size, values, swatch }: LegendProps): React.JSX.Element;
132
+ export declare function ChartLegend({ names, colors, options, visibility, size, values, swatch, colorNames }: LegendProps): React.JSX.Element;
106
133
  interface PanelProps {
107
134
  heading?: React.ReactNode;
108
135
  items: readonly MPChartTooltipItem[];
136
+ /** What the rows add up to, where the chart is a picture of that sum. */
137
+ total?: string;
138
+ /** And what that row is called, in the chart's own language. */
139
+ totalLabel?: string;
109
140
  x: number;
110
141
  y: number;
111
142
  flip: boolean;
@@ -118,7 +149,7 @@ interface PanelProps {
118
149
  * would sit under the pointer, take the hover from the plot, and close itself —
119
150
  * then reopen, then close, for as long as the reader held still.
120
151
  */
121
- export declare function ChartTooltipPanel({ heading, items, x, y, flip, size }: PanelProps): React.JSX.Element;
152
+ export declare function ChartTooltipPanel({ heading, items, total, totalLabel, x, y, flip, size }: PanelProps): React.JSX.Element;
122
153
  /**
123
154
  * The same reading, said out loud instead of drawn.
124
155
  *
@@ -132,9 +163,11 @@ export declare function ChartTooltipPanel({ heading, items, x, y, flip, size }:
132
163
  * Empty when nothing is active, so leaving the chart clears what was said
133
164
  * rather than leaving the last column standing in the region forever.
134
165
  */
135
- export declare function ChartStatus({ heading, items }: {
166
+ export declare function ChartStatus({ heading, items, total, totalLabel }: {
136
167
  heading?: React.ReactNode;
137
168
  items: readonly MPChartTooltipItem[];
169
+ total?: string;
170
+ totalLabel?: string;
138
171
  }): React.JSX.Element;
139
172
  interface TableProps {
140
173
  id: string;
@@ -178,11 +211,22 @@ export interface ChartShellProps extends Omit<React.ComponentPropsWithoutRef<'di
178
211
  children: React.ReactNode;
179
212
  /** Floated over the drawing. */
180
213
  tooltip?: React.ReactNode;
214
+ /**
215
+ * A control over the corner of the plot — the one thing a chart has that is
216
+ * neither the picture nor a legend entry.
217
+ *
218
+ * A **sibling** of the plot rather than a child, for the reason the readout
219
+ * is one: `role="img"` is a leaf role, and a button inside it is a button no
220
+ * keyboard can reach and no screen reader can find.
221
+ */
222
+ overlay?: React.ReactNode;
181
223
  legend?: React.ReactNode;
182
224
  legendSide?: MPSide;
183
225
  status: {
184
226
  heading?: React.ReactNode;
185
227
  items: readonly MPChartTooltipItem[];
228
+ total?: string;
229
+ totalLabel?: string;
186
230
  };
187
231
  table?: React.ReactNode;
188
232
  }
@@ -191,9 +235,15 @@ export interface ChartShellProps extends Omit<React.ComponentPropsWithoutRef<'di
191
235
  * it and the table underneath.
192
236
  *
193
237
  * The readout is a **sibling** of the plot rather than a child, and that is a
194
- * constraint rather than a layout preference — see `ChartStatus`. Putting the
195
- * arrangement here is what keeps the two frames from disagreeing about it: the
196
- * one place this is easy to get wrong is the one place it must not be.
238
+ * constraint rather than a layout preference — see `ChartStatus`. So is
239
+ * anything in `overlay`, for the same reason. Putting the arrangement here is
240
+ * what keeps the two frames from disagreeing about it: the one place this is
241
+ * easy to get wrong is the one place it must not be.
242
+ *
243
+ * The plot sits in a positioning box of its own rather than directly in the
244
+ * row. The box is always there, zoomed or not — a wrapper that came and went
245
+ * would unmount the plot with it, and a plot that unmounts takes the reader's
246
+ * focus with it.
197
247
  */
198
- export declare function ChartShell({ size, plotRef, name, describedBy, interactive, height, plotProps, children, tooltip, legend, legendSide, status, table, className, ...rest }: ChartShellProps): React.JSX.Element;
248
+ export declare function ChartShell({ size, plotRef, name, describedBy, interactive, height, plotProps, children, tooltip, overlay, legend, legendSide, status, table, className, ...rest }: ChartShellProps): React.JSX.Element;
199
249
  export {};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,Fragment as t,jsxs as l}from"react/jsx-runtime";import*as n from"react";import{VISUALLY_HIDDEN as a}from"./visually-hidden.js";import{cssLength as r}from"./length.js";import{PLOT_HEIGHT as i,formatCategory as s}from"./chart.js";export function useVisibility(e){const[t,l]=n.useState(()=>{const t=new Set;return e.forEach((e,l)=>{e.hidden&&t.add(l)}),t}),[a,r]=n.useState(null),i=n.useCallback(e=>{l(t=>{const l=new Set(t);return l.has(e)?l.delete(e):l.add(e),l})},[]);return{visible:e.map((e,l)=>!t.has(l)),hovered:a,toggle:i,setHovered:r}}const o={top:"flex-col-reverse",bottom:"flex-col",left:"flex-row-reverse",right:"flex-row"},c={start:"justify-start",center:"justify-center",end:"justify-end"};export function ChartLegend({names:n,colors:a,options:r,visibility:i,size:s,values:o,swatch:m}){const d=!1!==r.interactive,p="xs"===s||"sm"===s?"text-mp-label-small":"text-mp-label-medium";return e("ul",{className:["mp-chart__legend m-0 flex list-none flex-wrap items-center gap-x-4 gap-y-1 p-0",c[r.align??"center"],p].join(" "),children:n.map((n,r)=>{const s=i.visible[r],c=!s||null!==i.hovered&&i.hovered!==r,p=n??`${r+1}`,u=l(t,{children:[e("span",{className:"shrink-0","aria-hidden":"true",children:m?m(r,a[r]):e("span",{className:"block size-2.5 rounded-mp-full",style:{background:a[r]}})}),e("span",{className:"text-mp-on-surface-variant truncate",children:p}),o?.[r]?e("span",{className:"text-mp-on-surface tabular-nums",children:o[r]}):null]});return e("li",{className:"min-w-0",children:d?e("button",{type:"button","aria-pressed":s,onClick:()=>i.toggle(r),onPointerEnter:()=>i.setHovered(r),onPointerLeave:()=>i.setHovered(null),onFocus:()=>i.setHovered(r),onBlur:()=>i.setHovered(null),className:["flex min-w-0 cursor-pointer items-center gap-1.5 rounded-mp-xs","appearance-none border-0 bg-transparent p-0 text-inherit [font:inherit]","focus-visible:outline-mp-primary focus-visible:outline-2 focus-visible:outline-offset-2",c?"opacity-40":"",s?"":"line-through"].filter(Boolean).join(" "),children:u}):e("span",{className:"flex min-w-0 items-center gap-1.5 "+(c?"opacity-40":""),children:u})},r)})})}export function ChartTooltipPanel({heading:t,items:n,x:a,y:r,flip:i,size:s}){return l("div",{"aria-hidden":"true",className:["mp-chart__tooltip pointer-events-none absolute z-10 min-w-24 max-w-64","bg-mp-surface-container-high shadow-mp-2 rounded-mp-xs px-2.5 py-2","xs"===s||"sm"===s?"text-mp-label-small":"text-mp-label-medium"].join(" "),style:{left:a,top:r,transform:`translate(${i?"calc(-100% - 12px)":"12px"}, -50%)`},children:[null==t||""===t?null:e("div",{className:"text-mp-on-surface-variant mb-1 truncate",children:t}),e("ul",{className:"m-0 flex list-none flex-col gap-0.5 p-0",children:n.map(t=>l("li",{className:"flex items-center gap-1.5",children:[e("span",{"aria-hidden":"true",className:"block size-2 shrink-0 rounded-mp-full",style:{background:t.color}}),t.name?e("span",{className:"text-mp-on-surface-variant min-w-0 truncate",children:t.name}):null,e("span",{className:"text-mp-on-surface ms-auto ps-2 tabular-nums",children:t.label??t.formatted})]},t.seriesIndex))})]})}export function ChartStatus({heading:r,items:i}){return e("span",{role:"status","aria-live":"polite",className:a,children:0===i.length?null:l(t,{children:[null==r||""===r?null:l(t,{children:[r,", "]}),i.map((e,t)=>l(n.Fragment,{children:[t>0?", ":null,e.name?`${e.name}: `:null,e.label??e.formatted]},e.seriesIndex))]})})}export function ChartTable({id:t,caption:n,corner:r,categories:i,names:o,values:c,format:m,locale:d,empty:p}){return e("div",{id:t,className:a,children:l("table",{children:[e("caption",{children:n}),e("thead",{children:l("tr",{children:[e("th",{scope:"col",children:r}),o.map((t,l)=>e("th",{scope:"col",children:t??l+1},l))]})}),e("tbody",{children:0===i.length?e("tr",{children:e("td",{colSpan:o.length+1,children:p})}):i.map((t,n)=>l("tr",{children:[e("th",{scope:"row",children:s(t,d)}),o.map((t,l)=>{const a=c[l]?.[n];return e("td",{children:a?.label??(null===a?.value||void 0===a?p:m(a.value))},l)})]},n))})]})})}export function ChartShell({size:t,plotRef:n,name:a,describedBy:s,interactive:c,height:m,plotProps:d,children:p,tooltip:u,legend:h,legendSide:f="bottom",status:x,table:b,className:v,...g}){return l("div",{"data-mp-size":t,className:["mp-chart flex min-w-0 flex-col gap-3",v??""].filter(Boolean).join(" "),...g,children:[l("div",{className:`flex min-w-0 gap-3 ${o[f]}`,children:[l("div",{ref:n,role:"img",tabIndex:c?0:void 0,"aria-label":a,"aria-describedby":s,...d,className:["mp-chart__plot rounded-mp-xs relative min-w-0 flex-1","focus-visible:outline-mp-primary focus-visible:outline-2 focus-visible:outline-offset-2"].join(" "),style:{height:r(m)??i[t]},children:[p,u]}),h]}),e(ChartStatus,{heading:x.heading,items:x.items}),b]})}
2
+ import{jsx as e,Fragment as t,jsxs as l}from"react/jsx-runtime";import*as a from"react";import{VISUALLY_HIDDEN as n}from"./visually-hidden.js";import{cssLength as r}from"./length.js";import{PLOT_HEIGHT as i,formatCategory as s}from"./chart.js";export function useVisibility(e){const[t,l]=a.useState(()=>{const t=new Set;return e.forEach((e,l)=>{e.hidden&&t.add(l)}),t}),[n,r]=a.useState(null),i=a.useCallback(e=>{l(t=>{const l=new Set(t);return l.has(e)?l.delete(e):l.add(e),l})},[]);return{visible:e.map((e,l)=>!t.has(l)),hovered:n,toggle:i,setHovered:r}}const o={top:"flex-col-reverse",bottom:"flex-col",left:"flex-row-reverse",right:"flex-row"},c={start:"justify-start",center:"justify-center",end:"justify-end"};export function ChartLegend({names:a,colors:n,options:r,visibility:i,size:s,values:o,swatch:m,colorNames:d=!1}){const u=!1!==r.interactive,p="xs"===s||"sm"===s?"text-mp-label-small":"text-mp-label-medium";return e("ul",{className:["mp-chart__legend m-0 flex list-none flex-wrap items-center gap-x-4 gap-y-1 p-0",c[r.align??"center"],p].join(" "),children:a.map((a,r)=>{const s=i.visible[r],c=s&&null!==i.hovered&&i.hovered!==r,p=a??`${r+1}`,h=l(t,{children:[e("span",{className:"shrink-0","aria-hidden":"true",children:m?m(r,n[r]):e("span",{className:"block size-2.5 rounded-mp-full",style:{background:n[r]}})}),e("span",{className:d?"truncate":"text-mp-on-surface-variant truncate",style:d?{color:n[r]}:void 0,children:p}),o?.[r]?e("span",{className:"text-mp-on-surface tabular-nums",children:o[r]}):null]}),f=s?c?"opacity-60":"":"opacity-38";return e("li",{className:"min-w-0",children:u?e("button",{type:"button","aria-pressed":s,onClick:()=>i.toggle(r),onPointerEnter:()=>i.setHovered(r),onPointerLeave:()=>i.setHovered(null),onFocus:e=>{e.currentTarget.matches(":focus-visible")&&i.setHovered(r)},onBlur:()=>i.setHovered(null),className:["flex min-w-0 cursor-pointer items-center gap-1.5 rounded-mp-xs","appearance-none border-0 bg-transparent p-0 text-inherit [font:inherit]","focus-visible:outline-mp-primary focus-visible:outline-2 focus-visible:outline-offset-2",f].filter(Boolean).join(" "),children:h}):e("span",{className:`flex min-w-0 items-center gap-1.5 ${f}`,children:h})},r)})})}export function ChartTooltipPanel({heading:t,items:a,total:n,totalLabel:r,x:i,y:s,flip:o,size:c}){return l("div",{"aria-hidden":"true",className:["mp-chart__tooltip pointer-events-none absolute z-10 min-w-24 max-w-64","bg-mp-surface-container-high shadow-mp-2 rounded-mp-xs px-2.5 py-2","xs"===c||"sm"===c?"text-mp-label-small":"text-mp-label-medium"].join(" "),style:{left:i,top:s,transform:`translate(${o?"calc(-100% - 12px)":"12px"}, -50%)`},children:[null==t||""===t?null:e("div",{className:"text-mp-on-surface-variant mb-1 truncate",children:t}),l("ul",{className:"m-0 flex list-none flex-col gap-0.5 p-0",children:[a.map(t=>l("li",{className:"flex items-center gap-1.5",children:[e("span",{"aria-hidden":"true",className:"block size-2 shrink-0 rounded-mp-full",style:{background:t.color}}),t.name?e("span",{className:"text-mp-on-surface-variant min-w-0 truncate",children:t.name}):null,e("span",{className:"text-mp-on-surface ms-auto ps-2 tabular-nums",children:t.label??t.formatted})]},t.seriesIndex)),void 0===n?null:l("li",{className:"border-mp-outline-variant mt-1 flex items-center gap-1.5 border-0 border-t border-solid pt-1",children:[e("span",{className:"text-mp-on-surface-variant min-w-0 truncate",children:r}),e("span",{className:"text-mp-on-surface ms-auto ps-2 tabular-nums",children:n})]})]})]})}export function ChartStatus({heading:r,items:i,total:s,totalLabel:o}){return e("span",{role:"status","aria-live":"polite",className:n,children:0===i.length?null:l(t,{children:[null==r||""===r?null:l(t,{children:[r,", "]}),i.map((e,t)=>l(a.Fragment,{children:[t>0?", ":null,e.name?`${e.name}: `:null,e.label??e.formatted]},e.seriesIndex)),void 0===s?null:`, ${o}: ${s}`]})})}export function ChartTable({id:t,caption:a,corner:r,categories:i,names:o,values:c,format:m,locale:d,empty:u}){return e("div",{id:t,className:n,children:l("table",{children:[e("caption",{children:a}),e("thead",{children:l("tr",{children:[e("th",{scope:"col",children:r}),o.map((t,l)=>e("th",{scope:"col",children:t??l+1},l))]})}),e("tbody",{children:0===i.length?e("tr",{children:e("td",{colSpan:o.length+1,children:u})}):i.map((t,a)=>l("tr",{children:[e("th",{scope:"row",children:s(t,d)}),o.map((t,l)=>{const n=c[l]?.[a];return e("td",{children:n?.label??(null===n?.value||void 0===n?u:m(n.value))},l)})]},a))})]})})}export function ChartShell({size:t,plotRef:a,name:n,describedBy:s,interactive:c,height:m,plotProps:d,children:u,tooltip:p,overlay:h,legend:f,legendSide:x="bottom",status:b,table:v,className:g,...N}){return l("div",{"data-mp-size":t,className:["mp-chart flex min-w-0 flex-col gap-3",g??""].filter(Boolean).join(" "),...N,children:[l("div",{className:`flex min-w-0 gap-3 ${o[x]}`,children:[l("div",{className:"relative flex min-w-0 flex-1",children:[l("div",{ref:a,role:"img",tabIndex:c?0:void 0,"aria-label":n,"aria-describedby":s,...d,className:["mp-chart__plot rounded-mp-xs relative min-w-0 flex-1","focus-visible:outline-mp-primary focus-visible:outline-2 focus-visible:outline-offset-2"].join(" "),style:{height:r(m)??i[t]},children:[u,p]}),h]}),f]}),e(ChartStatus,{heading:b.heading,items:b.items,total:b.total,totalLabel:b.totalLabel}),v]})}
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { type ChartBaseProps } from './ChartChrome.js';
3
3
  import { BandScale, ChartValue, PlotBox, ValueScale } from './chart.js';
4
- import type { MPChartAxis, MPChartCategory, MPChartSeries, MPChartTooltipItem, MPSize } from '../types.js';
4
+ import type { MPChartAxis, MPChartCategory, MPChartSeries, MPChartStack, MPChartTooltipItem, MPChartZoom, MPSize } from '../types.js';
5
5
  /**
6
6
  * The frame a chart with two axes is drawn in.
7
7
  *
@@ -26,6 +26,15 @@ export interface CartesianChartProps extends ChartBaseProps {
26
26
  xAxis?: MPChartAxis;
27
27
  /** The value axis. */
28
28
  yAxis?: MPChartAxis;
29
+ /**
30
+ * Lets a reader drag a range out of the category axis and redraws to it.
31
+ *
32
+ * For the chart with ninety points on it, where the shape of one week is
33
+ * inside a picture of a quarter. Everything follows the window — the scale,
34
+ * the panel, the readout and the table — so what is drawn is a chart of that
35
+ * range rather than a magnified picture of the whole one.
36
+ */
37
+ zoom?: boolean | MPChartZoom;
29
38
  }
30
39
  /**
31
40
  * One mark on a plot whose marks are not arranged in columns.
@@ -74,6 +83,15 @@ export interface CartesianLayout {
74
83
  visible: readonly boolean[];
75
84
  /** And what colour each one is, by its original index. */
76
85
  colors: readonly string[];
86
+ /**
87
+ * What ink a value written onto one of series `index`' marks wears.
88
+ *
89
+ * Ordinary ink unless the caller asked for `labelColor="series"`. A chart
90
+ * whose labels sit **on** a fill rather than beside a mark ignores it: there
91
+ * the question is what reads against the colour underneath, which is not a
92
+ * question about identity at all.
93
+ */
94
+ labelInk: (series: number) => string;
77
95
  scale: ValueScale;
78
96
  band: BandScale;
79
97
  /** Bars run along the category axis rather than across it. */
@@ -102,6 +120,8 @@ export interface CartesianLayout {
102
120
  zeroPx: number;
103
121
  categories: readonly MPChartCategory[];
104
122
  format: (value: number) => string;
123
+ /** A fraction as the chart writes a share — whole percentages. */
124
+ share: (fraction: number) => string;
105
125
  size: MPSize;
106
126
  }
107
127
  /** The layout, plus everything the pointer decides. */
@@ -162,8 +182,8 @@ interface CartesianFrameProps extends CartesianChartProps {
162
182
  } | null;
163
183
  /** Bars, and only bars, run the other way. */
164
184
  horizontal?: boolean;
165
- /** The value axis measures totals rather than parts. */
166
- stacked?: boolean;
185
+ /** The value axis measures totals rather than parts, or shares of one. */
186
+ stacked?: MPChartStack;
167
187
  /** A line chart may leave zero out; a bar chart may not. */
168
188
  includeZero?: boolean;
169
189
  /** How much of a band the marks take. Bars need room reserved; lines do not. */
@@ -193,5 +213,5 @@ interface CartesianFrameProps extends CartesianChartProps {
193
213
  /**
194
214
  * The frame: two axes, a grid, a crosshair, a legend, a panel and the table.
195
215
  */
196
- export declare function CartesianFrame({ series, categories, xAxis, yAxis, horizontal, stacked, includeZero, bandRatio, inset, headroom, markInset, xScale, marks, markRadius, swatch, scale: givenScale, table: givenTable, markTooltip, height, format, locale: localeProp, label, legend, tooltip, empty, size: sizeProp, className, style, children, ...rest }: CartesianFrameProps): React.JSX.Element;
216
+ export declare function CartesianFrame({ series, categories, xAxis, yAxis, horizontal, zoom, stacked, includeZero, bandRatio, inset, headroom, markInset, xScale, marks, markRadius, swatch, scale: givenScale, table: givenTable, markTooltip, height, format, locale: localeProp, label, legend, tooltip, empty, labelColor, size: sizeProp, className, style, children, ...rest }: CartesianFrameProps): React.JSX.Element;
197
217
  export {};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useMPElementSize as i}from"../hooks/useMPElementSize.js";import{useMPLocale as a,useMPMessages as n}from"./locale.js";import{useMPSize as o}from"./config.js";import{CHART as r}from"./messages/chart.js";import{TABLE as s}from"./messages/table.js";import{ChartLegend as h,ChartShell as c,ChartTable as d,ChartTooltipPanel as u,useVisibility as m}from"./ChartChrome.js";import{CHART_FONT_SIZE as x,MARKER_RADIUS as f,PLOT_HEIGHT as p,bandScale as g,categoryAt as y,categoryCount as v,categoryExtent as k,fitsLast as b,formatCategory as M,formatStatistic as w,seriesColor as z,seriesExtent as S,showsTick as P,textWidth as A,tickStride as C,toValues as j,truncate as B,valueScale as $}from"./chart.js";const R=[],W="var(--_mp-color-outline-variant)",F="var(--_mp-color-outline)",N="var(--_mp-color-on-surface-variant)";function T({plot:l,scale:i,horizontal:a,categoryPx:n,categoryScale:o,categoryValuePx:r,valuePx:s,tickTexts:h,categoryTexts:c,valueAxis:d,categoryAxis:u,fontSize:m,zeroPx:x}){const f=!1!==d?.grid&&!d?.hidden,p=!u?.hidden&&(u?.grid??null!==o),g=e=>o?r(o.ticks[e]):(a?l.top:l.left)+n(e),y=C(c.length,a?l.height:l.width,a?1.8*m:Math.max(...c.map(e=>A(e,m)),1)+12),v=C(i.ticks.length,a?l.width:l.height,a?Math.max(...h.map(e=>A(e,m)),1)+16:2*m),k=c.length>1?Math.abs(g(1)-g(0)):l.width,M=i.ticks.length>1?Math.abs(s(i.ticks[1])-s(i.ticks[0])):l.height,w=b(c.length,y,k,a?1.8*m:A(c[c.length-1]??"",m)),z=b(i.ticks.length,v,M,a?A(h[h.length-1]??"",m):1.6*m);return t("g",{className:"mp-chart__axes",children:[i.ticks.map((n,o)=>{const r=s(n),c=Math.abs(n)<1e-9&&i.min<0,u=!d?.hidden&&P(o,i.ticks.length,v,z);return t("g",{children:[f?e("line",a?{x1:r,x2:r,y1:l.top,y2:l.top+l.height,stroke:c?F:W,strokeWidth:1}:{x1:l.left,x2:l.left+l.width,y1:r,y2:r,stroke:c?F:W,strokeWidth:1}):null,u?e("text",{x:a?r:l.left-8,y:a?l.top+l.height+m+6:r,textAnchor:a?"middle":"end",dominantBaseline:a?"auto":"central",fill:N,fontSize:m,children:h[o]}):null]},`v${o}`)}),c.map((i,n)=>{const o=g(n),r=!u?.hidden&&P(n,c.length,y,w);return t("g",{children:[p?e("line",a?{x1:l.left,x2:l.left+l.width,y1:o,y2:o,stroke:W,strokeWidth:1}:{x1:o,x2:o,y1:l.top,y2:l.top+l.height,stroke:W,strokeWidth:1}):null,r?e("text",{x:a?l.left-8:o,y:a?o:l.top+l.height+m+6,textAnchor:a?"end":"middle",dominantBaseline:a?"central":"auto",fill:N,fontSize:m,children:i}):null]},`c${n}`)}),e("line",a?{x1:x,x2:x,y1:l.top,y2:l.top+l.height,stroke:F,strokeWidth:1}:{x1:l.left,x2:l.left+l.width,y1:x,y2:x,stroke:F,strokeWidth:1}),d?.label&&!d.hidden?e("text",{x:a?l.left+l.width/2:m,y:a?l.top+l.height+2*m+12:l.top+l.height/2,textAnchor:"middle",dominantBaseline:a?"auto":"central",fill:N,fontSize:m,transform:a?void 0:`rotate(-90 ${m} ${l.top+l.height/2})`,children:d.label}):null,u?.label&&!u.hidden?e("text",{x:a?m:l.left+l.width/2,y:a?l.top+l.height/2:l.top+l.height+2*m+12,textAnchor:"middle",dominantBaseline:a?"central":"auto",fill:N,fontSize:m,transform:a?`rotate(-90 ${m} ${l.top+l.height/2})`:void 0,children:u.label}):null]})}export function CartesianFrame({series:b,categories:P,xAxis:C,yAxis:W,horizontal:N=!1,stacked:_=!1,includeZero:E=!0,bandRatio:I=1,inset:V=!1,headroom:D=0,markInset:X=0,xScale:Y="band",marks:Z,markRadius:L=24,swatch:H,scale:K,table:U,markTooltip:q,height:G,format:J,locale:O,label:Q,legend:ee,tooltip:te,empty:le,size:ie,className:ae,style:ne,children:oe,...re}){const se=o(ie),he=a(O),ce=n(r,he),de=n(s,he),ue=l.useRef(null),me=i(ue),xe=me.width,fe=l.useId(),pe=m(b),[ge,ye]=l.useState(null),[ve,ke]=l.useState(null),[be,Me]=l.useState(null),we=l.useCallback(e=>w(e,he,J,!0),[J,he]),ze=l.useMemo(()=>j(b),[b]),Se=l.useMemo(()=>b.map((e,t)=>z(t,e.color)),[b]),Pe=l.useMemo(()=>b.map(e=>e.name),[b]),Ae=v(b),Ce=l.useMemo(()=>Array.from({length:Ae},(e,t)=>y(t,P,ze)),[Ae,P,ze]),je=ze.filter((e,t)=>pe.visible[t]),Be=S(je,_),$e=x[se],Re=W,We=C,Fe=K??$(Be,{min:Re?.min,max:Re?.max,tickCount:Re?.tickCount,includeZero:E}),Ne="value"===Y?k(je,P):null,Te="value"===Y?$(Ne,{min:We?.min,max:We?.max,tickCount:We?.tickCount,includeZero:!1}):null,_e=Fe.ticks.map((e,t)=>Re?.tickFormat?String(Re.tickFormat(e,t)):we(e)),Ee=Te?Te.ticks.map((e,t)=>We?.tickFormat?String(We.tickFormat(e,t)):w(e,he,void 0,!0)):Ce.map((e,t)=>We?.tickFormat?String(We.tickFormat(e,t)):M(e,he)),Ie=_e.reduce((e,t)=>Math.max(e,A(t,$e)),0),Ve=$e+6,De=Re?.hidden?0:Ie+10+(Re?.label?Ve:0),Xe=(xe-(N?0:De)-16)/Math.max(1,Ae),Ye=Te?Ee:N||Xe-6>=2.4*$e?Ee.map(e=>B(e,N?150:Xe-6,$e)):Ee,Ze=Ye.reduce((e,t)=>Math.max(e,A(t,$e)),0),Le=N?We?.hidden?0:Ze+10+(We?.label?Ve:0):De,He=N?Re?.hidden?0:$e+12+(Re?.label?Ve:0):We?.hidden?0:$e+12+(We?.label?Ve:0),Ke=(N?We:Re)?.thickness??Le,Ue=(N?Re:We)?.thickness??He,qe=(N?12+D:Math.max(8,Ze/2))+X,Ge=f[se]+4+(N?0:D)+X,Je="number"==typeof G?G:void 0===G?p[se]:me.height,Oe={left:Ke+X,top:Ge,width:Math.max(0,xe-Ke-X-qe),height:Math.max(0,Je-Ge-Ue-X)},Qe=N?Oe.height:Oe.width,et=g(V?Math.max(1,Ae-1):Ae,Qe,I),tt=l.useCallback(e=>V?Ae<=1?Qe/2:Qe*e/(Ae-1):et.centre(e),[V,Ae,Qe,et]),lt=l.useCallback(e=>N?Oe.left+Fe.fraction(e)*Oe.width:Oe.top+(1-Fe.fraction(e))*Oe.height,[N,Oe.left,Oe.top,Oe.width,Oe.height,Fe]),it=l.useCallback(e=>N?Oe.top+(1-(Te?.fraction(e)??0))*Oe.height:Oe.left+(Te?.fraction(e)??0)*Oe.width,[N,Oe.left,Oe.top,Oe.width,Oe.height,Te]),at=l.useCallback((e,t)=>N?{x:lt(t),y:Oe.top+tt(e)}:{x:Oe.left+tt(e),y:lt(t)},[N,lt,tt,Oe.left,Oe.top]),nt=lt(Math.min(Math.max(0,Fe.min),Fe.max)),ot={plot:Oe,values:ze,visible:pe.visible,colors:Se,scale:Fe,band:et,horizontal:N,valuePx:lt,categoryPx:tt,point:at,categoryScale:Te,categoryValuePx:it,zeroPx:nt,categories:Ce,format:we,size:se},rt=Z?Z(ot):R,st=!1===te?{mode:"none"}:!0===te||void 0===te?{}:te,ht=st.mode??(Z?"item":"index"),ct=null===ve?null:rt[ve]??null,dt=Z?ct?ct.index:null:ge,ut=Z?rt.length:Ae,mt=()=>{ye(null),ke(null),Me(null)},xt=e=>{const t=null===e?null:Math.min(ut-1,Math.max(0,e));Z?ke(t):ye(t)},ft=e=>{Me(null);xt(((Z?ve:ge)??(e>0?-1:ut))+e)},pt=null===dt?[]:b.flatMap((e,t)=>{if(!pe.visible[t]||ct&&ct.series!==t)return[];const l=ze[t]?.[dt];return l&&null!==l.value?[{seriesIndex:t,name:e.name,color:l.color??Se[t],value:l.value,formatted:we(l.value),label:l.label}]:[]}),gt=ct&&q?q(ct):null,yt=gt?gt.items:"item"===ht&&pt.length>1&&null!==be?[pt.reduce((e,t)=>Math.abs(lt(t.value??0)-be)<Math.abs(lt(e.value??0)-be)?t:e)]:pt,vt=gt?gt.heading:ct?M(ze[ct.series]?.[ct.index]?.x??P?.[ct.index]??ct.index,he):null===dt?void 0:M(Ce[dt]??dt,he),kt=ct?ct.x:N?lt(yt[0]?.value??0):Oe.left+tt(dt??0),bt=ct?ct.y:N?Oe.top+tt(dt??0):Oe.top+Oe.height/2,Mt=ct?(ct.x-Oe.left)/Math.max(1,Oe.width)>.6:(N?Fe.fraction(yt[0]?.value??0):tt(dt??0)/Math.max(1,Qe))>.6,wt=!1===ee?{interactive:!1}:!0===ee||void 0===ee?{}:ee,zt=!0===ee||!1!==ee&&b.length>1,St=wt.side??"bottom",Pt={...ot,hovered:pe.hovered,activeIndex:dt,marks:rt,activeMark:ct},At=0===Ae||null===Be||"value"===Y&&null===Ne;return e(c,{...re,size:se,className:ae,style:ne,plotRef:ue,name:Q??ce.label,describedBy:At?void 0:fe,interactive:!At,height:G,legendSide:St,plotProps:{onPointerMove:At||"none"===ht?void 0:e=>{Z?ke(((e,t)=>{const l=ue.current;if(!l||0===rt.length)return null;const i=l.getBoundingClientRect(),a=e-i.left,n=t-i.top;let o=null,r=1/0,s=1/0;return rt.forEach((e,t)=>{const l=Math.hypot(e.x-a,e.y-n),i=void 0===e.rx?Math.max(0,l-e.r):Math.hypot(Math.max(0,Math.abs(e.x-a)-e.rx),Math.max(0,Math.abs(e.y-n)-(e.ry??e.rx)));i<=L&&(i<r||i===r&&l<s)&&(r=i,s=l,o=t)}),o})(e.clientX,e.clientY)):ye(((e,t)=>{const l=ue.current;if(!l||0===Ae)return null;const i=l.getBoundingClientRect(),a=N?t-i.top-Oe.top:e-i.left-Oe.left;if(a<-et.step||a>Qe+et.step)return null;const n=V?Ae<=1?0:Math.round(a/Qe*(Ae-1)):Math.floor(a/et.step);return Math.min(Ae-1,Math.max(0,n))})(e.clientX,e.clientY)),"item"===ht&&Me(((e,t)=>{const l=ue.current;if(!l)return null;const i=l.getBoundingClientRect();return N?e-i.left:t-i.top})(e.clientX,e.clientY))},onPointerLeave:mt,onKeyDown:At||"none"===ht?void 0:e=>{const t=N?"ArrowDown":"ArrowRight",l=N?"ArrowUp":"ArrowLeft";if(e.key===t)ft(1);else if(e.key===l)ft(-1);else if("Home"===e.key)xt(0);else if("End"===e.key)xt(ut-1);else{if("Escape"!==e.key)return;mt()}e.preventDefault()},onBlur:mt},tooltip:null!==dt&&yt.length>0&&"none"!==ht?st.render?e("div",{"aria-hidden":"true",className:"pointer-events-none absolute z-10",style:{left:kt,top:bt,transform:`translate(${Mt?"calc(-100% - 12px)":"12px"}, -50%)`},children:st.render({index:dt,category:Ce[dt]??dt,items:yt})}):e(u,{heading:vt,items:yt,x:kt,y:bt,flip:Mt,size:se}):null,legend:zt?e(h,{names:Pe,colors:Se,options:wt,visibility:pe,size:se,swatch:H,values:wt.showValue&&null!==dt?b.map((e,t)=>{const l=ze[t]?.[dt]?.value;return null==l?void 0:we(l)}):void 0}):null,status:{heading:vt,items:yt},table:At?null:U?.(fe)??e(d,{id:fe,caption:Q??ce.table,corner:We?.label??ce.category,categories:Ce,names:Pe,values:ze,format:we,locale:he,empty:de.empty}),children:At?e("div",{className:"text-mp-on-surface-variant text-mp-body-small flex h-full items-center justify-center",children:le??de.empty}):xe>0&&Je>0?t("svg",{width:xe,height:Je,viewBox:`0 0 ${xe} ${Je}`,"aria-hidden":"true",className:"block overflow-visible",children:[e(T,{plot:Oe,scale:Fe,horizontal:N,categoryPx:tt,categoryScale:Te,categoryValuePx:it,valuePx:lt,tickTexts:_e,categoryTexts:Ye,valueAxis:Re,categoryAxis:We,fontSize:$e,zeroPx:nt}),null===dt||Z||"index"!==ht||!1===st.crosshair?null:(()=>{const t=tt(dt);return e("line",N?{x1:Oe.left,x2:Oe.left+Oe.width,y1:Oe.top+t,y2:Oe.top+t,stroke:F,strokeWidth:1}:{x1:Oe.left+t,x2:Oe.left+t,y1:Oe.top,y2:Oe.top+Oe.height,stroke:F,strokeWidth:1})})(),oe(Pt)]}):null})}
2
+ import{jsx as t,jsxs as e,Fragment as l}from"react/jsx-runtime";import*as n from"react";import{useMPElementSize as a}from"../hooks/useMPElementSize.js";import{useMPLocale as i,useMPMessages as o}from"./locale.js";import{useMPSize as r}from"./config.js";import{CHART as s}from"./messages/chart.js";import{TABLE as h}from"./messages/table.js";import{ChartLegend as c,ChartShell as u,ChartTable as d,ChartTooltipPanel as m,useVisibility as p}from"./ChartChrome.js";import{VISUALLY_HIDDEN as f}from"./visually-hidden.js";import{CHART_FONT_SIZE as x,MARKER_RADIUS as g,PLOT_HEIGHT as v,bandScale as y,categoryAt as b,categoryCount as k,categoryExtent as M,fitsLast as w,formatCategory as z,formatShare as S,formatStatistic as P,seriesColor as C,seriesExtent as A,showsTick as $,textWidth as _,tickStride as B,tickTurn as j,toNumber as R,toValues as N,truncate as W,turnedBand as I,turnedRoom as F,turnedStep as T,valueScale as D,withReferences as L}from"./chart.js";const X=[];function Y({text:e,along:l,top:n,turn:a,fontSize:i}){return t("text",a<=0?{x:l,y:n+i+6,textAnchor:"middle",fill:Z,fontSize:i,children:e}:{x:l,y:n+8,textAnchor:"end",dominantBaseline:"central",transform:`rotate(${-a} ${l} ${n+8})`,fill:Z,fontSize:i,children:e})}const E="var(--_mp-color-outline-variant)",V="var(--_mp-color-outline)",Z="var(--_mp-color-on-surface-variant)";function U({plot:l,scale:n,horizontal:a,categoryPx:i,categoryScale:o,categoryValuePx:r,valuePx:s,tickTexts:h,categoryTexts:c,valueAxis:u,categoryAxis:d,fontSize:m,zeroPx:p,turn:f,tickBand:x}){const g=!1!==u?.grid&&!u?.hidden,v=!d?.hidden&&(d?.grid??null!==o),y=t=>o?r(o.ticks[t]):(a?l.top:l.left)+i(t),b=(t,e)=>f>0?T(f,m):Math.max(...t.map(t=>_(t,m)),1)+e,k=B(c.length,a?l.height:l.width,a?1.8*m:b(c,12)),M=B(n.ticks.length,a?l.width:l.height,a?b(h,16):2*m),z=c.length>1?Math.abs(y(1)-y(0)):l.width,S=n.ticks.length>1?Math.abs(s(n.ticks[1])-s(n.ticks[0])):l.height,P=w(c.length,k,z,a?1.8*m:f>0?T(f,m):_(c[c.length-1]??"",m)),C=w(n.ticks.length,M,S,a?f>0?T(f,m):_(h[h.length-1]??"",m):1.6*m);return e("g",{className:"mp-chart__axes",children:[n.ticks.map((i,o)=>{const r=s(i),c=Math.abs(i)<1e-9&&n.min<0,d=!u?.hidden&&$(o,n.ticks.length,M,C);return e("g",{children:[g?t("line",a?{x1:r,x2:r,y1:l.top,y2:l.top+l.height,stroke:c?V:E,strokeWidth:1}:{x1:l.left,x2:l.left+l.width,y1:r,y2:r,stroke:c?V:E,strokeWidth:1}):null,d?a?t(Y,{text:h[o],along:r,top:l.top+l.height,turn:f,fontSize:m}):t("text",{x:l.left-8,y:r,textAnchor:"end",dominantBaseline:"central",fill:Z,fontSize:m,children:h[o]}):null]},`v${o}`)}),c.map((n,i)=>{const o=y(i),r=!d?.hidden&&$(i,c.length,k,P);return e("g",{children:[v?t("line",a?{x1:l.left,x2:l.left+l.width,y1:o,y2:o,stroke:E,strokeWidth:1}:{x1:o,x2:o,y1:l.top,y2:l.top+l.height,stroke:E,strokeWidth:1}):null,r?a?t("text",{x:l.left-8,y:o,textAnchor:"end",dominantBaseline:"central",fill:Z,fontSize:m,children:n}):t(Y,{text:n,along:o,top:l.top+l.height,turn:f,fontSize:m}):null]},`c${i}`)}),t("line",a?{x1:p,x2:p,y1:l.top,y2:l.top+l.height,stroke:V,strokeWidth:1}:{x1:l.left,x2:l.left+l.width,y1:p,y2:p,stroke:V,strokeWidth:1}),u?.label&&!u.hidden?t("text",{x:a?l.left+l.width/2:m,y:a?l.top+l.height+x+m:l.top+l.height/2,textAnchor:"middle",dominantBaseline:a?"auto":"central",fill:Z,fontSize:m,transform:a?void 0:`rotate(-90 ${m} ${l.top+l.height/2})`,children:u.label}):null,d?.label&&!d.hidden?t("text",{x:a?m:l.left+l.width/2,y:a?l.top+l.height/2:l.top+l.height+x+m,textAnchor:"middle",dominantBaseline:a?"central":"auto",fill:Z,fontSize:m,transform:a?`rotate(-90 ${m} ${l.top+l.height/2})`:void 0,children:d.label}):null]})}function H(t,e){try{e?t.currentTarget.setPointerCapture(t.pointerId):t.currentTarget.releasePointerCapture(t.pointerId)}catch{}}function K(t,e,l){return(t??[]).map(t=>({...t,at:R(t.value),end:void 0===t.to?null:R(t.to)})).filter(t=>null!==t.at).map(t=>({at:e(t.at),to:null===t.end?null:e(t.end),upright:l,label:t.label,color:t.color?C(0,t.color):"var(--_mp-color-outline)",dashed:!1!==t.dashed}))}function O({marks:l,plot:n,pass:a,fontSize:i}){return 0===l.length?null:t("g",{className:`mp-chart__references mp-chart__references--${a}`,"aria-hidden":"true",children:l.map((l,o)=>{if("band"===a)return null===l.to?null:t("rect",{...(r=l.at,s=l.to,l.upright?{x:Math.min(r,s),y:n.top,width:Math.abs(s-r),height:n.height}:{x:n.left,y:Math.min(r,s),width:n.width,height:Math.abs(s-r)}),fill:l.color,opacity:.12},o);var r,s;const h=null===l.to?[l.at]:[l.at,l.to];return e("g",{children:[h.map(e=>t("line",{x1:l.upright?e:n.left,x2:l.upright?e:n.left+n.width,y1:l.upright?n.top:e,y2:l.upright?n.top+n.height:e,stroke:l.color,strokeWidth:1,strokeDasharray:l.dashed?"4 3":void 0},e)),void 0===l.label||null===l.label||""===l.label?null:t("text",{x:l.upright?l.at+4:n.left+n.width,y:l.upright?n.top+i:l.at-4,textAnchor:l.upright?"start":"end",fill:l.color,fontSize:i,children:l.label})]},o)})})}export function CartesianFrame({series:w,categories:$,xAxis:B,yAxis:R,horizontal:T=!1,zoom:Y,stacked:E=!1,includeZero:q=!0,bandRatio:G=1,inset:J=!1,headroom:Q=0,markInset:tt=0,xScale:et="band",marks:lt,markRadius:nt=24,swatch:at,scale:it,table:ot,markTooltip:rt,height:st,format:ht,locale:ct,label:ut,legend:dt,tooltip:mt,empty:pt,labelColor:ft="ink",size:xt,className:gt,style:vt,children:yt,...bt}){const kt=r(xt),Mt=i(ct),wt=o(s,Mt),zt=o(h,Mt),St=n.useRef(null),Pt=a(St),Ct=Pt.width,At=n.useId(),$t=n.useId(),_t=p(w),[Bt,jt]=n.useState(null),[Rt,Nt]=n.useState(null),[Wt,It]=n.useState(null),[Ft,Tt]=n.useState(null),Dt=n.useRef(null),Lt=t=>{Dt.current=t,Tt(t)},Xt=n.useCallback(t=>P(t,Mt,ht,!0),[ht,Mt]),Yt=n.useMemo(()=>N(w),[w]),Et=n.useMemo(()=>w.map((t,e)=>C(e,t.color)),[w]),Vt=n.useMemo(()=>w.map(t=>t.name),[w]),Zt=k(w),Ut=n.useMemo(()=>Array.from({length:Zt},(t,e)=>b(e,$,Yt)),[Zt,$,Yt]),Ht=!0!==Y&&!1!==Y&&Y?Y:{},Kt=void 0!==Y&&!1!==Y&&"band"===et,[Ot,qt]=n.useState(()=>Ht.defaultRange??null),Gt=(void 0!==Ht.range?Ht.range:Ot)??null,Jt=Kt&&null!==Gt&&0!==Zt?[Math.max(0,Math.min(Zt-1,Math.min(Gt[0],Gt[1]))),Math.max(0,Math.min(Zt-1,Math.max(Gt[0],Gt[1])))]:null,Qt=Jt?Jt[0]:0,te=Jt?Jt[1]-Jt[0]+1:Zt,ee=Jt?Yt.map(t=>t.slice(Qt,Qt+te)):Yt,le=Jt?Ut.slice(Qt,Qt+te):Ut,ne=t=>{void 0===Ht.range&&qt(t),Ht.onRangeChange?.(t)},ae=ee.filter((t,e)=>_t.visible[e]),ie="percent"===E,oe=ie?{min:0,max:1}:A(ae,Boolean(E)),re=x[kt],se=R,he=B,ce=it??D(ie?oe:L(oe,se?.references),{min:ie?0:se?.min,max:ie?1:se?.max,tickCount:se?.tickCount??(ie?4:void 0),includeZero:q}),ue="value"===et?M(ae,$):null,de="value"===et?D(L(ue,he?.references),{min:he?.min,max:he?.max,tickCount:he?.tickCount,includeZero:!1}):null,me=ce.ticks.map((t,e)=>se?.tickFormat?String(se.tickFormat(t,e)):ie?S(t,Mt):Xt(t)),pe=de?de.ticks.map((t,e)=>he?.tickFormat?String(he.tickFormat(t,e)):P(t,Mt,void 0,!0)):le.map((t,e)=>he?.tickFormat?String(he.tickFormat(t,e)):z(t,Mt)),fe=me.reduce((t,e)=>Math.max(t,_(e,re)),0),xe=re+6,ge=se?.hidden?0:fe+10+(se?.label?xe:0),ve="number"==typeof st?st:void 0===st?v[kt]:Pt.height,ye=(Ct-(T?0:ge)-16)/Math.max(1,te),be=T?se:he,ke=T?me:pe,Me=T?he?.hidden?0:pe.reduce((t,e)=>Math.max(t,Math.min(150,_(e,re))),0)+10+(he?.label?xe:0):ge,we=ke.reduce((t,e)=>Math.max(t,_(e,re)),0),ze=T?12+Q:Math.max(8,we/2),Se=(Ct-Me-ze-2*tt)/Math.max(1,ke.length),Pe=T||null!==de,Ce=be?.hidden?0:j(be?.tickLabels??(Pe?"truncate":"auto"),ke,re,Se),Ae=Math.min(120,.5*ve),$e=Ce>0&&!T?pe.map((t,e)=>W(t,(t=>Math.min(F(Ce,Ae,re),Ce>=90?1/0:(Me+Se*(t+(J?0:.5)))/Math.cos(Ce*Math.PI/180)))(e),re)):de?pe:T||ye-6>=2.4*re?pe.map(t=>W(t,T?150:ye-6,re)):pe,_e=$e.reduce((t,e)=>Math.max(t,_(e,re)),0),Be=be?.hidden?0:Ce>0?8+Math.min(Ae,I(Ce,T?fe:_e,re))+4:re+12,je=T?he?.hidden?0:_e+10+(he?.label?xe:0):ge,Re=Be+(be?.hidden||!be?.label?0:xe),Ne=(T?he:se)?.thickness??je,We=be?.thickness??Re,Ie=(T||Ce>0?12+(T?Q:0):Math.max(8,_e/2))+tt,Fe=g[kt]+4+(T?0:Q)+tt,Te={left:Ne+tt,top:Fe,width:Math.max(0,Ct-Ne-tt-Ie),height:Math.max(0,ve-Fe-We-tt)},De=T?Te.height:Te.width,Le=y(J?Math.max(1,te-1):te,De,G),Xe=n.useCallback(t=>J?te<=1?De/2:De*t/(te-1):Le.centre(t),[J,te,De,Le]),Ye=n.useCallback(t=>T?Te.left+ce.fraction(t)*Te.width:Te.top+(1-ce.fraction(t))*Te.height,[T,Te.left,Te.top,Te.width,Te.height,ce]),Ee=n.useCallback(t=>T?Te.top+(1-(de?.fraction(t)??0))*Te.height:Te.left+(de?.fraction(t)??0)*Te.width,[T,Te.left,Te.top,Te.width,Te.height,de]),Ve=n.useCallback((t,e)=>T?{x:Ye(e),y:Te.top+Xe(t)}:{x:Te.left+Xe(t),y:Ye(e)},[T,Ye,Xe,Te.left,Te.top]),Ze=Ye(Math.min(Math.max(0,ce.min),ce.max)),Ue=[...K(se?.references,Ye,T),...de?K(he?.references,Ee,!T):[]],He=t=>t instanceof Date?z(t,Mt):Xt(t),Ke=[...se?.references??[],...de?he?.references??[]:[]].filter(t=>void 0!==t.label&&null!==t.label&&""!==t.label),Oe={plot:Te,values:ee,visible:_t.visible,colors:Et,labelInk:t=>"series"===ft?Et[t]??Z:"var(--_mp-color-on-surface)",scale:ce,band:Le,horizontal:T,valuePx:Ye,categoryPx:Xe,point:Ve,categoryScale:de,categoryValuePx:Ee,zeroPx:Ze,categories:le,format:Xt,share:t=>S(t,Mt),size:kt},qe=lt?lt(Oe):X,Ge=!1===mt?{mode:"none"}:!0===mt||void 0===mt?{}:mt,Je=Ge.mode??(lt?"item":"index"),Qe=(t,e)=>{const l=St.current;if(!l||0===te)return null;const n=l.getBoundingClientRect(),a=T?e-n.top-Te.top:t-n.left-Te.left;if(a<-Le.step||a>De+Le.step)return null;const i=J?te<=1?0:Math.round(a/De*(te-1)):Math.floor(a/Le.step);return Math.min(te-1,Math.max(0,i))},tl=null===Rt?null:qe[Rt]??null,el=lt?tl?tl.index:null:Bt,ll=lt?qe.length:te,nl=()=>{jt(null),Nt(null),It(null)},al=t=>{const e=Dt.current;if(null===e)return;H(t,!1);const l=Math.min(e.start,e.to),n=Math.max(e.start,e.to);Lt(null),n-l+1>=Math.max(2,Ht.min??2)&&ne([Qt+l,Qt+n])},il=t=>{const e=null===t?null:Math.min(ll-1,Math.max(0,t));lt?Nt(e):jt(e)},ol=t=>{It(null);il(((lt?Rt:Bt)??(t>0?-1:ll))+t)},rl=null!==el&&ie?ee.reduce((t,e,l)=>{const n=_t.visible[l]?e[el]?.value:null;return t+(null!=n&&n>0?n:0)},0):0,sl=null===el?[]:w.flatMap((t,e)=>{if(!_t.visible[e]||tl&&tl.series!==e)return[];const l=ee[e]?.[el];return l&&null!==l.value?[{seriesIndex:e,name:t.name,color:l.color??Et[e],value:l.value,formatted:ie&&rl>0&&l.value>0?`${Xt(l.value)} · ${S(l.value/rl,Mt)}`:Xt(l.value),label:l.label}]:[]}),hl=tl&&rt?rt(tl):null,cl=hl?hl.items:"item"===Je&&sl.length>1&&null!==Wt?[sl.reduce((t,e)=>Math.abs(Ye(e.value??0)-Wt)<Math.abs(Ye(t.value??0)-Wt)?e:t)]:sl,ul="value"===Ge.sort?[...cl].sort((t,e)=>(e.value??-1/0)-(t.value??-1/0)):cl,dl=!(Ge.total??!0===E)||hl||cl.length<2?void 0:Xt(cl.reduce((t,e)=>t+(e.value??0),0)),ml=hl?hl.heading:tl?z(ee[tl.series]?.[tl.index]?.x??$?.[tl.index]??tl.index,Mt):null===el?void 0:z(le[el]??el,Mt),pl=tl?tl.x:T?Ye(cl[0]?.value??0):Te.left+Xe(el??0),fl=tl?tl.y:T?Te.top+Xe(el??0):Te.top+Te.height/2,xl=tl?(tl.x-Te.left)/Math.max(1,Te.width)>.6:(T?ce.fraction(cl[0]?.value??0):Xe(el??0)/Math.max(1,De))>.6,gl=!1===dt?{interactive:!1}:!0===dt||void 0===dt?{}:dt,vl=!0===dt||!1!==dt&&w.length>1,yl=gl.side??"bottom",bl={...Oe,hovered:_t.hovered,activeIndex:el,marks:qe,activeMark:tl},kl=0===te||null===oe||"value"===et&&null===ue;return t(u,{...bt,size:kt,className:gt,style:vt,plotRef:St,name:ut??wt.label,describedBy:kl?void 0:Ke.length>0?`${At} ${$t}`:At,interactive:!kl,height:st,legendSide:yl,plotProps:{onPointerDown:Kt&&!kl?t=>{const e=Qe(t.clientX,t.clientY);null!==e&&(H(t,!0),nl(),Lt({start:e,to:e}))}:void 0,onPointerMove:kl?void 0:t=>{null===Dt.current?"none"!==Je&&(lt?Nt(((t,e)=>{const l=St.current;if(!l||0===qe.length)return null;const n=l.getBoundingClientRect(),a=t-n.left,i=e-n.top;let o=null,r=1/0,s=1/0;return qe.forEach((t,e)=>{const l=Math.hypot(t.x-a,t.y-i),n=void 0===t.rx?Math.max(0,l-t.r):Math.hypot(Math.max(0,Math.abs(t.x-a)-t.rx),Math.max(0,Math.abs(t.y-i)-(t.ry??t.rx)));n<=nt&&(n<r||n===r&&l<s)&&(r=n,s=l,o=e)}),o})(t.clientX,t.clientY)):jt(Qe(t.clientX,t.clientY)),"item"===Je&&It(((t,e)=>{const l=St.current;if(!l)return null;const n=l.getBoundingClientRect();return T?t-n.left:e-n.top})(t.clientX,t.clientY))):Lt({...Dt.current,to:Qe(t.clientX,t.clientY)??Dt.current.to})},onPointerUp:Kt&&!kl?al:void 0,onPointerCancel:Kt&&!kl?()=>Lt(null):void 0,onPointerLeave:t=>{Kt&&!kl&&al(t),nl()},onKeyDown:kl||"none"===Je&&!Kt?void 0:t=>{const e=T?"ArrowDown":"ArrowRight",l=T?"ArrowUp":"ArrowLeft";if(t.key===e)ol(1);else if(t.key===l)ol(-1);else if("Home"===t.key)il(0);else if("End"===t.key)il(ll-1);else{if("Escape"!==t.key)return;null===el&&null!==Jt?ne(null):nl()}t.preventDefault()},onBlur:nl},overlay:null===Jt||kl?null:t("button",{type:"button",onClick:()=>ne(null),className:["mp-chart__reset absolute end-0 top-0 z-10 cursor-pointer","text-mp-primary text-mp-label-medium rounded-mp-xs px-2 py-1","appearance-none border-0 bg-transparent [font:inherit]","focus-visible:outline-mp-primary focus-visible:outline-2 focus-visible:outline-offset-2"].join(" "),children:wt.showAll}),tooltip:null!==el&&cl.length>0&&"none"!==Je&&null===Ft?Ge.render?t("div",{"aria-hidden":"true",className:"pointer-events-none absolute z-10",style:{left:pl,top:fl,transform:`translate(${xl?"calc(-100% - 12px)":"12px"}, -50%)`},children:Ge.render({index:el,category:le[el]??el,items:ul,total:dl})}):t(m,{heading:ml,items:ul,total:dl,totalLabel:wt.total,x:pl,y:fl,flip:xl,size:kt}):null,legend:vl?t(c,{names:Vt,colors:Et,options:gl,visibility:_t,size:kt,swatch:at,colorNames:"series"===ft,values:gl.showValue&&null!==el?w.map((t,e)=>{const l=ee[e]?.[el]?.value;return null==l?void 0:Xt(l)}):void 0}):null,status:{heading:ml,items:ul,total:dl,totalLabel:wt.total},table:kl?null:e(l,{children:[ot?.(At)??t(d,{id:At,caption:ut??wt.table,corner:he?.label??wt.category,categories:le,names:Vt,values:ee,format:Xt,locale:Mt,empty:zt.empty}),0===Ke.length?null:t("ul",{id:$t,className:f,children:Ke.map((t,l)=>e("li",{children:[t.label,":"," ",void 0===t.to?He(t.value):`${He(t.value)}–${He(t.to)}`]},l))})]}),children:kl?t("div",{className:"text-mp-on-surface-variant text-mp-body-small flex h-full items-center justify-center",children:pt??zt.empty}):Ct>0&&ve>0?e("svg",{width:Ct,height:ve,viewBox:`0 0 ${Ct} ${ve}`,"aria-hidden":"true",className:"block overflow-visible",children:[t(U,{plot:Te,scale:ce,horizontal:T,categoryPx:Xe,categoryScale:de,categoryValuePx:Ee,valuePx:Ye,tickTexts:me,categoryTexts:$e,valueAxis:se,categoryAxis:he,fontSize:re,zeroPx:Ze,turn:Ce,tickBand:Be}),t(O,{marks:Ue,plot:Te,pass:"band",fontSize:re}),null===el||lt||"index"!==Je||!1===Ge.crosshair?null:(()=>{const e=Xe(el);return t("line",T?{x1:Te.left,x2:Te.left+Te.width,y1:Te.top+e,y2:Te.top+e,stroke:V,strokeWidth:1}:{x1:Te.left+e,x2:Te.left+e,y1:Te.top,y2:Te.top+Te.height,stroke:V,strokeWidth:1})})(),yt(bl),t(O,{marks:Ue,plot:Te,pass:"line",fontSize:re}),null===Ft?null:(()=>{const e=[Ft.start,Ft.to].map(t=>(T?Te.top:Te.left)+Xe(t)).sort((t,e)=>t-e),l=Math.max(Le.step,1),n=e[0]-l/2,a=e[1]-e[0]+l;return t("rect",{x:T?Te.left:n,y:T?n:Te.top,width:T?Te.width:a,height:T?a:Te.height,fill:"var(--_mp-color-primary)",fillOpacity:.12,stroke:"var(--_mp-color-primary)",strokeWidth:1})})()]}):null})}