@martinomagnifico/tablechart 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ :root{--cssimported-tablechart:true}.tablechart{margin:var(--tablechart-margin,0);color:var(--tablechart-color,currentColor);font-size:var(--tablechart-font-size,1em);line-height:var(--tablechart-line-height,1.25)}:where([data-chart]){margin:var(--tablechart-margin,0);color:var(--tablechart-color,currentColor);font-size:var(--tablechart-font-size,1em);line-height:var(--tablechart-line-height,1.25)}.tablechart :where(figcaption){margin-bottom:var(--tablechart-caption-gap,.5em);text-align:var(--tablechart-caption-align,left)}:where([data-chart]) :where(figcaption){margin-bottom:var(--tablechart-caption-gap,.5em);text-align:var(--tablechart-caption-align,left)}.tablechart{position:relative}:where([data-chart]){position:relative}.tablechart :where(table){left:0;right:0;clip-path:inset(50%);margin:0;position:absolute;top:0}.tablechart :where(.chart-annotations){left:0;right:0;clip-path:inset(50%);margin:0;position:absolute;top:0}:where([data-chart]) :where(table){left:0;right:0;clip-path:inset(50%);margin:0;position:absolute;top:0}:where([data-chart]) :where(.chart-annotations){left:0;right:0;clip-path:inset(50%);margin:0;position:absolute;top:0}@media (scripting:none){.tablechart :where(table){clip-path:none;position:static}.tablechart :where(.chart-annotations){clip-path:none;position:static}:where([data-chart]) :where(table){clip-path:none;position:static}:where([data-chart]) :where(.chart-annotations){clip-path:none;position:static}}.tablechart-plot{position:relative}.tablechart-plot :where(svg){width:100%;height:auto;display:block;overflow:visible}.tablechart-plot:not(.is-placed) :where(.tablechart-value,.tablechart-badge,.tablechart-name){visibility:hidden}.tablechart-sr{white-space:nowrap;clip-path:inset(50%);width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.tablechart-value{white-space:nowrap;font-size:var(--tablechart-value-size,calc(var(--tablechart-category-size,.95em) * 1.3));position:absolute;transform:translate(-50%,-100%)}.tablechart-value[data-place=outside]{color:var(--tablechart-value-color,currentColor)}.tablechart-value[data-place=inside]{color:var(--tablechart-bar-ink,oklch(from var(--tablechart-bar-color,currentColor) calc(.18 + .8 * clamp(0, (.68 - l) * 1000, 1)) 0 0));transform:translate(-50%,-50%)}.tablechart-value[data-place=around]{color:var(--tablechart-value-color,currentColor);transform:translate(-50%,-50%)}.tablechart-value[data-place=below]{color:var(--tablechart-value-color,currentColor);transform:translate(-50%)}.tablechart-value[data-place=middle]{color:var(--tablechart-value-color,currentColor);transform:translate(-50%,-50%)}.tablechart-value[data-place=after]{color:var(--tablechart-value-color,currentColor);transform:translateY(-50%)}.tablechart-value[data-place=none]{display:none}.tablechart-value[data-left-out]{visibility:hidden}.tablechart-value[data-active]{visibility:visible}.tablechart-value[data-place=inside][data-kind=up]{color:var(--tablechart-up-ink,oklch(from var(--tablechart-up-color,var(--tablechart-bar-color,currentColor)) calc(.18 + .8 * clamp(0, (.68 - l) * 1000, 1)) 0 0))}.tablechart-value[data-place=inside][data-kind=down]{color:var(--tablechart-down-ink,oklch(from var(--tablechart-down-color,var(--tablechart-bar-color,currentColor)) calc(.18 + .8 * clamp(0, (.68 - l) * 1000, 1)) 0 0))}.tablechart-value[data-place=inside][data-series]{color:var(--tablechart-piece-ink,oklch(from var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas))) calc(.18 + .8 * clamp(0, (.68 - l) * 1000, 1)) 0 0))}.tablechart-value[data-place=inside][data-kind=total]{color:var(--tablechart-total-ink,oklch(from var(--tablechart-total-color,var(--tablechart-bar-color,currentColor)) calc(.18 + .8 * clamp(0, (.68 - l) * 1000, 1)) 0 0))}.tablechart-name{white-space:nowrap;font-size:var(--tablechart-name-size,var(--tablechart-category-size,.95em));color:var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas)));position:absolute;transform:translateY(-50%)}.tablechart-legend{box-sizing:border-box;width:-moz-fit-content;width:fit-content;max-width:100%;padding:var(--tablechart-legend-padding,0);border:var(--tablechart-legend-border,none);border-radius:var(--tablechart-legend-radius,0);background:var(--tablechart-legend-surface,none);margin-inline-start:auto;margin-inline-end:auto;margin-top:var(--tablechart-legend-gap,.6em);font-size:var(--tablechart-name-size,var(--tablechart-category-size,.95em));flex-wrap:wrap;justify-content:center;gap:.3em 1.2em;display:flex}.tablechart-name[data-place=legend]{color:inherit;font-size:inherit;position:static;transform:none}.tablechart-name[data-place=legend]:before{content:"";vertical-align:-.05em;background:var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas)));width:1.6em;height:.8em;-webkit-mask-image:var(--_line), var(--_mark,none);mask-image:var(--_line), var(--_mark,none);margin-right:.4em;display:inline-block;-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.tablechart-name[data-place=legend]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H24'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-line=dashed]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H24' stroke-dasharray='4 2.5' stroke-linecap='butt'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-line=dotted]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H24' stroke-dasharray='0 3'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=circle]{--_mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='12' cy='6' r='3.4' fill='white'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=circle][data-open]{--_mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='12' cy='6' r='3.4'/%3E%3C/svg%3E");--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H8.6 M15.4 6H24'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=circle][data-open][data-line=dashed]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H8.6 M15.4 6H24' stroke-dasharray='4 2.5' stroke-linecap='butt'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=circle][data-open][data-line=dotted]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H8.6 M15.4 6H24' stroke-dasharray='0 3'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=square]{--_mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Crect x='9' y='3' width='6' height='6' stroke-linecap='butt' fill='white'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=square][data-open]{--_mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Crect x='9' y='3' width='6' height='6' stroke-linecap='butt'/%3E%3C/svg%3E");--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H9 M15 6H24'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=square][data-open][data-line=dashed]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H9 M15 6H24' stroke-dasharray='4 2.5' stroke-linecap='butt'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=square][data-open][data-line=dotted]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H9 M15 6H24' stroke-dasharray='0 3'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=diamond]{--_mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpolygon points='12,1.9 16.1,6 12,10.1 7.9,6' fill='white'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=diamond][data-open]{--_mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpolygon points='12,1.9 16.1,6 12,10.1 7.9,6'/%3E%3C/svg%3E");--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H7.9 M16.1 6H24'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=diamond][data-open][data-line=dashed]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H7.9 M16.1 6H24' stroke-dasharray='4 2.5' stroke-linecap='butt'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-marker=diamond][data-open][data-line=dotted]{--_line:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M0 6H7.9 M16.1 6H24' stroke-dasharray='0 3'/%3E%3C/svg%3E")}.tablechart-name[data-place=legend][data-swatch=box]:before{vertical-align:-.05em;background:var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas)));border-radius:.15em;width:.7em;height:.7em;-webkit-mask:none;mask:none}.tablechart-categories :where(span[data-kind=total]){display:none}.tablechart-categories :where(span[data-kind=slice]):before{content:"";width:var(--tablechart-key-size,.6em);height:var(--tablechart-key-size,.6em);background:var(--palette,color-mix(in oklab, var(--tablechart-slice-color,currentColor) max(var(--tablechart-slice-min,20%), calc(100% - var(--n) * var(--tablechart-slice-fade,15%))), var(--tablechart-surface,Canvas)));border-radius:50%;margin-right:.4em;display:inline-block}.tablechart-categories[data-place=key]{box-sizing:border-box;width:-moz-fit-content;width:fit-content;max-width:100%;padding:var(--tablechart-legend-padding,0);border:var(--tablechart-legend-border,none);border-radius:var(--tablechart-legend-radius,0);background:var(--tablechart-legend-surface,none);flex-wrap:wrap;justify-content:center;gap:.3em 1.2em;margin-inline-start:auto;margin-inline-end:auto;display:flex}.tablechart-categories[data-place=key] :where(span){white-space:nowrap;padding:0}.tablechart-categories[data-place=beside]{pointer-events:none;margin:0;display:block;position:absolute;top:0;bottom:0;left:0;right:0}.tablechart-categories[data-place=beside] :where(span){text-align:right;width:max-content;max-width:var(--tablechart-name-max,40%);text-wrap:balance;-webkit-hyphens:auto;hyphens:auto;overflow-wrap:break-word;padding:0;position:absolute;transform:translate(-100%,-50%)}.tablechart-categories{grid-template-columns:repeat(var(--tablechart-columns,1), minmax(0, 1fr));margin-top:var(--tablechart-categories-gap,.45em);display:grid}.tablechart-categories :where(span){text-align:center;padding:var(--tablechart-category-padding,0 .2em);font-size:calc(var(--tablechart-category-size,.95em) * var(--tablechart-name-fit,1));-webkit-hyphens:manual;hyphens:manual;overflow-wrap:normal}.tablechart-bar{fill:var(--tablechart-bar-color,currentColor)}.tablechart-bar[data-kind=up]{fill:var(--tablechart-up-color,var(--tablechart-bar-color,currentColor))}.tablechart-bar[data-kind=down]{fill:var(--tablechart-down-color,var(--tablechart-bar-color,currentColor))}.tablechart-bar[data-kind=total]{fill:var(--tablechart-total-color,var(--tablechart-bar-color,currentColor))}.tablechart-bar[data-series],.tablechart-piece{fill:var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas)))}.tablechart-plot[data-grouped] :where(.tablechart-value){font-size:calc(var(--tablechart-group-value-size,.95em) * var(--tablechart-fit,1))}.tablechart-rule{stroke:var(--tablechart-rule-color,currentColor);stroke-width:var(--tablechart-rule-width,1px);opacity:var(--tablechart-rule-opacity,.45);vector-effect:non-scaling-stroke}.tablechart-connector{stroke:var(--tablechart-connector-color,currentColor);stroke-width:var(--tablechart-connector-width,1px);stroke-dasharray:var(--tablechart-connector-dash,2 3);opacity:var(--tablechart-connector-opacity,.55);fill:none;vector-effect:non-scaling-stroke}.tablechart-series{stroke:var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas)));stroke-width:var(--tablechart-series-width,2px);stroke-linecap:round;fill:none;vector-effect:non-scaling-stroke}.tablechart-area{fill:var(--tablechart-area-color,var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas))));opacity:var(--tablechart-area-opacity,.25)}.tablechart-area[data-muted]{opacity:calc(var(--tablechart-area-opacity,.25) / 2)}.tablechart-area[data-stacked]{opacity:var(--tablechart-area-opacity,.5)}.tablechart-area[data-stacked][data-muted]{opacity:calc(var(--tablechart-area-opacity,.5) / 2)}.tablechart-series[data-line=dashed]{stroke-dasharray:var(--tablechart-dash,6 4);stroke-dashoffset:var(--along,0)}.tablechart-series[data-line=dotted]{stroke-dasharray:var(--tablechart-dot,0 4);stroke-dashoffset:var(--along,0)}.tablechart-point{fill:var(--tablechart-point-color,var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas))))}.tablechart-point[data-open]{fill:none;stroke:var(--tablechart-point-color,var(--tablechart-series-ink,color-mix(in oklab, var(--palette,color-mix(in oklab, var(--tablechart-series-color,var(--tablechart-bar-color,currentColor)) max(var(--tablechart-series-min,40%), calc((100% - var(--n,0) * min(var(--tablechart-series-fade,30%), calc((100% - var(--tablechart-series-min,40%)) / max(var(--tablechart-series-count,2) - 1, 1)))) * (1 - var(--m,0)) + var(--m,0) * 100%)), var(--tablechart-surface,Canvas))) calc(100% - var(--m,0) * (100% - var(--tablechart-muted-share,45%))), var(--tablechart-surface,Canvas))));stroke-width:var(--tablechart-series-width,2px);vector-effect:non-scaling-stroke}.tablechart-slice{fill:none;stroke:var(--palette,color-mix(in oklab, var(--tablechart-slice-color,currentColor) max(var(--tablechart-slice-min,20%), calc(100% - var(--n) * var(--tablechart-slice-fade,15%))), var(--tablechart-surface,Canvas)))}.tablechart-divide{stroke:#000;stroke-width:var(--tablechart-slice-gap,4);fill:none}.tablechart-leader{stroke:var(--tablechart-leader-color,currentColor);stroke-width:var(--tablechart-leader-width,1px);opacity:var(--tablechart-leader-opacity,.45);fill:none;vector-effect:non-scaling-stroke}.tablechart-centre{white-space:nowrap;text-align:center;font-size:var(--tablechart-centre-size,1.6em);color:var(--tablechart-centre-color,currentColor);position:absolute;transform:translate(-50%,-50%)}.tablechart-break[data-part=edge]{fill:none;stroke:var(--tablechart-break-color,currentColor);stroke-width:var(--tablechart-break-width,1px);opacity:var(--tablechart-break-opacity,.55);vector-effect:non-scaling-stroke}.tablechart-line{stroke:var(--tablechart-annotation-color,currentColor);stroke-width:var(--tablechart-annotation-width,1.25px);fill:none;stroke-linecap:butt;stroke-linejoin:miter;vector-effect:non-scaling-stroke}.tablechart-head{fill:var(--tablechart-annotation-color,currentColor)}.tablechart-badge{background:var(--tablechart-badge-surface,none);color:var(--tablechart-annotation-color,currentColor);border:var(--tablechart-badge-border-width,1px) solid currentColor;border-radius:var(--tablechart-badge-radius,50%);padding:var(--tablechart-badge-padding,.5em 1.25em);white-space:nowrap;line-height:1;position:absolute;transform:translate(-50%,-50%)}.tablechart-badge :where(.tablechart-caption){color:var(--tablechart-color,currentColor);background:0 0;border:0;position:absolute;bottom:calc(100% + .45em);left:50%;transform:translate(-50%)}:where([data-animate]) :where(.tablechart-bar){transform-box:fill-box;transform-origin:bottom;transition:transform var(--tablechart-duration,.5s) var(--tablechart-easing,cubic-bezier(.22, .75, .3, 1));transition-delay:calc(var(--i) * var(--tablechart-stagger,.12s));transform:scaleY(0)}:where([data-animate]) :where(.tablechart-bar[data-grow=down]){transform-origin:top}:where([data-animate]) :where(.tablechart-bar[data-grow=right]){transform-origin:0;transform:scaleX(0)}:where([data-animate]) :where(.tablechart-series){stroke-dasharray:var(--len);stroke-dashoffset:var(--len);transition:stroke-dashoffset var(--tablechart-stagger,.12s) linear;transition-delay:calc(max(var(--i) - 1, 0) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-series[data-line]){clip-path:inset(-20px 100% -20px 0);transition:clip-path var(--tablechart-stagger,.12s) linear;transition-delay:calc(max(var(--i) - 1, 0) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-area-fill){opacity:0;transition:opacity calc(max(var(--rows) - 1, 1) * var(--tablechart-stagger,.12s)) ease;transition-delay:calc(max(var(--i) - 1, 0) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-point,.tablechart-hole){opacity:0;transition:opacity var(--tablechart-duration,.5s) ease;transition-delay:calc((var(--i) + .2) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-hole[data-for=badge]){transition:opacity .3s;transition-delay:calc(var(--after) * var(--tablechart-stagger,.12s) + .35s)}:where([data-animate]) :where(.tablechart-value,.tablechart-name){opacity:0;transition:opacity var(--tablechart-duration,.5s) ease;transition-delay:calc((var(--i) + .4) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-connector){stroke-opacity:0;transition:stroke-opacity var(--tablechart-duration,.5s) ease;transition-delay:max(0s, (var(--i) - .45) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-slice){stroke-dasharray:0 var(--circ);transition:stroke-dasharray var(--tablechart-duration,.5s) var(--tablechart-easing,cubic-bezier(.22, .75, .3, 1));transition-delay:calc(var(--i) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-centre){opacity:0;transition:opacity var(--tablechart-duration,.5s) ease;transition-delay:calc((var(--i,0) + .5) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-leader){stroke-opacity:0;transition:stroke-opacity var(--tablechart-duration,.5s) ease;transition-delay:calc((var(--i,0) + .5) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-break[data-part=edge]){stroke-opacity:0;transition:stroke-opacity .2s;transition-delay:calc((var(--after) + .9) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-line){stroke-dasharray:var(--len);stroke-dashoffset:var(--len);transition:stroke-dashoffset var(--tablechart-annotation-duration,.6s) var(--tablechart-easing,cubic-bezier(.22, .75, .3, 1));transition-delay:calc(var(--after) * var(--tablechart-stagger,.12s))}:where([data-animate]) :where(.tablechart-head){opacity:0;transition:opacity .2s;transition-delay:calc(var(--after) * var(--tablechart-stagger,.12s) + .55s)}:where([data-animate]) :where(.tablechart-badge){opacity:0;transition:opacity .3s;transition-delay:calc(var(--after) * var(--tablechart-stagger,.12s) + .35s)}:where([data-animate].is-shown) :where(.tablechart-bar){transform:scaleY(1)}:where([data-animate].is-shown) :where(.tablechart-bar[data-grow=right]){transform:scaleX(1)}:where([data-animate].is-shown) :where(.tablechart-series){stroke-dashoffset:0}:where([data-animate].is-shown) :where(.tablechart-series[data-line]){clip-path:inset(-20px)}:where([data-animate].is-shown) :where(.tablechart-point){opacity:1}:where([data-animate].is-shown) :where(.tablechart-hole){opacity:1}:where([data-animate].is-shown) :where(.tablechart-area-fill){opacity:1}:where([data-animate].is-shown) :where(.tablechart-value){opacity:1}:where([data-animate].is-shown) :where(.tablechart-name){opacity:1}:where([data-animate].is-shown) :where(.tablechart-head){opacity:1}:where([data-animate].is-shown) :where(.tablechart-badge){opacity:1}:where([data-animate].is-shown) :where(.tablechart-centre){opacity:1}:where([data-animate].is-shown) :where(.tablechart-leader){stroke-opacity:1}:where([data-animate].is-shown) :where(.tablechart-break[data-part=edge]){stroke-opacity:1}:where([data-animate].is-shown) :where(.tablechart-slice){stroke-dasharray:var(--arc) calc(var(--circ) - var(--arc))}:where([data-animate].is-shown) :where(.tablechart-connector){stroke-opacity:1}:where([data-animate].is-shown) :where(.tablechart-line){stroke-dashoffset:0}:where([data-animate]){transition:opacity var(--tablechart-queue-duration,.4s) ease}:where([data-animate].tablechart-queued){opacity:0}@media (prefers-reduced-motion:reduce){:where([data-animate]) :where(*){transition-duration:1ms!important;transition-delay:0s!important}}.tablechart-plot[data-active] .tablechart-value:not([data-active]){visibility:hidden}.tablechart-plot[data-pointed] .tablechart-value{transition-delay:0s}.tablechart-plot[data-hover]{cursor:default}.tablechart-plot[data-hover] :where(.tablechart-value){-webkit-user-select:none;user-select:none}.tablechart-pointer{background:var(--tablechart-pointer-color,color-mix(in oklab, currentColor 8%, transparent));pointer-events:none;display:none;position:absolute}.tablechart-plot[data-active]>.tablechart-pointer{display:block}
2
+ /*$vite$:1*/
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Makes a chart of one element, and builds it when it scrolls into view. Returns
3
+ * the chart, or null if the element has no data to draw. If the element is
4
+ * already a chart, returns that chart.
5
+ *
6
+ * ```js
7
+ * import { create } from "@martinomagnifico/tablechart";
8
+ *
9
+ * const chart = await create(document.querySelector("#sales"), { threshold: 0.3 });
10
+ * ```
11
+ */
12
+ export declare const create: (element: HTMLElement, options?: Partial<TablechartConfig>) => Promise<TablechartChart | null>;
13
+
14
+ export declare const defaultConfig: TablechartConfig;
15
+
16
+ /**
17
+ * Makes charts of every element in `root` that matches the selector, and builds
18
+ * each one when it scrolls into view. An element that is already a chart is
19
+ * skipped.
20
+ *
21
+ * ```js
22
+ * import { init } from "@martinomagnifico/tablechart";
23
+ * import "@martinomagnifico/tablechart/style.css";
24
+ *
25
+ * init({ threshold: 0.5 });
26
+ * ```
27
+ */
28
+ export declare const init: (options?: Partial<TablechartConfig>, root?: ParentNode) => Promise<TablechartInstance>;
29
+
30
+ /** One chart, as `create` returns it and as `figure.tablechart` holds it. */
31
+ export declare interface TablechartChart {
32
+ /** The element that holds the chart. */
33
+ figure: HTMLElement;
34
+ /** Lays the chart out again, for example after a script has changed its text. */
35
+ refresh(): void;
36
+ /** Stops watching scroll, size and language. The chart stays as it is. */
37
+ destroy(): void;
38
+ }
39
+
40
+ export declare interface TablechartConfig {
41
+ /** Which elements Tablechart turns into charts. */
42
+ selector: string;
43
+ /** Height of the plot as a share of its width. */
44
+ aspect: number;
45
+ /** Share of a band that a bar fills. */
46
+ barfill: number;
47
+ /** Share of a donut's radius that the ring itself takes. */
48
+ ringfill: number;
49
+ /**
50
+ * Locale for number formatting. Left unset, the document's own language is
51
+ * used and followed when it changes, so a translated page reformats itself.
52
+ */
53
+ locale?: string;
54
+ /** Animate a chart when it builds. */
55
+ animate: boolean;
56
+ /**
57
+ * Where a column's number goes: `outside`, standing on the bar, or `inside`,
58
+ * in the middle of it, in the bar's own ink. A bar too short to hold its
59
+ * number keeps it outside. A figure says otherwise with `data-chart-labels`.
60
+ */
61
+ labels: "outside" | "inside";
62
+ /**
63
+ * Where the names of the lines go, in a chart with several lines: `false` puts
64
+ * each name at the end of its line, `true` puts them all in a legend under the
65
+ * chart. A figure says otherwise with `data-chart-legend`, or
66
+ * `data-chart-legend="false"`.
67
+ */
68
+ legend: boolean;
69
+ /**
70
+ * If a chart has numbers that were left out because there is no room for them,
71
+ * pointing at a row, or tapping it, shows the numbers of that row. The other
72
+ * numbers are hidden for that time. A figure turns it off with
73
+ * `data-chart-hover="false"`.
74
+ */
75
+ hover: boolean;
76
+ /** The name of the total that a donut without a total row works out, for screen readers. */
77
+ totallabel: string;
78
+ /** How much of a chart must be in view before it builds, from 0 to 1. */
79
+ threshold: number;
80
+ /** Build again each time a chart scrolls back into view, not only the first time. */
81
+ replay: boolean;
82
+ /**
83
+ * The attribute that holds translation keys, for a translation script. A figure
84
+ * with `data-chart-keys` gets translation keys on its names. `false` turns them off.
85
+ */
86
+ langattribute: string | false;
87
+ /** Show messages in the console for whoever is working on the page. */
88
+ debug?: boolean;
89
+ }
90
+
91
+ /** What `init` returns: the charts it made, and a way to act on all of them. */
92
+ export declare interface TablechartInstance {
93
+ charts: TablechartChart[];
94
+ /** Lays out every chart again, for example after a script has changed its text. */
95
+ refresh(): void;
96
+ /** Stops watching scroll, size and language. The charts stay as they are. */
97
+ destroy(): void;
98
+ }
99
+
100
+ export { }
101
+
102
+
103
+ declare global {
104
+ interface HTMLElement {
105
+ /** The chart made of this element, by `init` or `create`. */
106
+ tablechart?: TablechartChart;
107
+ }
108
+ }
@@ -0,0 +1 @@
1
+ !function(){var t="tablechart",e="tablechart-value",a="tablechart-bar",n="tablechart-rule",o="tablechart-line",r="tablechart-head",s="tablechart-slice",c="tablechart-legend",i="tablechart-hole",l="tablechart-break",d=1e3,u={selector:"[data-chart]",aspect:.38,barfill:.58,ringfill:.42,animate:!0,labels:"outside",legend:!1,hover:!0,totallabel:"Total",threshold:.5,replay:!1,langattribute:"data-i18n"},h=(t,e)=>`${t}:${e}`,f=(t,e={})=>{const a=document.createElementNS("http://www.w3.org/2000/svg",t);for(const n in e)a.setAttribute(n,String(e[n]));return a},b=(t,e)=>[t,...e.classes].join(" "),m=(t,e)=>{const a=document.createElement("span");return a.className=t,a.inert=!0,e.appendChild(a),a},g=(t,e,a,n,o)=>{t.style.left=e/n*100+"%",t.style.top=a/o*100+"%"},y=0,$=(t,e,a,n)=>{if(!e.length)return;const o="tablechart-cut-"+ ++y,r=f("mask",{id:o,maskUnits:"userSpaceOnUse"});r.appendChild(f("rect",{x:-a,y:-n,width:3*a,height:3*n,fill:"white"}));for(const i of e)i.setAttribute("fill","black"),r.appendChild(i);let s=t.querySelector(":scope > defs");s||(s=f("defs"),t.prepend(s)),s.appendChild(r);const c=f("g",{mask:`url(#${o})`});for(const i of Array.from(t.childNodes))i!==s&&c.appendChild(i);t.appendChild(c)},w=0,p={create:()=>null,draw(t,e,a){const{segments:n,cx:o,y:r,barWidth:s,svg:c,breakAt:i}=a;if(null===i)return;const d=r(i),u=s+.09*s*2,b="zigzag"===t.getAttribute("data-mark"),m=.3*u,g=(t,e)=>{const a=t-u/2;if(!b)return[[a,e+m/2],[a+u,e-m/2]];const n=u/6,o=[[a,e]];for(let r=0;r<6;r++)o.push([a+n*(r+1),e+(r%2==0?-3.38:3.38)]);return o},y=(t,e=!1)=>t.map(([t,e],a)=>`${0===a?"M":"L"} ${t.toFixed(1)} ${e.toFixed(1)}`).join(" ")+(e?" Z":""),$="tablechart-break-"+ ++w,p=f("mask",{id:$,maskUnits:"userSpaceOnUse"});p.appendChild(f("rect",{x:-1e3,y:-a.height,width:3e3,height:3*a.height,fill:"white"}));const v=[];for(const[w,A]of n.entries()){if(Math.min(A.from,A.to)>=i||Math.max(A.from,A.to)<=i)continue;const t=o(w),e=g(t,d-13),n=g(t,d);p.appendChild(f("path",{d:y([...e,...n.slice().reverse()],!0),fill:"black"})),v.push(e,n);const r=h("--after",A.slot);for(const o of[e,n])c.appendChild(f("path",{class:l,"data-part":"edge","data-note":a.note,d:y(o),style:r}))}if(!v.length)return;const k=Array.from(c.querySelectorAll(`.${l}`)),M=f("g",{mask:`url(#${$})`});for(const l of Array.from(c.childNodes))k.includes(l)||M.appendChild(l);const x=f("defs");x.appendChild(p),c.prepend(x,M)}},v=t=>(t.split(/[.,]/)[1]||"").length,k=(t,e,a)=>new Intl.NumberFormat(a||document.documentElement.lang||void 0,{minimumFractionDigits:e,maximumFractionDigits:e}).format(t),M=(t,e)=>{const a=document.createElement("span");if(a.className="tablechart-badge",a.inert=!0,t.childElementCount>0)for(const n of Array.from(t.children))a.appendChild(n.cloneNode(!0));else{a.textContent=(t.textContent||"").trim();const e=t.getAttribute("data-i18n");e&&a.setAttribute("data-i18n",e)}return e.appendChild(a),a},x=(e,a,n,o)=>{const r=(s=e?.textContent||"",Number.parseFloat((s.match(/-?[\d.,]+/)||["NaN"])[0].replace(",",".")));var s;const c=!!Number.isNaN(r)||Math.abs(a-r)<=.5,i={label:n,computed:a,stated:r,agrees:c};o.checks.push(i),c||console.warn(`[${t}] An annotation reads ${r}%, but ${n} is ${a.toFixed(1)}%. The chart shows what you wrote; this is only a check.`)},A={create:M,draw(e,a,n){const{rows:s,cx:c,y:i,unit:l,labelHeight:u,badgeHeight:b,height:m,svg:y,after:$}=n,[w,p]=((t,e)=>{const a=(e,a)=>{const n=Number.parseInt(t.getAttribute(e)??"",10);return Number.isFinite(n)?n-1:a};return[a("data-from",0),a("data-to",e-1)]})(e,s.length),v=s[w],k=s[p];if(!v||!k)return void console.warn(`[${t}] A bracket points at a row that is not there (row ${w+1} to ${p+1}, of ${s.length}).`);const M=7*l,A=4*l,S=c(w),N=c(p),H=Math.min(i(v.value),i(k.value))-u-A-.9*b,T=t=>i(t)-u-A,z=`M ${S} ${T(v.value)} L ${S} ${H} L ${N} ${H} L ${N} ${T(k.value)-M}`,O=(T(v.value)-H+Math.abs(N-S)+(T(k.value)-M-H))/l+1;y.appendChild(f("path",{class:o,"data-note":n.note,d:z,style:`--len:${O.toFixed(1)}; ${h("--after",$)}`}));const L=T(k.value);var U;y.appendChild(f("polygon",{class:r,"data-note":n.note,points:`${N},${L} ${N-.45*M},${L-M} ${N+.45*M},${L-M}`,style:h("--after",$)})),a&&(g(a,(S+N)/2,H,d,m),a.style.setProperty("--after",String($))),x(a,(U=v.value,(k.value-U)/Math.abs(U)*100),`${v.value} to ${k.value}`,n)}},S={create:M,draw(t,e,a){const{rows:n,cx:s,y:c,unit:i,labelHeight:l,height:u,svg:b,values:m,after:y}=a,$=n[0],w=n[n.length-1];if(!$||!w)return;const p=l+18*i,v=10*i,k=10*i;let M=s(0),A=c($.value)-p,S=s(n.length-1),N=c(w.value)-p,H=0;n.forEach((t,e)=>{const a=S===M?0:(s(e)-M)/(S-M),n=A+a*(N-A)-(c(t.value)-p);n>H&&(H=n)}),A-=H,N-=H;const T=S-M,z=N-A,O=Math.hypot(T,z)||1,L=T/O,U=z/O;M-=L*v,A-=U*v,S+=L*v,N+=U*v;const C=Number.parseFloat(t.getAttribute("data-at")||"0.5");if(e){const t=M+(S-M)*C,a=A+(N-A)*C,o=e.offsetWidth*i/2,r=a+e.offsetHeight*i/2+8*i;let d=0;n.forEach((e,a)=>{const n=(m[a]?.offsetWidth||0)*i/2;if(Math.abs(s(a)-t)>=o+n)return;const u=c(e.value)-7*i-l;d=Math.max(d,r-u)}),A-=d,N-=d}const F=S-L*k,E=N-U*k,B=Math.hypot(F-M,E-A)/i+1;b.appendChild(f("line",{class:o,"data-note":a.note,x1:M,y1:A,x2:F,y2:E,style:`--len:${B.toFixed(1)}; ${h("--after",y)}`}));const P=-U,q=L,I=.42*k;b.appendChild(f("polygon",{class:r,"data-note":a.note,points:[`${S},${N}`,`${F+P*I},${E+q*I}`,`${F-P*I},${E-q*I}`].join(" "),style:h("--after",y)})),e&&(g(e,M+(S-M)*C,A+(N-A)*C,d,u),e.style.setProperty("--after",String(y)));const j=Number.parseFloat(t.getAttribute("data-years")||"");!Number.isNaN(j)&&j>0&&x(e,((t,e,a)=>100*(Math.pow(e/t,1/a)-1))($.value,w.value,j),`${$.value} to ${w.value} over ${j} years`,a)}},N=(t,e,a)=>{const n=.15,o=Math.min(.7*t/(e+(e-1)*n),a),r=e*o+(e-1)*o*n;return{size:o,gap:o*n,offset:t=>-r/2+t*o*1.15}},H=(t,e,a)=>{const n=t.series[a],o=t.series.some(t=>t.focus)&&!n.focus;return{"data-series":a+1,...o&&{"data-muted":""},style:`--n:${a}; --m:${o?1:0}; --palette:var(--tablechart-color-${a+1}); ${h("--i",e.slot)}`}},T=(t,e)=>{let a=0;return Array.from({length:e},(e,n)=>{const o=t.cells[n]??t.cells[0],r=a;return!o.missing&&o.value>0&&(a+=o.value),{from:r,to:a,cell:o}})},z=(t,e)=>T(t,e).at(-1)?.to??0,O=(t,e,a)=>{const n=e.series.some(t=>t.focus);t.style.setProperty("--n",String(a)),t.style.setProperty("--m",n&&!e.series[a].focus?"1":"0"),t.style.setProperty("--palette",`var(--tablechart-color-${a+1})`)},L=(t,e,n,o={})=>{const r=f("g",{class:b(a,e),"data-kind":"bar","data-row":n+1,...o,"data-stack":"",style:h("--i",e.slot)});return t.svg.appendChild(r),(a,n)=>{r.appendChild(f("rect",{...n,class:b("tablechart-piece",e),...H(t,e,a)}))}},U=(t,e,a)=>t.some(t=>t.offsetWidth*a>e-6*a),C=(t,e,a)=>e>=t.offsetHeight*a*1.6,F=(t,e,a)=>e>=t.offsetWidth*a*1.5,E=(t,e,a,n,o=.7)=>{t.style.setProperty(n,"1");let r=1;for(const c of e){const{size:t,room:e}=a(c);t>e&&(r=Math.min(r,e/t))}const s=r>=o?r:0;return t.style.setProperty(n,String(s||o)),s},B={segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),series:!0,legend:"box",stackable:!0,totals:!0,aspect:.5,minHeight:({labelHeight:t,nameHeight:e,rows:a,series:n,stacked:o})=>{const r=1.1*t,s=n>1&&!o?r*(n+.15*(n-1))/.7:r/.58;return a*Math.max(s,1.2*e)},categories:"beside",headroom:()=>0,draw(t){const{segments:e,height:o,unit:r,svg:s,values:c,categories:i,config:l,barMax:u}=t,m=t.series.length>1,y=Math.max(...i.map(t=>t.offsetWidth*r),0),$=Math.min(y+10*r,420),w=d-4*r,p=t.stacked?Math.max(...t.rows.map(e=>z(e,t.series.length)),0)||1:Math.max(...t.rows.flatMap(e=>e.cells.slice(0,t.series.length).map(t=>Math.abs(t.value))),0)||1,v=t=>t.offsetWidth*r,k=t=>t.length?Math.max(...t.map(v))+9*r:0;let M=t.stacked?k(t.totals):m?k(t.seriesValues.flat()):0;if(!m)for(let a=0;a<3;a++){const t=w-$-M,a=k(e.map((t,e)=>({seg:t,label:c[e]})).filter(({seg:e,label:a})=>!F(a,Math.abs(e.value)/p*t,r)).map(({label:t})=>t));if(a<=M)break;M=a}const x=w-$-M,A=t=>$+Math.abs(t)/p*x,S=o/e.length,U=t=>(t+.5)*S,C=Math.min(S*l.barfill,u);if(t.stacked)return t.rows.forEach((e,a)=>{const n=L(t,e,a,{"data-grow":"right"}),s=U(a)-C/2,c=T(e,t.series.length);c.forEach(({from:e,to:c,cell:i},l)=>{const u=t.seriesValues[l][a];if(u.dataset.place="none",i.missing||c===e)return;const h=A(e),f=A(c);n(l,{x:h,y:s,width:Math.max(f-h,1),height:C}),u.dataset.place="inside",u.toggleAttribute("data-left-out",!F(u,f-h,r)||u.offsetHeight*r>C),O(u,t,l),g(u,(h+f)/2,U(a),d,o)});const l=t.totals[a];l&&(l.dataset.place="after",g(l,A(c.at(-1)?.to??0)+5*r,U(a),d,o));const u=i[a];u&&g(u,$-8*r,U(a),d,o)}),void s.appendChild(f("line",{class:n,x1:$,x2:$,y1:0,y2:o}));if(m){const e=N(S,t.series.length,u);t.plot.dataset.grouped="";const c=t.seriesValues.flat().filter(t=>void 0===t.dataset.missing),l=E(t.plot,c,t=>({size:t.offsetHeight*r,room:e.size+.5*e.gap}),"--tablechart-fit");return t.rows.forEach((n,c)=>{t.series.forEach((i,u)=>{const h=n.cells[u]??n.cells[0],m=t.seriesValues[u][c];if(h.missing)return void(m.dataset.place="none");const y=A(h.value),w=U(c)+e.offset(u);s.appendChild(f("rect",{class:b(a,n),"data-kind":"bar","data-row":c+1,"data-grow":"right",x:$,y:w,width:Math.max(y-$,1),height:e.size,...H(t,n,u)})),m.dataset.place="after",m.toggleAttribute("data-left-out",!l),g(m,y+5*r,w+e.size/2,d,o)});const u=i[c];u&&g(u,$-8*r,U(c),d,o)}),void s.appendChild(f("line",{class:n,x1:$,x2:$,y1:0,y2:o}))}e.forEach((t,e)=>{const n=A(t.value),l=U(e);s.appendChild(f("rect",{class:b(a,t),"data-kind":t.kind,"data-row":e+1,"data-grow":"right",x:$,y:l-C/2,width:Math.max(n-$,1),height:C,style:h("--i",t.slot)}));const u=c[e],m=F(u,n-$,r);u.dataset.place=m?"inside":"after",u.dataset.kind=t.kind,g(u,m?n-6*r-u.offsetWidth*r/2:n+5*r,l,d,o);const y=i[e];y&&g(y,$-8*r,l,d,o)}),s.appendChild(f("line",{class:n,x1:$,x2:$,y1:0,y2:o}))}},P={segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),series:!0,legend:"box",stackable:!0,totals:!0,breakable:!0,headroom:({labelHeight:t,badgeHeight:e,hasAnnotations:a,unit:n})=>t+4*n+(a?1.6*e:0),draw(t){const{segments:e,cx:o,y:r,barWidth:s,height:c,unit:i,svg:l,values:u,labels:m}=t,y=r(0);if(t.stacked)return t.rows.forEach((e,a)=>{const n=L(t,e,a),l=o(a)-s/2;T(e,t.series.length).forEach(({from:e,to:u,cell:h},f)=>{const b=t.seriesValues[f][a];if(b.dataset.place="none",h.missing||u===e)return;const m=r(u),y=r(e);n(f,{x:l,y:m,width:s,height:Math.max(y-m,1)}),b.dataset.place="inside",b.toggleAttribute("data-left-out",!C(b,y-m,i)||b.offsetWidth*i>s-4*i),O(b,t,f),g(b,o(a),(m+y)/2,d,c)});const u=t.totals[a],h=T(e,t.series.length).at(-1)?.to??0;u&&(u.dataset.place="outside",g(u,o(a),r(h)-4*i,d,c))}),void l.appendChild(f("line",{class:n,x1:0,x2:d,y1:y,y2:y}));if(t.series.length>1){const e=N(o(1)-o(0)||2*o(0),t.series.length,t.barMax);t.plot.dataset.grouped="";const s=t.seriesValues.flat().filter(t=>void 0===t.dataset.missing),u=E(t.plot,s,t=>({size:t.offsetWidth*i,room:e.size+.5*e.gap}),"--tablechart-fit");return t.rows.forEach((n,s)=>{t.series.forEach((h,m)=>{const $=n.cells[m]??n.cells[0],w=t.seriesValues[m][s],p=o(s)+e.offset(m);if($.missing)return void(w.dataset.place="none");const v=r($.value);l.appendChild(f("rect",{class:b(a,n),"data-kind":"bar","data-row":s+1,x:p,y:v,width:e.size,height:Math.max(y-v,1),...H(t,n,m)})),w.dataset.place="outside",w.toggleAttribute("data-left-out",!u),g(w,p+e.size/2,v-4*i,d,c)})}),void l.appendChild(f("line",{class:n,x1:0,x2:d,y1:y,y2:y}))}const $=U(u,s,i);e.forEach((t,e)=>{const n=r(t.value);if(t.missing)return g(u[e],o(e),y-4*i,d,c),void(u[e].dataset.place="outside");l.appendChild(f("rect",{class:b(a,t),"data-kind":t.kind,"data-row":e+1,x:o(e)-s/2,y:n,width:s,height:Math.max(y-n,1),style:h("--i",t.slot)}));const w=y-n,p="inside"===m&&!$&&C(u[e],w,i);g(u[e],o(e),p?n+w/2:n-4*i,d,c),u[e].dataset.place=p?"inside":"outside"}),l.appendChild(f("line",{class:n,x1:0,x2:d,y1:y,y2:y}))}},q=0,I={aspect:.66,centre:!0,headroom:()=>0,segments:t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),draw({rows:t,height:e,unit:a,labelHeight:n,svg:o,values:r,config:c,centre:i}){const l=500,u=e/2,m=(t=>t.filter(t=>!t.isTotal))(t).reduce((t,e)=>t+Math.abs(e.value),0);if(!m)return;const y=1.2*n+10*a,$=Math.max(Math.min(d,e)/2-y,10),w=$*c.ringfill,p=$-w/2,v=2*Math.PI*p,k=[];let M=0,x=0;if(t.forEach((t,c)=>{const i=r[c];if(t.isTotal)return void(i.dataset.place="none");const y=Math.abs(t.value)/m*v,A=M/v*2*Math.PI-Math.PI/2;k.push(A),o.appendChild(f("circle",{class:b(s,t),"data-slice":x+1,"data-row":c+1,cx:l,cy:u,r:p,"stroke-width":w,transform:`rotate(-90 500 ${u})`,"stroke-dasharray":`${y.toFixed(1)} ${(v-y).toFixed(1)}`,"stroke-dashoffset":(-M).toFixed(1),style:`--n:${x}; --palette:var(--tablechart-color-${x+1}); --arc:${y.toFixed(1)}; --circ:${v.toFixed(1)}; ${h("--i",t.slot)}`}));const S=A+y/v*Math.PI,N=Math.cos(S),H=Math.sin(S);o.appendChild(f("line",{class:"tablechart-leader",x1:l+N*($+2*a),y1:u+H*($+2*a),x2:l+N*($+7*a),y2:u+H*($+7*a),"data-row":c+1,style:h("--i",t.slot)}));const T=$+9*a,z=i.offsetWidth*a/2;g(i,l+N*(T+Math.abs(N)*z),u+H*(T+Math.abs(H)*n*.7),d,e),i.dataset.place="around",M+=y,x+=1}),k.length>1){const t=p-w/2-1,a=p+w/2+1,n="tablechart-slices-"+ ++q,r=f("mask",{id:n,maskUnits:"userSpaceOnUse"});r.appendChild(f("rect",{x:0,y:0,width:d,height:e,fill:"white"}));for(const e of k)r.appendChild(f("line",{class:"tablechart-divide",x1:l+Math.cos(e)*t,y1:u+Math.sin(e)*t,x2:l+Math.cos(e)*a,y2:u+Math.sin(e)*a}));const c=f("g",{mask:`url(#${n})`});for(const e of Array.from(o.querySelectorAll(`.${s}`)))c.appendChild(e);const i=f("defs");i.appendChild(r),o.prepend(i,c)}i&&g(i,l,u,d,e)}},j=["circle","square","diamond"],K=(t,e)=>{const a=t[e]?.marker?.toLowerCase().split(/\s+/)??[],n=j.find(t=>a.includes(t));return{shape:n??j[Math.floor(e/2)%j.length],open:a.includes("open")||!a.includes("filled")&&!n&&e%2==1}},R=(t,e,a,n,o={})=>{if("square"===t){const t=.88*n;return f("rect",{x:e-t,y:a-t,width:2*t,height:2*t,...o})}if("diamond"===t){const t=1.2*n;return f("polygon",{points:`${e},${a-t} ${e+t},${a} ${e},${a+t} ${e-t},${a}`,...o})}return f("circle",{cx:e,cy:a,r:n,...o})},V=t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"})),W=t=>({segments:V,breakable:!0,series:!0,stackable:!0,swatch:t?"box":void 0,headroom:({labelHeight:t,unit:e})=>1.6*t+6*e,footroom:({labelHeight:e,unit:a,series:n,focused:o,stacked:r})=>t||r||2!==n||o?0:e+7*a,draw(e){const{rows:a,series:o,seriesValues:r,names:s,cx:c,y:l,height:u,unit:b,labelHeight:m,svg:y,stacked:w}=e,p="step"===e.shape,v=l(0),k=o.length>1,M=o.some(t=>t.focus),x=a.length-1,A=(t,e)=>a[e]?.cells[t]??a[e]?.cells[0],S=a.map(t=>w?T(t,o.length):null),N=(t,e)=>S[e]?.[t].to??A(t,e)?.value??0,H=(t,e)=>S[e]?.[t].from??0,z=(t,e)=>[c(e),l(N(t,e))],O=(t,e)=>!A(t,e)||!!A(t,e)?.missing,L=o.map((t,e)=>{if(!k)return{attrs:{},ink:""};const a=M&&!t.focus;return{attrs:{"data-series":e+1,...a&&{"data-muted":""}},ink:`--n:${e}; --m:${a?1:0}; --palette:var(--tablechart-color-${e+1}); `}}),U=(t,e)=>h("--i",a[e].slot),C=a.length>1?c(1)-c(0):2*c(0),F=t=>a.map((e,a)=>({i:a,next:a<x&&!O(t,a+1)})).filter(({i:e,next:a})=>!O(t,e)&&(p||a));if(t&&o.forEach((t,e)=>{const n=f("g",{class:"tablechart-area",...L[e].attrs,...w&&{"data-stacked":""},style:L[e].ink}),o=F(e),r=f("g",{class:"tablechart-area-fill",style:`--rows:${a.length}; ${o.length?U(0,p?o[0].i:o[0].i+1):""}`});n.appendChild(r);for(const{i:a,next:s}of o){const t=p?c(a)-C/2:c(a),n=p?c(a)+C/2:c(a+1),[o,i]=[l(N(e,a)),l(H(e,a))],[d,u]=p?[o,i]:[l(N(e,a+1)),l(H(e,a+1))],h=p?a+1:a+2,m=p?s:a+1<x&&!O(e,a+2);let g=m?1.5*b:0;const y=(t,e,a,n)=>(e-t)/(n-a),$=(e,a,o)=>[p?e:e+y(a,e,t,n)*g,p?o:e+y(e,o,n,c(h))*g],w=m?Math.max(...$(d,o,l(N(e,h)))):d,v=m?Math.min(...$(u,i,l(H(e,h)))):u;w>=v&&(g=0);const k=p?[[t,i],[t,o],[n,o],[n,w],[n+g,w],[n+g,v],[n,v],[n,i]]:[[t,i],[t,o],[n,d],[n+g,w],[n+g,v],[n,u]];r.appendChild(f("polygon",{points:k.map(t=>t.join(",")).join(" "),"data-row":(p?a:a+1)+1,style:U(0,p?a:a+1)}))}y.appendChild(n)}),o.forEach((t,e)=>{let a=0;for(const{i:n,next:o}of F(e)){const r=p?[[c(n)-C/2,l(N(e,n))],[c(n)+C/2,l(N(e,n))],...o?[[c(n)+C/2,l(N(e,n+1))]]:[]]:[z(e,n),z(e,n+1)];let s=1;for(let t=1;t<r.length;t++){const[[e,a],[n,o]]=[r[t-1],r[t]];s+=Math.hypot(n-e,o-a)/b}y.appendChild(f("polyline",{class:"tablechart-series",...L[e].attrs,points:r.map(t=>t.join(",")).join(" "),...t.line&&{"data-line":t.line},"data-row":(p?n:n+1)+1,style:`${L[e].ink}--len:${s.toFixed(1)}; --along:${(-a).toFixed(1)}; ${U(0,p?n:n+1)}`})),a+=s-1}}),!p){const t=o.map((t,e)=>k?K(o,e):{shape:"circle",open:!1});$(y,o.flatMap((e,n)=>t[n].open?a.flatMap((e,a)=>{if(O(n,a))return[];const[o,r]=z(n,a);return[R(t[n].shape,o,r,4*b,{class:i,"data-row":a+1,...k&&{"data-series":n+1},style:U(0,a)})]}):[]),d,u),o.forEach((e,n)=>{a.forEach((e,a)=>{if(O(n,a))return;const[o,r]=z(n,a);y.appendChild(R(t[n].shape,o,r,4*b,{class:"tablechart-point",...L[n].attrs,"data-marker":t[n].shape,...t[n].open&&{"data-open":""},"data-row":a+1,style:`${L[n].ink}${U(0,a)}`}))})})}const E=(t,e)=>{let a=e;for(;a<x&&!O(t,a+1)&&A(t,a+1)?.value===A(t,e)?.value;)a++;return a};r.forEach((e,a)=>{e.forEach((e,n)=>{const s=((e,a)=>{const n=A(e,a);if(!n||n.missing)return"none";if(p&&a>0&&!O(e,a-1)&&A(e,a-1)?.value===n.value)return"none";if(M&&!o[e].focus)return"none";if(w)return"middle";if(!k||M||o.length>2)return"above";const r=A(1-e,a);return!r||r.missing||n.value>r.value||n.value===r.value&&0===e||t&&z(e,a)[1]+7*b+m>v?"above":"below"})(a,n);if(e.dataset.place="above"===s?"outside":s,e.toggleAttribute("data-left-out","none"!==s&&((t,e)=>w||p?r[t][e].offsetWidth*b>(p?E(t,e)-e+1:1)*C-4*b||w&&l(H(t,e))-l(N(t,e))<1.2*m:k&&!M&&o.length>2)(a,n)),p&&"none"!==s?e.dataset.rowEnd=String(E(a,n)+1):delete e.dataset.rowEnd,"none"===s)return;const i=e.offsetWidth*b/2+4*b,h=p?(c(n)+c(E(a,n)))/2:"middle"===s&&0===n?c(n)+i:"middle"===s&&n===x?c(n)-i:c(n),f=l(N(a,n));g(e,h,"middle"===s?(f+l(H(a,n)))/2:"above"===s?f-7*b:f+7*b,d,u)})});const B=s.map((t,e)=>{let a=x;for(;a>0&&O(e,a);)a--;const[n,o]=z(e,a);return{name:t,x:(p?n+C/2:n)+10*b,y:w?(o+l(H(e,a)))/2:o}}),P=(s[0]?.offsetHeight||0)*b;for(const t of((t,e)=>(t.sort((t,e)=>t.y-e.y),t.forEach((a,n)=>{const o=t[n-1];o&&a.y<o.y+e&&(a.y=o.y+e)}),t))(B,P))g(t.name,t.x,t.y,d,u);const q=t||w||2!==o.length||M?v:u-2*b;y.appendChild(f("line",{class:n,x1:0,x2:c(x)+c(0),y1:q,y2:q}))}}),D=W(!1),G=W(!0),Z={segments:t=>{let e=0;return t.map(t=>{if(t.isTotal)return e=t.value,{...t,from:0,to:t.value,kind:"total"};const a=e;return e+=t.value,{...t,from:a,to:e,kind:t.value>=0?"up":"down"}})},breakable:!0,headroom:({labelHeight:t,badgeHeight:e,hasAnnotations:a,unit:n})=>t+6*n+(a?1.6*e:0),draw({segments:t,cx:e,y:o,barWidth:r,height:s,unit:c,svg:i,values:l,breakAt:u}){const m=o(0),y=U(l,r,c);t.forEach((a,n)=>{const s=t[n+1];if(!s)return;const c=o(a.to),l=e(n)+r/2,d=e(n+1)-r/2;i.appendChild(f("line",{class:"tablechart-connector",x1:l,x2:d,y1:c,y2:c,"data-row":n+2,style:h("--i",s.slot)}))}),t.forEach((t,n)=>{const m=o(Math.max(t.from,t.to)),$=Math.abs(o(t.from)-o(t.to));i.appendChild(f("rect",{class:b(a,t),"data-kind":t.kind,"data-row":n+1,"data-grow":"down"===t.kind?"down":"up",x:e(n)-r/2,y:m,width:r,height:Math.max($,1),style:h("--i",t.slot)}));const w=l[n],p=!(null!==u&&Math.min(t.from,t.to)<u&&Math.max(t.from,t.to)>u)&&!y&&C(w,$,c);w.dataset.place=p?"inside":"outside",w.dataset.kind=t.kind;const v=p?m+$/2:"down"===t.kind?m+$+w.offsetHeight*c+3*c:m-3*c;g(w,e(n),v,d,s)}),i.appendChild(f("line",{class:n,x1:0,x2:d,y1:m,y2:m}))}},J={enabled:!1,log(...e){J.enabled&&console.log(`[${t}]`,...e)}},Q=t=>{const e=(t?.textContent||"").trim(),a=e.match(/^(.*?)(-?\d+(?:[.,]\d+)?)(.*)$/);return{raw:e,number:a?.[2]??"",prefix:a?.[1]??"",suffix:a?.[3]??"",missing:!a,value:a?Number.parseFloat(a[2].replace(",",".")):0}},X=t=>Array.from(t.querySelector("thead tr:last-child")?.children??[]).slice(1),Y={area:G,bar:B,column:P,donut:I,line:D,waterfall:Z},_={"axis-break":p,trend:S,bracket:A},tt=Object.keys(_),et=t=>{let e="";for(let a=t.previousSibling;a&&(e=(a.textContent??"")+e,!e.trim());a=a.previousSibling);return e.trim()},at=0,nt=(a,n,o=null)=>{const r=o??(a.getAttribute("data-chart")||"column"),s=Y[r];if(!s)return console.warn(`[${t}] Unknown chart type "${r}". Known types: ${Object.keys(Y).join(", ")}.`),null;const i=((t,e="data-i18n")=>Array.from(t.querySelectorAll("tbody tr")).map((t,a)=>{const n=t.querySelector("th"),o=Array.from(t.querySelectorAll("td")).map(Q);return o.length||o.push(Q(null)),{...o[0],label:(n?.textContent||"").trim(),key:e&&n?.getAttribute(e)||null,cells:o,classes:Array.from(t.classList),isTotal:"total"===t.getAttribute("data-kind"),slot:a}}))(a,n.langattribute);if(!i.length)return console.warn(`[${t}] A chart has no rows in its table, so there is nothing to draw.`),null;(t=>{const e=t.querySelector(":scope > figcaption");if(!e)return;(t=>{for(const e of t.querySelectorAll("br")){if(e.previousElementSibling?.classList.contains("tablechart-sr"))continue;if(/[.!?:;,…]$/.test(et(e)))continue;const t=document.createElement("span");t.className="tablechart-sr",t.textContent=". ",e.before(t)}})(e);const a=t=>t.hasAttribute("aria-label")||t.hasAttribute("aria-labelledby"),n=t=>{e.id||(e.id="tablechart-caption-"+ ++at),t.setAttribute("aria-labelledby",e.id)};"FIGURE"!==t.tagName||a(t)||n(t);const o=t.querySelector("table");!o||a(o)||o.querySelector(":scope > caption")||n(o)})(a);let l=((t,e,a="data-i18n")=>{const n=X(t),o=Math.max(1,...e.map(t=>t.cells.length));return Array.from({length:o},(t,e)=>{const o=n[e];return{name:(o?.textContent||"").trim(),key:a&&o?.getAttribute(a)||null,focus:"focus"===o?.getAttribute("data-kind"),marker:o?.getAttribute("data-marker")??null,line:(r=o?.getAttribute("data-line"),"dashed"===r||"dotted"===r?r:null)};var r})})(a,i,n.langattribute);l.length>1&&!s.series&&(console.warn(`[${t}] A ${r} chart draws one series; only the first of the table's ${l.length} value columns is used.`),l=l.slice(0,1));const d=l.length>1;d&&a.style.setProperty("--tablechart-series-count",String(l.length));const u=a.hasAttribute("data-chart-stack");u&&!s.stackable&&console.warn(`[${t}] A ${r} chart cannot be stacked.`);const h=u&&!!s.stackable&&d;h&&i.some(t=>t.cells.slice(0,l.length).some(t=>t.value<0))&&console.warn(`[${t}] A stacked chart has a value below zero. It takes no room in the stack.`);const b=document.createElement("div");b.className="tablechart-plot",b.setAttribute("aria-hidden","true");const g=f("svg",{role:"presentation",focusable:"false"});b.appendChild(g),a.appendChild(b);const y=s.centre?i.filter(t=>!t.isTotal):i,$=Math.max(0,...y.flatMap(t=>t.cells.slice(0,l.length).map(t=>v(t.number)))),w=l.map((t,a)=>i.map((t,n)=>{const o=t.cells[a]??t.cells[0],r=m(e,b);return r.classList.add(...t.classes),r.dataset.value=String(o.value),o.prefix&&(r.dataset.prefix=o.prefix),o.suffix&&(r.dataset.suffix=o.suffix),o.missing&&(r.dataset.missing=o.raw),d&&(r.dataset.series=String(a+1)),r.dataset.row=String(n+1),r.style.setProperty("--i",String(t.slot)),r})),p=w[0],k=h&&s.totals?i.map((t,a)=>{const n=m(e,b);n.classList.add(...t.classes),n.dataset.kind="total",n.dataset.row=String(a+1),n.dataset.value=String(z(t,l.length));const o=t.cells[0];return o.prefix&&(n.dataset.prefix=o.prefix),o.suffix&&(n.dataset.suffix=o.suffix),n.style.setProperty("--i",String(t.slot)),n}):[],M=i[i.length-1],x=l.some(t=>t.focus),A=a.getAttribute("data-chart-legend"),S=d&&(null===A?n.legend||void 0!==s.legend:"false"!==A)?document.createElement("div"):null;S&&(S.className=c,S.setAttribute("aria-hidden","true"),S.inert=!0);const N=d?l.map((t,e)=>{const o=m("tablechart-name",S??b);S&&(o.dataset.place="legend");const r=s.legend??s.swatch;if(r&&(o.dataset.swatch=r),o.textContent=t.name,!r&&"step"!==a.dataset.chartShape){const t=K(l,e);o.dataset.marker=t.shape,o.toggleAttribute("data-open",t.open)}return t.line&&!r&&(o.dataset.line=t.line),t.key&&n.langattribute&&o.setAttribute(n.langattribute,t.key),o.dataset.series=String(e+1),o.style.setProperty("--n",String(e)),o.style.setProperty("--palette",`var(--tablechart-color-${e+1})`),o.style.setProperty("--m",x&&!t.focus?"1":"0"),o.style.setProperty("--i",String(M.slot)),o}):[],H=s.centre?m("tablechart-centre",b):null;if(H){const t=i.find(t=>t.isTotal),e=t?t.value:i.reduce((t,e)=>t+Math.abs(e.value),0);H.dataset.value=String(e),t&&(H.dataset.decimals=String(v(t.number)))}const T=H&&!i.some(t=>t.isTotal)?((t,e,a)=>{const n=t.querySelector("table");if(!n)return null;const o=n.querySelector("tfoot [data-chart-total]");if(o)return o.dataset.value=e.dataset.value??"0",o;const r=(n.tFoot??n.createTFoot()).insertRow(),s=document.createElement("th");s.scope="row",s.textContent=a.totallabel;const c=t.getAttribute("data-chart-keys");c&&a.langattribute&&s.setAttribute(a.langattribute,`${c}-total`);const i=r.insertCell();return i.setAttribute("data-chart-total",""),i.dataset.value=e.dataset.value??"0",r.prepend(s),i})(a,H,n):null,O="beside"===s.categories,L=document.createElement("div");L.className="tablechart-categories",L.setAttribute("aria-hidden","true"),L.inert=!0,O?L.dataset.place="beside":s.centre&&(L.dataset.place="key"),L.style.setProperty("--tablechart-columns",String(i.length));let U=0;for(const t of i){const e=document.createElement("span");e.classList.add(...t.classes),e.textContent=t.label,t.key&&n.langattribute&&e.setAttribute(n.langattribute,t.key),s.centre&&(e.dataset.kind=t.isTotal?"total":"slice",t.isTotal||(e.dataset.slice=String(U+1),e.style.setProperty("--n",String(U)),e.style.setProperty("--palette",`var(--tablechart-color-${U+1})`),U+=1)),e.style.setProperty("--i",String(t.slot)),e.dataset.row=String(i.indexOf(t)+1),L.appendChild(e)}(O?b:a).appendChild(L),S&&a.appendChild(S);const C=Array.from(a.querySelectorAll("[data-annotation]")).map(e=>{const a=e.getAttribute("data-annotation"),n=_[a];if(!n)return console.warn(`[${t}] Unknown annotation "${a}". Known annotations: ${Object.keys(_).join(", ")}.`),null;const o=Number.parseInt(e.getAttribute("data-series")??"1",10),r=o>=1&&o<=l.length?o-1:0;return o!==r+1&&console.warn(`[${t}] An annotation reads line ${o}, which the chart does not have; it reads the first.`),{spec:e,type:n,badge:n.create(e,b),series:r,after:i.length}}).filter(t=>null!==t);n.animate&&a.setAttribute("data-animate","");const F={figure:a,plot:b,svg:g,rows:i,decimals:$,type:s,values:p,series:l,seriesValues:w,names:S?[]:N,categories:Array.from(L.children),centre:H,stacked:h,totals:k,totalCell:T,rowAt:null,rowBox:null,annotations:C,checks:[]};return n.hover&&"false"!==a.getAttribute("data-chart-hover")&&it(F),st(F,n),F},ot=(t,e,a,n)=>{const o=getComputedStyle(t),r=(o.getPropertyValue(a).trim()||n).match(/^(\d+(?:\.\d+)?)(px|%|em|rem)$/);if(!r)return null;const s=Number(r[1]);return"%"===r[2]?s/100*d:s*("em"===r[2]?Number.parseFloat(o.fontSize):"rem"===r[2]?Number.parseFloat(getComputedStyle(document.documentElement).fontSize):1)*e},rt=(t,e)=>ot(t,e,"--tablechart-bar-max","60px")??Number.POSITIVE_INFINITY,st=(t,e)=>{const a=[...t.seriesValues.flat(),...t.totals,...t.totalCell?[t.totalCell]:[]];for(const n of t.centre?[...a,t.centre]:a){const{missing:a,prefix:o="",suffix:r=""}=n.dataset;n.textContent=void 0===a?o+k(Number.parseFloat(n.dataset.value||"0"),n.dataset.decimals?Number(n.dataset.decimals):t.decimals,e.locale)+r:a}},ct=(t,e)=>{t.figure.classList.toggle("is-shown",e),e||t.plot.removeAttribute("data-pointed")},it=t=>{const{plot:e}=t,a=()=>[...t.seriesValues.flat(),...t.totals];e.setAttribute("data-hover","");const n=document.createElement("div");n.className="tablechart-pointer",e.prepend(n);const o=()=>{e.removeAttribute("data-active");for(const t of a())t.removeAttribute("data-active")},r=r=>{if(!e.classList.contains("is-placed")||!t.rowAt)return;const s=e.getBoundingClientRect(),c=s.width/e.offsetWidth||1,i=t.rowAt((r.clientX-s.left)/c,(r.clientY-s.top)/c),l=null===i?null:i+1,d=t=>"none"!==t.dataset.place,u=null===l?[]:a().filter(t=>((t,e)=>{const a=Number(t.dataset.row),n=Number(t.dataset.rowEnd??a);return e>=a&&e<=n})(t,l)&&d(t));if(!a().some(t=>t.hasAttribute("data-left-out")&&d(t))||!u.length)return o();e.setAttribute("data-pointed",""),e.setAttribute("data-active",String(l));const[h,f,b,m]=t.rowBox?.(l-1)??[0,0,0,0];Object.assign(n.style,{left:`${h}%`,top:`${f}%`,width:`${b}%`,height:`${m}%`});for(const t of a())t.toggleAttribute("data-active",u.includes(t))};e.addEventListener("pointermove",r),e.addEventListener("pointerdown",r),e.addEventListener("pointerleave",t=>{"mouse"===t.pointerType&&o()}),document.addEventListener("pointerdown",t=>{e.contains(t.target)||o()})},lt=t=>"id"===t||"style"===t||t.startsWith("data-chart"),dt=/^\s*(?:Table)?:\s+/,ut=t=>"P"===t?.tagName&&dt.test(t.textContent??""),ht=/^\s*([a-z][\w-]*)((?:\s+[\w-]+=[^\s:]+)*)\s*(:\s*|$)/,ft=t=>{const e=bt(t);return"P"===e?.tagName?e:t},bt=t=>{const e=Array.from(t.childNodes).filter(t=>t.nodeType===Node.ELEMENT_NODE||t.nodeType===Node.TEXT_NODE&&t.textContent?.trim());return 1===e.length&&e[0]instanceof HTMLElement?e[0]:null},mt="strong, b, span.total",gt="data-chart-made",yt=()=>window.matchMedia("(prefers-reduced-motion: reduce)").matches,$t=new Set,wt=null,pt=["column","bar"],vt=t=>{const e=t.getAttribute("data-chart")||"column";if(!pt.includes(e))return null;const a=getComputedStyle(t).getPropertyValue("--tablechart-type").trim();return pt.includes(a)?a:e},kt=async(e,a)=>{const n=(t=>t.map(t=>{const e=t.closest("p"),a=ut(e)?e:t;if("TABLE"!==a.tagName&&"P"!==a.tagName)return a;const n=document.createElement("div");((t,e)=>{for(const{name:a,value:n}of Array.from(t.attributes))("class"===a||lt(a))&&(e.setAttribute(a,n),t.removeAttribute(a))})(t,n),t.classList.length||t.removeAttribute("class");const o="TABLE"===a.tagName?a:null,r=a.previousElementSibling;let s=a.nextElementSibling;const c=o?ut(r)?r:ut(s)?s:null:a;o&&c===s&&(s=s?.nextElementSibling??null);const i=s?.classList.contains("chart-annotations")?s:(t=>{if("UL"!==t?.tagName&&"OL"!==t?.tagName)return null;const e=Array.from(t.children),a=e.map(t=>t.hasAttribute("data-annotation")?null:(t=>{const e=ft(t).firstChild;if(e?.nodeType!==Node.TEXT_NODE)return null;const a=ht.exec(e.textContent??"");if(!a||!tt.includes(a[1]))return null;if(!a[3]&&e.nextSibling)return null;const n=a[2].trim().split(/\s+/).filter(Boolean).map(t=>t.split("="));return{name:a[1],options:n,text:e,length:a[0].length}})(t));return!e.length||e.some((t,e)=>!a[e]&&!t.hasAttribute("data-annotation"))?null:(e.forEach((t,e)=>{const n=a[e],o=ft(t);if(o!==t&&o.replaceWith(...o.childNodes),n){t.setAttribute("data-annotation",n.name);for(const[e,a]of n.options)t.setAttribute(`data-${e}`,a);n.text.textContent=(n.text.textContent??"").slice(n.length)}t.children.length&&Array.from(t.childNodes).filter(t=>t.nodeType===Node.ELEMENT_NODE||t.textContent?.trim()).forEach((t,e)=>{const a=document.createElement("span");0===e&&t instanceof HTMLElement&&t.matches("em, i")?(a.className="tablechart-caption",a.append(...t.childNodes),t.replaceWith(a)):t.nodeType===Node.TEXT_NODE&&(a.textContent=(t.textContent??"").trim(),t.replaceWith(a))})}),t.classList.add("chart-annotations"),t)})(s);return a.replaceWith(n),c&&n.append((t=>{const e=document.createElement("figcaption");for(const{name:r,value:s}of Array.from(t.attributes))e.setAttribute(r,s);const a=t.firstChild;a?.nodeType===Node.TEXT_NODE&&(a.textContent=(a.textContent??"").replace(dt,""),a.textContent||a.remove());const n=Array.from(t.childNodes),o=n.findIndex(t=>"BR"===t.nodeName);if(e.append(...-1===o?n:n.slice(0,o+1)),-1!==o&&o<n.length-1){const t=document.createElement("span");t.append(...n.slice(o+1)),e.append(t)}return t.remove(),e})(c)),o&&n.append(o),i&&n.append(i),J?.log?.(`A ${o?"table":"caption"} with chart attributes was wrapped in a figure of its own`),n}))(e.filter(t=>!t.hasAttribute(gt)));return await(async e=>{await Promise.all(e.filter(t=>t.hasAttribute("data-chart-src")).map(async e=>{const a=e.getAttribute("data-chart-src");for(const t of e.querySelectorAll("table"))t.remove();try{const t=await fetch(a);if(!t.ok)throw new Error(`${t.status} ${t.statusText}`);const n=await t.json(),o=Array.isArray(n)?n:n?.rows;if(!Array.isArray(o))throw new Error("no array of rows in it");const r=Array.isArray(n?.series)?n.series.map(String):[],s=e.querySelector(":scope > figcaption"),c=((t,e=[])=>{const a=document.createElement("table");if(e.length){const t=a.createTHead().insertRow();t.append(document.createElement("th"));for(const a of e){const e=document.createElement("th");e.textContent=a,t.append(e)}}const n=a.createTBody();for(const o of t){const t=n.insertRow();"total"===o.kind&&(t.dataset.kind="total");const e=document.createElement("th");e.textContent=String(o.label??""),t.append(e);for(const a of o.values??[o.value??null])t.insertCell().textContent=null===a?"":String(a)}return a})(o,r);s?s.after(c):e.prepend(c),J?.log?.(`Read ${o.length} rows from "${a}"`)}catch(n){const e="file:"===window.location.protocol;console.warn(`[${t}] Could not read the chart data in "${a}": ${n.message}.`+(e?" A page opened from the file system cannot fetch files; open the page from a server instead.":""))}}))})(n),(t=>{for(const e of t){for(const a of e.querySelectorAll("tbody tr")){const t=a.cells[0];if("TD"!==t?.tagName||a.cells.length<2)continue;const e=document.createElement("th");for(const{name:a,value:n}of Array.from(t.attributes))e.setAttribute(a,n);e.append(...t.childNodes),t.replaceWith(e);for(let n=bt(e);n?.matches(mt);n=bt(e))a.dataset.kind="total",n.replaceWith(...n.childNodes)}const t=Array.from(e.querySelector("thead tr:last-child")?.children??[]);for(const e of t.slice(1))for(let t=bt(e);t?.matches(mt);t=bt(e))e.setAttribute("data-kind","focus"),t.replaceWith(...t.childNodes)}})(n),((e,a)=>{if(!a)return;const n=new Map;for(const o of e){let e=o.getAttribute("data-chart-keys")||null;if(!e)continue;if(n.has(e)){const a=n.get(e)+1;n.set(e,a),console.warn(`[${t}] Two charts on the page have data-chart-keys="${e}". If two charts use the same keys, they get the same translations. This one uses "${e}-${a}".`),e=`${e}-${a}`}else n.set(e,1);o.querySelectorAll("tbody th").forEach((t,n)=>{t.getAttribute(a)||t.setAttribute(a,`${e}-row${n+1}`)});const r=X(o);r.length>1&&r.forEach((t,n)=>{t.getAttribute(a)||t.setAttribute(a,`${e}-col${n+1}`)}),J?.log?.(`Keys for "${e}" written onto ${o.querySelectorAll("tbody th").length} rows`)}})(n,a.langattribute),n},Mt=(e,a)=>{const n=nt(e,a);return n?(e.setAttribute(gt,""),((e,a)=>{let n=e,o=vt(n.figure),r=null,s=!1,l=!1;const u=async()=>{if(!a.animate)return ct(n,!0);const t=n.figure.classList.contains("is-shown");if(!s||null===r||t||l)!s&&a.replay&&t&&ct(n,!1);else{l=!0;const t=yt()?null:(t=>{for(let e=t;e&&e!==document.body;e=e.parentElement)if("0"===getComputedStyle(e).opacity)return e;return null})(n.figure);t&&await(e=t,new Promise(t=>{const a=["animationstart","transitionrun"],n=()=>{for(const t of a)document.removeEventListener(t,o,!0);r.disconnect(),t()},o=t=>{t.target instanceof Node&&t.target.contains(e)&&n()},r=new MutationObserver(()=>{"0"!==getComputedStyle(e).opacity&&n()});for(const e of a)document.addEventListener(e,o,!0);r.observe(e,{attributes:!0,attributeFilter:["class","style"]})})),await(async t=>{if(yt())return;await new Promise(requestAnimationFrame);const e=t.getAnimations().filter(t=>t instanceof CSSAnimation);for(let o=t.parentElement;o&&o!==document.body;o=o.parentElement)e.push(...o.getAnimations());let a=0;for(const o of e){const t=o.effect?.getComputedTiming(),e=Number(t?.activeDuration??0);if(!t||!Number.isFinite(e))continue;const n=Number(t.delay??0)+e/2;a=Math.max(a,n-Number(o.currentTime??0))}var n;a>0&&await(n=a,new Promise(t=>setTimeout(t,n)))})(n.figure),l=!1,!s&&a.replay||ct(n,!0)}var e},h=()=>{const t=vt(n.figure);if(!t||t===o)return;const e=nt(n.figure,a,t);e&&((t=>{t.plot.remove(),t.categories[0]?.parentElement?.remove(),t.figure.querySelector(`:scope > .${c}`)?.remove()})(n),n=e,o=t,r=null)},b=()=>{h();const e=n.plot.clientWidth;e&&e!==r&&((e,a)=>{const{plot:n,svg:o,rows:r,type:s,values:c,series:l,seriesValues:u,names:h,annotations:b}=e,m=n.clientWidth;if(!m)return!1;const g=d/m,y=Number.parseFloat(e.figure.dataset.chartAspect??""),w=d*(y>0?y:s.aspect??a.aspect);n.classList.add("is-placed");const p=(c[0]?.offsetHeight||0)*g,v=b[0]?.badge?b[0].badge.offsetHeight*g:0,k=Math.max(w,ot(e.figure,g,"--tablechart-min-height","200px")??0,s.minHeight?.({labelHeight:p,nameHeight:Math.max(0,...e.categories.map(t=>t.offsetHeight))*g,unit:g,rows:r.length,series:l.length,stacked:e.stacked})??0),M=e.stacked?r.map(t=>{const e=z(t,l.length);return{...t,value:e,cells:t.cells.map((t,a)=>0===a?{...t,value:e}:t)}}):r,x=(s.segments??(t=>t.map(t=>({...t,from:0,to:t.value,kind:"bar"}))))(e.stacked?M.map(t=>({...t,cells:[t.cells[0]]})):r),A={labelHeight:p,badgeHeight:v,hasAnnotations:b.length>0,unit:g,series:l.length,focused:l.some(t=>t.focus),stacked:e.stacked},S=s.headroom?.(A)??p,N=2*g+(s.footroom?.(A)??0),H=S,T=e.stacked?Math.max(...M.map(t=>t.value),0):Math.max(...x.flatMap(t=>[t.from,t.to,t.value]),...r.flatMap(t=>t.cells.slice(0,l.length).map(t=>t.value))),O=k-H-N,L=1.02*T,U=b.find(t=>"axis-break"===t.spec.getAttribute("data-annotation"))?.spec,C=t=>{const e=Number.parseFloat(U?.getAttribute(t)??"");return Number.isFinite(e)?e:null},F=C("data-from")??C("data-at"),B=C("data-to");let P=null;if(U&&(null!==F||null!==B)){const e=F??0,a=B??L,n=null===B?e:null===F?a:(e+a)/2,o=U.getAttribute("data-size"),r=o?.match(/^\s*(\d+(?:\.\d+)?)\s*%\s*$/);null===o||r||console.warn(`[${t}] data-size="${o}" is not a percentage, such as 30%. Using the default.`);const c=Math.min(Math.max(r?Number(r[1])/100:null===B?.22:.3,.05),.8),i=x.filter(t=>("up"===t.kind||"down"===t.kind)&&Math.max(t.from,t.to)>e&&Math.min(t.from,t.to)<a);s.breakable?e<0||a<=e||a>L||0===e&&a===L?console.warn(`[${t}] A break from ${e} to ${a} does not fit a scale that runs from 0 to ${T}.`):i.length?console.warn(`[${t}] A break from ${e} to ${a} would cut a step that floats. Keep it below or above the steps.`):P={lo:e,hi:a,gap:n,share:c}:console.warn(`[${t}] This kind of chart cannot break its scale.`)}const q=P?P.gap:null,I=k-N;let j=t=>I-t/L*O;if(P){const{lo:t,hi:e,gap:a,share:n}=P,o=O*n,r=(O-o-13)/(t+(L-e)),s=o/(e-t);j=n=>n<=t?I-n*r:n<=a?I-t*r-(n-t)*s:n<=e?I-t*r-(n-t)*s-13:I-t*r-o-13-(n-e)*r}const K=h.length?Math.max(...h.map(t=>t.offsetWidth))*g+12*g:0,R=e.categories[0]?.parentElement;R&&(R.style.paddingRight=K?K/d*100+"%":"");const V=(d-K)/r.length,W=t=>t>=0&&t<r.length?t:null;e.rowAt=s.centre?null:"beside"===s.categories?(t,e)=>W(Math.floor(e*g/(k/r.length))):t=>W(Math.floor(t*g/V));const D=V/d*100,G=100/r.length;e.rowBox="beside"===s.categories?t=>[0,t*G,100,G]:t=>[t*D,0,D,100],o.setAttribute("viewBox",`0 0 1000 ${k}`),o.textContent="",e.checks=[];const Z={rows:r,segments:x,cx:t=>(t+.5)*V,y:j,barWidth:Math.min(V*a.barfill,rt(e.figure,g)),barMax:rt(e.figure,g),height:k,unit:g,labelHeight:p,badgeHeight:v,after:r.length,note:0,labels:"inside"===e.figure.dataset.chartLabels||"outside"!==e.figure.dataset.chartLabels&&"inside"===a.labels?"inside":"outside",breakAt:q,stacked:e.stacked,shape:"step"===e.figure.dataset.chartShape?"step":"straight",totals:e.totals,svg:o,plot:n,values:c,series:l,seriesValues:u,names:h,categories:e.categories,centre:e.centre,config:a,checks:e.checks};s.draw(Z);const J=e.categories[0]?.parentElement;J&&"beside"!==s.categories&&E(J,e.categories.filter(t=>null!==t.offsetParent),t=>({size:t.scrollWidth,room:t.clientWidth}),"--tablechart-name-fit");for(const[t,i]of b.entries()){i.badge?.setAttribute("data-note",String(t+1));const a=i.series,n=t=>({...t,...t.cells[a]??t.cells[0]});i.type.draw(i.spec,i.badge,{...Z,...e.stacked&&{rows:M,...e.totals.length&&{values:e.totals}},...a>0&&!e.stacked&&{rows:r.map(n),segments:x.map(t=>{const e=n(t);return"bar"===t.kind?{...e,to:e.value}:e}),values:u[a]},after:i.after,note:t+1})}return $(o,b.flatMap(({badge:t})=>{if(!(t instanceof HTMLElement&&t.offsetWidth))return[];const e=t.offsetWidth*g,a=t.offsetHeight*g,n=Number.parseFloat(t.style.left)/100*d,o=Number.parseFloat(t.style.top)/100*k,r=getComputedStyle(t).borderTopLeftRadius,s=r.endsWith("%")?Number.parseFloat(r)/100:null,c=(Number.parseFloat(r)||0)*g;return[f("rect",{class:i,"data-for":"badge","data-note":t.dataset.note??"",x:n-e/2,y:o-a/2,width:e,height:a,rx:null===s?c:e*s,ry:null===s?c:a*s,style:["--after"].map(e=>t.style.getPropertyValue(e)&&`${e}:${t.style.getPropertyValue(e)}`).filter(Boolean).join("; ")})]}),d,k),!0})(n,a)&&(r=e,u())};let m=!1;const g=new ResizeObserver(()=>{m||(m=!0,requestAnimationFrame(()=>{m=!1,b()}))}),y=new IntersectionObserver(t=>{for(const e of t)s=e.isIntersecting,u()},{threshold:a.threshold}),w=()=>ct(n,!0),p=()=>{r=null,b()},v={relabel:()=>st(n,a),refresh:p};h(),b(),g.observe(n.figure),y.observe(n.figure),window.addEventListener("beforeprint",w),(t=>{$t.add(t),wt||(wt=new MutationObserver(()=>{for(const t of $t)t.relabel();requestAnimationFrame(()=>requestAnimationFrame(()=>{for(const t of $t)t.refresh()}))})).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"]})})(v);const k={figure:n.figure,refresh:p,destroy(){g.disconnect(),y.disconnect(),window.removeEventListener("beforeprint",w),(t=>{$t.delete(t),!$t.size&&wt&&(wt.disconnect(),wt=null)})(v),n.figure.tablechart===k&&delete n.figure.tablechart}};return n.figure.tablechart=k,k})(n,a)):null};window.Tablechart={init:async(t={},e=document)=>{const a={...u,...t};a.debug&&(J.enabled=!0);const n=(await kt(Array.from(e.querySelectorAll(a.selector)),a)).map(t=>Mt(t,a)).filter(t=>null!==t);return J.log(`Made ${n.length} chart(s).`),{charts:n,refresh:()=>{for(const t of n)t.refresh()},destroy:()=>{for(const t of n)t.destroy()}}},create:async(t,e={})=>{if(t.tablechart)return t.tablechart;const a={...u,...e};a.debug&&(J.enabled=!0);const[n]=await kt([t],a);return n?Mt(n,a):null},defaultConfig:u}}();
@@ -0,0 +1,2 @@
1
+ import { _ as e, n as t, t as n } from "./tablechart-shared.mjs";
2
+ export { n as create, e as defaultConfig, t as init };
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@martinomagnifico/tablechart",
3
+ "version": "0.1.0",
4
+ "description": "Simple charts from an HTML or Markdown table: column, bar, line, area, waterfall and donut, with annotations. A chart builds when it scrolls into view.",
5
+ "type": "module",
6
+ "sideEffects": [
7
+ "**/*.css",
8
+ "**/*.scss"
9
+ ],
10
+ "main": "./dist/tablechart.mjs",
11
+ "types": "./dist/tablechart.d.ts",
12
+ "unpkg": "./dist/tablechart.js",
13
+ "jsdelivr": "./dist/tablechart.js",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/tablechart.d.ts",
17
+ "import": "./dist/tablechart.mjs"
18
+ },
19
+ "./core": {
20
+ "types": "./dist/tablechart-core.d.ts",
21
+ "import": "./dist/tablechart-core.mjs"
22
+ },
23
+ "./style.css": "./dist/tablechart.css"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "CHANGELOG.md"
29
+ ],
30
+ "scripts": {
31
+ "start": "cd docs && npm start",
32
+ "dev": "vite",
33
+ "docs": "cd docs && npm start",
34
+ "docs:build": "cd docs && npm run build",
35
+ "docs:preview": "npm run build && cd docs && rm -rf dist && npm run build && npm run preview",
36
+ "preview": "npm run docs:preview",
37
+ "build": "npm run clean && npm run build:lib",
38
+ "build:lib": "vite build",
39
+ "prepack": "npm run build",
40
+ "clean": "rm -rf dist",
41
+ "setup": "cd docs && npm install"
42
+ },
43
+ "keywords": [
44
+ "chart",
45
+ "charts",
46
+ "svg",
47
+ "table",
48
+ "waterfall",
49
+ "donut"
50
+ ],
51
+ "author": "Martijn De Jongh",
52
+ "license": "MIT",
53
+ "devDependencies": {
54
+ "@microsoft/api-extractor": "^7.59.3",
55
+ "@vituum/vite-plugin-pug": "^2.0.1",
56
+ "sass": "^1.97.3",
57
+ "terser": "^5.46.0",
58
+ "typescript": "^5.9.3",
59
+ "vite": "^8.0.0",
60
+ "vite-plugin-dts": "5.0.0-beta.6",
61
+ "vituum": "^2.0.1"
62
+ },
63
+ "module": "./dist/tablechart.mjs",
64
+ "publishConfig": {
65
+ "access": "public"
66
+ }
67
+ }