ioloco-charts 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/D3/AreaChart/index.d.ts +1 -1
- package/dist/D3/AreaChart/index.js +44 -43
- package/dist/D3/AreaChart/types.d.ts +2 -0
- package/dist/D3/BarChart/index.d.ts +1 -1
- package/dist/D3/BarChart/index.js +28 -27
- package/dist/D3/BarChart/types.d.ts +3 -0
- package/dist/D3/DonutChart/index.d.ts +1 -1
- package/dist/D3/DonutChart/index.js +26 -25
- package/dist/D3/DonutChart/types.d.ts +5 -0
- package/dist/D3/FunnelChart/index.d.ts +1 -1
- package/dist/D3/FunnelChart/index.js +20 -19
- package/dist/D3/FunnelChart/types.d.ts +2 -0
- package/dist/D3/GanttTimeline/index.d.ts +1 -1
- package/dist/D3/GanttTimeline/index.js +21 -21
- package/dist/D3/GanttTimeline/types.d.ts +1 -0
- package/dist/D3/GaugeChart/index.d.ts +1 -1
- package/dist/D3/GaugeChart/index.js +15 -15
- package/dist/D3/GaugeChart/types.d.ts +1 -0
- package/dist/D3/HeatmapChart/index.d.ts +1 -1
- package/dist/D3/HeatmapChart/index.js +26 -25
- package/dist/D3/HeatmapChart/types.d.ts +2 -0
- package/dist/D3/LineChart/index.js +30 -30
- package/dist/D3/RadialBarChart/index.d.ts +1 -1
- package/dist/D3/RadialBarChart/index.js +27 -27
- package/dist/D3/RadialBarChart/types.d.ts +1 -0
- package/dist/D3/RelationshipDiagram/index.js +20 -20
- package/dist/D3/SankeyChart/index.d.ts +1 -1
- package/dist/D3/SankeyChart/index.js +24 -23
- package/dist/D3/SankeyChart/types.d.ts +2 -0
- package/dist/D3/ScatterPlot/index.d.ts +1 -1
- package/dist/D3/ScatterPlot/index.js +25 -25
- package/dist/D3/ScatterPlot/types.d.ts +1 -0
- package/dist/D3/SparklineChart/index.js +5 -5
- package/dist/D3/StackedBarChart/index.d.ts +1 -1
- package/dist/D3/StackedBarChart/index.js +30 -29
- package/dist/D3/StackedBarChart/types.d.ts +2 -0
- package/dist/D3/TreemapChart/index.d.ts +1 -1
- package/dist/D3/TreemapChart/index.js +23 -22
- package/dist/D3/TreemapChart/types.d.ts +2 -0
- package/dist/D3/index.d.ts +0 -2
- package/dist/D3/shared/chartLabels.d.ts +2 -0
- package/dist/D3/shared/chartLabels.js +2 -0
- package/dist/index.js +0 -1
- package/dist/ioloco-charts.css +1 -1
- package/package.json +1 -1
- package/dist/D3/KpiCard/index.d.ts +0 -2
- package/dist/D3/KpiCard/index.js +0 -12
- package/dist/D3/KpiCard/index.styles.d.ts +0 -108
- package/dist/D3/KpiCard/index.styles.js +0 -3
- package/dist/D3/KpiCard/types.d.ts +0 -16
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { AreaChartProps } from './types';
|
|
2
|
-
export declare function AreaChart({ series, title, description, height, compact, onPointClick }: Readonly<AreaChartProps>): import("react").JSX.Element;
|
|
2
|
+
export declare function AreaChart({ series, title, description, height, compact, valueLabel, hoverHint, onPointClick }: Readonly<AreaChartProps>): import("react").JSX.Element;
|
|
@@ -5,50 +5,51 @@ import{max as n}from"d3-array"
|
|
|
5
5
|
import{scalePoint as s,scaleLinear as i}from"d3-scale"
|
|
6
6
|
import{select as a,pointer as l}from"d3-selection"
|
|
7
7
|
import{area as c,line as h}from"d3-shape"
|
|
8
|
-
import{chartPalette as
|
|
9
|
-
import{ChartFrame as
|
|
10
|
-
import{ChartLegend as
|
|
11
|
-
import{areaChartAxisLayout as
|
|
8
|
+
import{chartPalette as m}from"../../tokens.stylex.js"
|
|
9
|
+
import{ChartFrame as d}from"../shared/ChartFrame/index.js"
|
|
10
|
+
import{ChartLegend as f}from"../shared/ChartLegend/index.js"
|
|
11
|
+
import{areaChartAxisLayout as u}from"../shared/chartAxisLayout/areaChart.js"
|
|
12
12
|
import{renderXAxis as p,renderYAxis as $}from"../shared/chartAxisLayout/render.js"
|
|
13
|
-
import{chartFrameInteractionProps as
|
|
14
|
-
import{CHART_SERIES_CURVE as
|
|
15
|
-
import{useChartInteraction as
|
|
16
|
-
import{
|
|
17
|
-
import{
|
|
18
|
-
|
|
13
|
+
import{chartFrameInteractionProps as v,chartPointerHandlers as g}from"../shared/chartBinding.js"
|
|
14
|
+
import{CHART_SERIES_CURVE as j,sanitizeGradientKey as y,appendAreaSeriesGradient as x,chartLineStrokeWidth as k,seriesDimOpacity as L}from"../shared/chartVisualStyle.js"
|
|
15
|
+
import{useChartInteraction as b}from"../shared/useChartInteraction.js"
|
|
16
|
+
import{formatChartValue as C}from"../shared/chartLabels.js"
|
|
17
|
+
import{useChartLegendToggle as I}from"../shared/useChartLegendToggle.js"
|
|
18
|
+
import{innerSize as w}from"../shared/chartUtils.js"
|
|
19
|
+
function B(r,t,e){if(0===r.length)return
|
|
19
20
|
let o=r[0],n=Infinity
|
|
20
21
|
for(const s of r){const r=e(s)??0,i=Math.abs(t-r)
|
|
21
|
-
i<n&&(n=i,o=s)}return o}function
|
|
22
|
-
if(!
|
|
23
|
-
const
|
|
24
|
-
return{color:t.color??
|
|
25
|
-
return{title:r,rows:
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
o(()=>{const r=
|
|
29
|
-
if(!r||0===
|
|
30
|
-
const t=r.clientWidth||640,e=
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
p(
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
x(
|
|
37
|
-
let
|
|
38
|
-
const
|
|
39
|
-
if(e)for(let r=
|
|
40
|
-
if(n&&(t>=
|
|
41
|
-
|
|
42
|
-
if(!o)return void(
|
|
43
|
-
const n=`${o.seriesKey}:${o.point.x}`,s=
|
|
44
|
-
if(n!==
|
|
45
|
-
|
|
22
|
+
i<n&&(n=i,o=s)}return o}function A(r,t,e,o){return`${r} · ${t}: ${C(e,o)}`}function M(r,t,e,o){const n=t.map(t=>{const n=t.points.find(t=>t.x===r)
|
|
23
|
+
if(!n)return null
|
|
24
|
+
const s=e.findIndex(r=>r.id===t.id)
|
|
25
|
+
return{color:t.color??m[s%m.length],label:t.id,value:C(n.y,o)}}).filter(r=>null!==r)
|
|
26
|
+
return{title:r,rows:n}}function H({series:C,title:H="Area chart",description:S,height:T=320,compact:F=!1,valueLabel:K,hoverHint:P="Hover the chart for values.",onPointClick:R}){const U=t(null),V=b(P),q=t(R)
|
|
27
|
+
q.current=R
|
|
28
|
+
const z=e(()=>C.map(r=>r.id),[C]),{hiddenIds:D,visibleIds:E,toggle:G}=I(z),J=e(()=>C.filter(r=>E.includes(r.id)),[C,E])
|
|
29
|
+
o(()=>{const r=U.current
|
|
30
|
+
if(!r||0===J.length)return
|
|
31
|
+
const t=r.clientWidth||640,e=F?Math.min(T,280):T,o=u(F),d=o.margin,{width:f,height:v}=w(t,e,d),b=k(F),I=g(V),H=a(r)
|
|
32
|
+
H.selectAll("*").remove(),H.attr("viewBox",`0 0 ${t} ${e}`)
|
|
33
|
+
const S=H.append("g").attr("transform",`translate(${d.left},${d.top})`),P=H.append("defs"),R=J[0]?.points.map(r=>r.x)??[],z=s().domain(R).range([0,f]).padding(.5),D=i().domain([0,n(J,r=>n(r.points,r=>r.y)??0)??0]).nice().range([v,0])
|
|
34
|
+
p(S,z,v,o.x),$(S,D,o.y)
|
|
35
|
+
const E=c().x(r=>z(r.x)??0).y0(v).y1(r=>D(r.y)).curve(j),G=h().x(r=>z(r.x)??0).y(r=>D(r.y)).curve(j)
|
|
36
|
+
J.forEach((r,t)=>{const e=C.findIndex(t=>t.id===r.id),o=r.color??m[e%m.length],n=`area-gradient-${y(r.id)}`
|
|
37
|
+
x(P,n,o,F),S.append("path").datum(r.points).attr("class",`area-fill-${t}`).attr("fill",`url(#${n})`).attr("stroke","none").attr("d",E).attr("pointer-events","none"),S.append("path").datum(r.points).attr("class",`area-line-${t}`).attr("fill","none").attr("stroke",o).attr("stroke-width",b).attr("stroke-linecap","round").attr("stroke-linejoin","round").attr("d",G).attr("pointer-events","none")})
|
|
38
|
+
let N=null
|
|
39
|
+
const O=(r,t)=>{const e=B(R,r,z)
|
|
40
|
+
if(e)for(let r=J.length-1;r>=0;r-=1){const o=J[r],n=o.points.find(r=>r.x===e)
|
|
41
|
+
if(n&&(t>=D(n.y)&&t<=v))return{seriesKey:o.id,point:n}}},Q=S.append("rect").attr("class","area-interaction-overlay").attr("x",0).attr("y",0).attr("width",f).attr("height",v).attr("fill","transparent").attr("pointer-events","all").attr("cursor","crosshair")
|
|
42
|
+
Q.on("mousemove",r=>{const[t,e]=l(r,S.node()),o=O(t,e)
|
|
43
|
+
if(!o)return void(N&&(N=null,I.onHoverEnd()))
|
|
44
|
+
const n=`${o.seriesKey}:${o.point.x}`,s=A(o.seriesKey,o.point.x,o.point.y,K),i=M(o.point.x,J,C,K)
|
|
45
|
+
if(n!==N)return N=n,void I.onHover(n,s,r,i)
|
|
46
|
+
I.onPointerMove?.(r)}).on("mouseleave",()=>{N=null,I.onHoverEnd()}).on("click",r=>{const[t,e]=l(r,S.node()),o=O(t,e)
|
|
46
47
|
if(!o)return
|
|
47
|
-
const n=`${o.seriesKey}:${o.point.x}`,s=
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return()=>{
|
|
53
|
-
const
|
|
54
|
-
return r(
|
|
48
|
+
const n=`${o.seriesKey}:${o.point.x}`,s=A(o.seriesKey,o.point.x,o.point.y,K)
|
|
49
|
+
I.onToggleSelect(n,s),q.current?.({seriesId:o.seriesKey,x:o.point.x,y:o.point.y})})
|
|
50
|
+
const W=V.registerFocusApply(()=>{const r=V.getHoverKey(),t=V.getSelectedKey()
|
|
51
|
+
J.forEach((e,o)=>{const n=e.id,s=!r&&!t||Boolean(r?.startsWith(`${n}:`))||Boolean(t?.startsWith(`${n}:`)),i=L(s)
|
|
52
|
+
S.select(`path.area-fill-${o}`).attr("opacity",i),S.select(`path.area-line-${o}`).attr("opacity",i)})})
|
|
53
|
+
return()=>{W(),Q.on("mousemove mouseleave click",null)}},[F,T,V.getHoverKey,V.getSelectedKey,V.onHover,V.onHoverEnd,V.onPointerMove,V.onToggleSelect,V.registerFocusApply,P,C,K,J])
|
|
54
|
+
const N=e(()=>r(f,{ariaLabel:"Series",hiddenIds:D,onToggle:G,items:C.map((r,t)=>({id:r.id,label:r.id,color:r.color??m[t%m.length]}))}),[D,C,G])
|
|
55
|
+
return r(d,{title:H,description:S,height:F?Math.min(T,280):T,compact:F,...v(V),svgRef:U,legend:N})}export{H as AreaChart}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import 'd3-transition';
|
|
2
2
|
import type { BarChartProps } from './types';
|
|
3
|
-
export declare function BarChart({ data, title, description, height, compact, valueLabel, onDatumClick }: Readonly<BarChartProps>): import("react").JSX.Element;
|
|
3
|
+
export declare function BarChart({ data, title, description, height, compact, valueLabel, hoverHint, onDatumClick }: Readonly<BarChartProps>): import("react").JSX.Element;
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as
|
|
3
|
-
import{useRef as
|
|
4
|
-
import{max as
|
|
5
|
-
import{scaleBand as i,scaleLinear as
|
|
6
|
-
import{select as
|
|
2
|
+
import{jsx as r}from"react/jsx-runtime"
|
|
3
|
+
import{useRef as t,useEffect as o}from"react"
|
|
4
|
+
import{max as e}from"d3-array"
|
|
5
|
+
import{scaleBand as i,scaleLinear as a}from"d3-scale"
|
|
6
|
+
import{select as s}from"d3-selection"
|
|
7
7
|
import"d3-transition"
|
|
8
|
-
import{chartPalette as
|
|
9
|
-
import{ChartFrame as
|
|
10
|
-
import{barChartAxisLayout as
|
|
11
|
-
import{renderXAxis as
|
|
12
|
-
import{chartFrameInteractionProps as l,chartPointerHandlers as
|
|
13
|
-
import{bindChartPointer as
|
|
14
|
-
import{
|
|
15
|
-
import{
|
|
16
|
-
import{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
8
|
+
import{chartPalette as m}from"../../tokens.stylex.js"
|
|
9
|
+
import{ChartFrame as n}from"../shared/ChartFrame/index.js"
|
|
10
|
+
import{barChartAxisLayout as h}from"../shared/chartAxisLayout/barChart.js"
|
|
11
|
+
import{renderXAxis as c,renderYAxis as d}from"../shared/chartAxisLayout/render.js"
|
|
12
|
+
import{chartFrameInteractionProps as l,chartPointerHandlers as f}from"../shared/chartBinding.js"
|
|
13
|
+
import{bindChartPointer as p,applyPointerOpacity as u}from"../shared/chartInteraction.js"
|
|
14
|
+
import{formatChartHint as j}from"../shared/chartLabels.js"
|
|
15
|
+
import{sanitizeGradientKey as g,appendBarSeriesGradient as x,SHAPE_STROKE_WIDTH as y}from"../shared/chartVisualStyle.js"
|
|
16
|
+
import{useChartInteraction as k}from"../shared/useChartInteraction.js"
|
|
17
|
+
import{innerSize as v}from"../shared/chartUtils.js"
|
|
18
|
+
function $({data:$,title:b="Bar chart",description:C,height:w=320,compact:L=!1,valueLabel:B,hoverHint:F="Hover a bar for details.",onDatumClick:A}){const H=t(null),I=k(F),M=t(A)
|
|
19
|
+
return M.current=A,o(()=>{const r=H.current
|
|
20
|
+
if(!r)return
|
|
21
|
+
const t=r.clientWidth||640,o=L?Math.min(w,280):w,n=h(L),l=n.margin,{width:k,height:b}=v(t,o,l),C=m[0],F=`bar-gradient-${g(C)}`,A=s(r)
|
|
22
|
+
A.selectAll("*").remove(),A.attr("viewBox",`0 0 ${t} ${o}`)
|
|
23
|
+
const D=A.append("defs")
|
|
24
|
+
x(D,F,C,L)
|
|
25
|
+
const R=A.append("g").attr("transform",`translate(${l.left},${l.top})`),S=i().domain($.map(r=>r.label)).range([0,k]).padding(.25),U=a().domain([0,e($,r=>r.value)??0]).nice().range([b,0])
|
|
26
|
+
c(R,S,b,n.x),d(R,U,n.y)
|
|
27
|
+
const V=R.selectAll("rect").data($).join("rect").attr("x",r=>S(r.label)??0).attr("width",S.bandwidth()).attr("y",b).attr("height",0).attr("fill",`url(#${F})`).attr("stroke",C).attr("stroke-width",y).attr("stroke-opacity",.35).attr("rx",4)
|
|
28
|
+
V.transition().duration(500).attr("y",r=>U(r.value)).attr("height",r=>b-U(r.value)),p(V,{keyFn:r=>r.label,hintFn:r=>j(r.label,r.value,B),...f(I),onClick:r=>M.current?.(r)})
|
|
29
|
+
const q=I.registerFocusApply(()=>{u(V,r=>r.label,I.getFocusOpacity)})
|
|
30
|
+
return()=>{q(),V.on("mouseenter mouseleave click",null)}},[L,$,w,I.getFocusOpacity,I.onHover,I.onHoverEnd,I.onToggleSelect,I.registerFocusApply,F,B]),r(n,{title:b,description:C,height:L?Math.min(w,280):w,compact:L,...l(I),svgRef:H})}export{$ as BarChart}
|
|
@@ -8,6 +8,9 @@ export type BarChartProps = {
|
|
|
8
8
|
description?: string;
|
|
9
9
|
height?: number;
|
|
10
10
|
compact?: boolean;
|
|
11
|
+
/** Suffix for values in hover hints, e.g. "containers" or "CIs". */
|
|
11
12
|
valueLabel?: string;
|
|
13
|
+
/** Initial interaction hint below the chart. */
|
|
14
|
+
hoverHint?: string;
|
|
12
15
|
onDatumClick?: (datum: BarDatum) => void;
|
|
13
16
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { DonutChartProps } from './types';
|
|
2
|
-
export declare function DonutChart({ data, title, description, height, compact, innerRadiusRatio, onDatumClick }: Readonly<DonutChartProps>): import("react").JSX.Element;
|
|
2
|
+
export declare function DonutChart({ data, title, description, height, compact, innerRadiusRatio, valueLabel, totalLabel, hoverHint, onDatumClick }: Readonly<DonutChartProps>): import("react").JSX.Element;
|
|
@@ -2,34 +2,35 @@
|
|
|
2
2
|
import{jsx as t}from"react/jsx-runtime"
|
|
3
3
|
import{useRef as e,useMemo as r,useEffect as o}from"react"
|
|
4
4
|
import{sum as n}from"d3-array"
|
|
5
|
-
import{scaleOrdinal as
|
|
6
|
-
import{select as
|
|
7
|
-
import{pie as a,arc as
|
|
8
|
-
import{chartPalette as
|
|
5
|
+
import{scaleOrdinal as i}from"d3-scale"
|
|
6
|
+
import{select as s}from"d3-selection"
|
|
7
|
+
import{pie as a,arc as m}from"d3-shape"
|
|
8
|
+
import{chartPalette as d}from"../../tokens.stylex.js"
|
|
9
9
|
import{ChartFrame as l}from"../shared/ChartFrame/index.js"
|
|
10
10
|
import{ChartLegend as c}from"../shared/ChartLegend/index.js"
|
|
11
11
|
import{chartFrameInteractionProps as h,chartPointerHandlers as f}from"../shared/chartBinding.js"
|
|
12
12
|
import{bindChartPointerLite as p}from"../shared/chartInteraction.js"
|
|
13
|
-
import{
|
|
14
|
-
import{
|
|
15
|
-
import{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
L.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
import{formatChartHint as u}from"../shared/chartLabels.js"
|
|
14
|
+
import{appendBarSeriesGradient as g,sanitizeGradientKey as j,chartSeriesStrokeColor as k}from"../shared/chartVisualStyle.js"
|
|
15
|
+
import{useChartInteraction as x}from"../shared/useChartInteraction.js"
|
|
16
|
+
import{useChartLegendToggle as v}from"../shared/useChartLegendToggle.js"
|
|
17
|
+
const b=.4,y=.75
|
|
18
|
+
function C({data:C,title:L="Donut chart",description:$,height:I=320,compact:M=!1,innerRadiusRatio:w=.58,valueLabel:F,totalLabel:R,hoverHint:z="Hover a segment for details.",onDatumClick:B}){const D=e(null),H=x(z),S=e(B)
|
|
19
|
+
S.current=B
|
|
20
|
+
const T=r(()=>C.map(t=>t.label),[C]),{hiddenIds:V,visibleIds:q,toggle:A}=v(T),E=r(()=>C.filter(t=>q.includes(t.label)),[C,q])
|
|
21
|
+
o(()=>{const t=D.current
|
|
22
|
+
if(!t||0===E.length)return
|
|
23
|
+
const e=t.clientWidth||480,r=M?Math.min(I,280):I,o=Math.min(e,r)/2-16,l=o*Math.min(y,Math.max(b,w)),c=s(t)
|
|
23
24
|
c.selectAll("*").remove(),c.attr("viewBox",`0 0 ${e} ${r}`)
|
|
24
25
|
const h=c.append("defs")
|
|
25
|
-
|
|
26
|
-
const r=t.color??
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
p(
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
return e.data.label===t?
|
|
33
|
-
return
|
|
34
|
-
const
|
|
35
|
-
return t(l,{title
|
|
26
|
+
C.forEach((t,e)=>{if(!q.includes(t.label))return
|
|
27
|
+
const r=t.color??d[e%d.length]
|
|
28
|
+
g(h,`donut-${j(t.label)}`,r,M)})
|
|
29
|
+
const x=c.append("g").attr("transform",`translate(${e/2},${r/2})`),v=i().domain(C.map(t=>t.label)).range(C.map((t,e)=>t.color??d[e%d.length])),L=a().value(t=>t.value).sort(null).padAngle(.015),$=m().innerRadius(l).outerRadius(o),z=x.selectAll("path").data(L(E)).join("path").attr("fill",t=>`url(#donut-${j(t.data.label)})`).attr("stroke",t=>v(t.data.label)).attr("stroke-width",M?2.5:3).attr("stroke-linejoin","round").attr("d",$)
|
|
30
|
+
p(z,{keyFn:t=>t.data.label,hintFn:t=>u(t.data.label,t.data.value,F),...f(H),onClick:t=>S.current?.(t.data)})
|
|
31
|
+
const B=H.registerFocusApply(()=>{const t=H.getHoverKey()
|
|
32
|
+
z.attr("opacity",t=>H.getFocusOpacity(t.data.label)).attr("stroke",e=>{const r=v(e.data.label)
|
|
33
|
+
return e.data.label===t?k(r):r}).attr("stroke-width",e=>e.data.label===t?M?3:3.5:M?2.5:3)}),T=n(E,t=>t.value)
|
|
34
|
+
return x.append("text").attr("text-anchor","middle").attr("dy","-0.2em").attr("font-size",M?18:22).attr("font-weight",700).attr("pointer-events","none").text(T.toLocaleString()),R&&x.append("text").attr("text-anchor","middle").attr("dy","1.2em").attr("font-size",M?10:12).attr("fill","rgba(0,0,0,0.5)").attr("pointer-events","none").text(R),()=>{B(),z.on("mouseenter mouseleave click",null)}},[M,C,I,w,H.getFocusOpacity,H.onHover,H.onHoverEnd,H.onPointerMove,H.onToggleSelect,H.registerFocusApply,z,R,F,E,q])
|
|
35
|
+
const G=r(()=>t(c,{ariaLabel:"Segments",hiddenIds:V,onToggle:A,items:C.map((t,e)=>({id:t.label,label:t.label,color:t.color??d[e%d.length]}))}),[C,V,A])
|
|
36
|
+
return t(l,{title:L,description:$,height:M?Math.min(I,280):I,compact:M,...h(H),svgRef:D,legend:G})}export{C as DonutChart}
|
|
@@ -11,5 +11,10 @@ export type DonutChartProps = {
|
|
|
11
11
|
compact?: boolean;
|
|
12
12
|
/** Hole size as a fraction of the outer radius. Clamped to keep a visible donut ring. */
|
|
13
13
|
innerRadiusRatio?: number;
|
|
14
|
+
/** Suffix for values in hover hints, e.g. "items". */
|
|
15
|
+
valueLabel?: string;
|
|
16
|
+
/** Label under the centre total; omitted when not set. */
|
|
17
|
+
totalLabel?: string;
|
|
18
|
+
hoverHint?: string;
|
|
14
19
|
onDatumClick?: (datum: DonutDatum) => void;
|
|
15
20
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { FunnelChartProps } from './types';
|
|
2
|
-
export declare function FunnelChart({ data, title, description, height, compact, onStageClick }: Readonly<FunnelChartProps>): import("react").JSX.Element;
|
|
2
|
+
export declare function FunnelChart({ data, title, description, height, compact, valueLabel, hoverHint, onStageClick }: Readonly<FunnelChartProps>): import("react").JSX.Element;
|
|
@@ -3,25 +3,26 @@ import{jsx as t}from"react/jsx-runtime"
|
|
|
3
3
|
import{useRef as e,useEffect as r}from"react"
|
|
4
4
|
import{max as n}from"d3-array"
|
|
5
5
|
import{select as o}from"d3-selection"
|
|
6
|
-
import{chartPalette as
|
|
7
|
-
import{ChartFrame as
|
|
6
|
+
import{chartPalette as i}from"../../tokens.stylex.js"
|
|
7
|
+
import{ChartFrame as s}from"../shared/ChartFrame/index.js"
|
|
8
8
|
import{chartFrameInteractionProps as a,chartPointerHandlers as c}from"../shared/chartBinding.js"
|
|
9
|
-
import{bindChartPointer as
|
|
10
|
-
import{
|
|
9
|
+
import{bindChartPointer as l,applyPointerOpacity as m}from"../shared/chartInteraction.js"
|
|
10
|
+
import{formatChartHint as h}from"../shared/chartLabels.js"
|
|
11
|
+
import{appendCenterWeightedGradient as f,sanitizeGradientKey as d,SHAPE_STROKE_WIDTH as p}from"../shared/chartVisualStyle.js"
|
|
11
12
|
import{useChartInteraction as u}from"../shared/useChartInteraction.js"
|
|
12
|
-
import{defaultMargin as
|
|
13
|
-
function
|
|
14
|
-
return
|
|
13
|
+
import{defaultMargin as x,innerSize as g}from"../shared/chartUtils.js"
|
|
14
|
+
function j({data:j,title:k="Funnel chart",description:v,height:y=340,compact:$=!1,valueLabel:w,hoverHint:b="Hover a stage for details.",onStageClick:C}){const F=e(null),z=u(b),B=e(C)
|
|
15
|
+
return B.current=C,r(()=>{const t=F.current
|
|
15
16
|
if(!t)return
|
|
16
|
-
const e=t.clientWidth||520,r=$?Math.min(y,300):y,
|
|
17
|
-
|
|
18
|
-
const k
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const b
|
|
25
|
-
|
|
26
|
-
const z
|
|
27
|
-
return()=>{
|
|
17
|
+
const e=t.clientWidth||520,r=$?Math.min(y,300):y,s={...x,left:120},{width:a,height:u}=g(e,r,s),k=o(t)
|
|
18
|
+
k.selectAll("*").remove(),k.attr("viewBox",`0 0 ${e} ${r}`)
|
|
19
|
+
const v=k.append("defs")
|
|
20
|
+
j.forEach((t,e)=>{const r=i[e%i.length]
|
|
21
|
+
f(v,`funnel-${d(t.label)}`,r,$)})
|
|
22
|
+
const b=k.append("g").attr("transform",`translate(${s.left},${s.top})`),C=n(j,t=>t.value)??0,H=u/j.length
|
|
23
|
+
j.forEach((t,e)=>{const r=t.value/C*a,n=(a-r)/2,o=e*H+4,s=i[e%i.length]
|
|
24
|
+
b.append("rect").attr("class","funnel-stage").attr("x",n).attr("y",o).attr("width",r).attr("height",H-8).attr("fill",`url(#funnel-${d(t.label)})`).attr("stroke",s).attr("stroke-width",p).attr("stroke-opacity",.35).attr("rx",6).datum(t),b.append("text").attr("x",-8).attr("y",o+(H-8)/2).attr("text-anchor","end").attr("dominant-baseline","middle").attr("font-size",11).attr("pointer-events","none").text(t.label),b.append("text").attr("x",n+r/2).attr("y",o+(H-8)/2).attr("text-anchor","middle").attr("dominant-baseline","middle").attr("font-size",12).attr("font-weight",600).attr("fill","#fff").attr("pointer-events","none").text(t.value)})
|
|
25
|
+
const I=b.selectAll("rect.funnel-stage")
|
|
26
|
+
l(I,{keyFn:t=>t.label,hintFn:t=>h(t.label,t.value,w),...c(z),onClick:t=>B.current?.(t)})
|
|
27
|
+
const L=z.registerFocusApply(()=>{m(I,t=>t.label,z.getFocusOpacity)})
|
|
28
|
+
return()=>{L(),I.on("mouseenter mouseleave click",null)}},[$,j,y,z.getFocusOpacity,z.onHover,z.onHoverEnd,z.onPointerMove,z.onToggleSelect,z.registerFocusApply,b,w]),t(s,{title:k,description:v,height:$?Math.min(y,300):y,compact:$,...a(z),svgRef:F})}export{j as FunnelChart}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { GanttTimelineProps } from './types';
|
|
2
|
-
export declare function GanttTimeline({ tasks, title, description, height, compact, onTaskClick }: Readonly<GanttTimelineProps>): import("react").JSX.Element;
|
|
2
|
+
export declare function GanttTimeline({ tasks, title, description, height, compact, hoverHint, onTaskClick }: Readonly<GanttTimelineProps>): import("react").JSX.Element;
|
|
@@ -3,34 +3,34 @@ import{jsx as t}from"react/jsx-runtime"
|
|
|
3
3
|
import{useRef as r,useMemo as e,useEffect as o}from"react"
|
|
4
4
|
import{extent as i}from"d3-array"
|
|
5
5
|
import{scaleTime as s,scaleBand as a,scaleOrdinal as n}from"d3-scale"
|
|
6
|
-
import{select as
|
|
7
|
-
import{timeParse as
|
|
6
|
+
import{select as m}from"d3-selection"
|
|
7
|
+
import{timeParse as h,timeFormat as d}from"d3-time-format"
|
|
8
8
|
import{chartPalette as c}from"../../tokens.stylex.js"
|
|
9
9
|
import{ChartFrame as l}from"../shared/ChartFrame/index.js"
|
|
10
10
|
import{ChartLegend as f}from"../shared/ChartLegend/index.js"
|
|
11
11
|
import{ganttTimelineAxisLayout as p}from"../shared/chartAxisLayout/ganttTimeline.js"
|
|
12
12
|
import{renderXAxis as g,renderYAxis as u}from"../shared/chartAxisLayout/render.js"
|
|
13
13
|
import{chartFrameInteractionProps as j,chartPointerHandlers as k}from"../shared/chartBinding.js"
|
|
14
|
-
import{bindChartPointer as
|
|
15
|
-
import{appendBarSeriesGradient as
|
|
14
|
+
import{bindChartPointer as x,applyPointerOpacity as $}from"../shared/chartInteraction.js"
|
|
15
|
+
import{appendBarSeriesGradient as y,sanitizeGradientKey as v,SHAPE_STROKE_WIDTH as C}from"../shared/chartVisualStyle.js"
|
|
16
16
|
import{useChartInteraction as b}from"../shared/useChartInteraction.js"
|
|
17
|
-
import{useChartLegendToggle as
|
|
17
|
+
import{useChartLegendToggle as w}from"../shared/useChartLegendToggle.js"
|
|
18
18
|
import{innerSize as I}from"../shared/chartUtils.js"
|
|
19
|
-
function L({tasks:L,title:O="
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
o(()=>{const t=
|
|
23
|
-
if(!t||0===
|
|
24
|
-
const r=t.clientWidth||720,e=M?Math.min(F,320):F,o=p(M),l=o.margin,{width:f,height:j}=I(r,e,l),b=
|
|
19
|
+
function L({tasks:L,title:O="Gantt timeline",description:T,height:F=360,compact:M=!1,hoverHint:A="Hover a bar for details.",onTaskClick:B}){const D=r(null),G=b(A),H=r(B)
|
|
20
|
+
H.current=B
|
|
21
|
+
const S=e(()=>[...new Set(L.map(t=>t.group??"Other"))],[L]),{hiddenIds:R,visibleIds:U,toggle:V}=w(S),Y=e(()=>S.filter(t=>U.includes(t)),[S,U]),q=e(()=>L.filter(t=>Y.includes(t.group??"Other")),[L,Y])
|
|
22
|
+
o(()=>{const t=D.current
|
|
23
|
+
if(!t||0===q.length)return
|
|
24
|
+
const r=t.clientWidth||720,e=M?Math.min(F,320):F,o=p(M),l=o.margin,{width:f,height:j}=I(r,e,l),b=h("%Y-%m-%d"),w=q.map(t=>({...t,startDate:b(t.start),endDate:b(t.end)})).filter(t=>t.startDate&&t.endDate),L=m(t)
|
|
25
25
|
L.selectAll("*").remove(),L.attr("viewBox",`0 0 ${r} ${e}`)
|
|
26
26
|
const O=L.append("defs")
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const T=L.append("g").attr("transform",`translate(${l.left},${l.top})`),
|
|
30
|
-
g(T,
|
|
31
|
-
const U=T.selectAll("rect").data(
|
|
32
|
-
|
|
33
|
-
const V=
|
|
34
|
-
return()=>{V(),U.on("mouseenter mouseleave click",null)}},[M,
|
|
35
|
-
const
|
|
36
|
-
return t(l,{title:O,description:T,height:M?Math.min(F,320):F,compact:M,...j(
|
|
27
|
+
S.forEach((t,r)=>{const e=c[r%c.length]
|
|
28
|
+
y(O,`gantt-${v(t)}`,e,M)})
|
|
29
|
+
const T=L.append("g").attr("transform",`translate(${l.left},${l.top})`),A=s().domain(i(w.flatMap(t=>[t.startDate,t.endDate]))).range([0,f]),B=a().domain(w.map(t=>t.label)).range([0,j]).padding(.25),R=n().domain(S).range(S.map((t,r)=>c[r%c.length]))
|
|
30
|
+
g(T,A,j,o.x,t=>t.ticks(M?4:6).tickFormat(d("%d %b"))),u(T,B,o.y)
|
|
31
|
+
const U=T.selectAll("rect").data(w).join("rect").attr("x",t=>A(t.startDate)).attr("y",t=>B(t.label)??0).attr("width",t=>Math.max(4,A(t.endDate)-A(t.startDate))).attr("height",B.bandwidth()).attr("fill",t=>`url(#gantt-${v(t.group??"Other")})`).attr("stroke",t=>R(t.group??"Other")).attr("stroke-width",C).attr("stroke-opacity",.35).attr("rx",4)
|
|
32
|
+
x(U,{keyFn:t=>t.id,hintFn:t=>`${t.label}: ${t.start} → ${t.end}`,...k(G),onClick:t=>H.current?.(t)})
|
|
33
|
+
const V=G.registerFocusApply(()=>{$(U,t=>t.id,G.getFocusOpacity)})
|
|
34
|
+
return()=>{V(),U.on("mouseenter mouseleave click",null)}},[M,S,F,G.getFocusOpacity,G.onHover,G.onHoverEnd,G.onPointerMove,G.onToggleSelect,G.registerFocusApply,L,q])
|
|
35
|
+
const z=e(()=>t(f,{ariaLabel:"Groups",hiddenIds:R,onToggle:V,items:S.map((t,r)=>({id:t,label:t,color:c[r%c.length]}))}),[S,R,V])
|
|
36
|
+
return t(l,{title:O,description:T,height:M?Math.min(F,320):F,compact:M,...j(G),svgRef:D,legend:z})}export{L as GanttTimeline}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { GaugeChartProps } from './types';
|
|
2
|
-
export declare function GaugeChart({ value, min, max, title, description, height, compact, label, unit, onClick }: Readonly<GaugeChartProps>): import("react").JSX.Element;
|
|
2
|
+
export declare function GaugeChart({ value, min, max, title, description, height, compact, label, unit, hoverHint, onClick }: Readonly<GaugeChartProps>): import("react").JSX.Element;
|
|
@@ -2,21 +2,21 @@
|
|
|
2
2
|
import{jsx as t}from"react/jsx-runtime"
|
|
3
3
|
import{useRef as e,useEffect as o}from"react"
|
|
4
4
|
import{scaleLinear as r}from"d3-scale"
|
|
5
|
-
import{select as
|
|
6
|
-
import{arc as
|
|
5
|
+
import{select as i}from"d3-selection"
|
|
6
|
+
import{arc as n}from"d3-shape"
|
|
7
7
|
import{chartPalette as a}from"../../tokens.stylex.js"
|
|
8
8
|
import{ChartFrame as s}from"../shared/ChartFrame/index.js"
|
|
9
|
-
import{chartFrameInteractionProps as
|
|
10
|
-
import{sanitizeGradientKey as
|
|
11
|
-
import{useChartInteraction as
|
|
12
|
-
function f({value:f,min:
|
|
13
|
-
return
|
|
9
|
+
import{chartFrameInteractionProps as l}from"../shared/chartBinding.js"
|
|
10
|
+
import{sanitizeGradientKey as m,appendArcSeriesGradient as c,chartLineStrokeWidth as h}from"../shared/chartVisualStyle.js"
|
|
11
|
+
import{useChartInteraction as u}from"../shared/useChartInteraction.js"
|
|
12
|
+
function f({value:f,min:p=0,max:d=100,title:g="Gauge chart",description:x,height:$=260,compact:v=!1,label:b="Value",unit:y="%",hoverHint:M,onClick:k}){const j=e(null),z=u(M??`${b}: ${f}${y}.`),w=e(k)
|
|
13
|
+
return w.current=k,o(()=>{const t=j.current
|
|
14
14
|
if(!t)return
|
|
15
|
-
const e=t.clientWidth||420,o=v?Math.min($,220):$,s=Math.min(e,2*o)/2-12,
|
|
16
|
-
|
|
17
|
-
const g=a[0],x=`gauge-${
|
|
18
|
-
c(
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
return
|
|
15
|
+
const e=t.clientWidth||420,o=v?Math.min($,220):$,s=Math.min(e,2*o)/2-12,l=`${b}: ${f}${y} (${p}–${d})`,u=i(t)
|
|
16
|
+
u.selectAll("*").remove(),u.attr("viewBox",`0 0 ${e} ${o}`)
|
|
17
|
+
const g=a[0],x=`gauge-${m(g)}`,M=u.append("defs")
|
|
18
|
+
c(M,x,g,v)
|
|
19
|
+
const k=u.append("g").attr("transform",`translate(${e/2},${o-8})`),C=r().domain([p,d]).range([-Math.PI/2,Math.PI/2]),S=n().innerRadius(.62*s).outerRadius(s).startAngle(-Math.PI/2).endAngle(Math.PI/2)
|
|
20
|
+
k.append("path").attr("d",S).attr("fill","rgba(0,0,0,0.08)")
|
|
21
|
+
const B=n().innerRadius(.62*s).outerRadius(s).startAngle(-Math.PI/2).endAngle(C(f)),V=k.append("path").attr("d",B).attr("fill",`url(#${x})`).attr("stroke",g).attr("stroke-width",h(v)).attr("stroke-linecap","round").attr("cursor","pointer").attr("role","button").attr("tabindex",0)
|
|
22
|
+
return V.on("mouseenter",t=>{V.attr("opacity",.85),z.onHover("gauge",l,t)}).on("mousemove",t=>{z.onPointerMove(t)}).on("mouseleave",()=>{V.attr("opacity",1),z.onHoverEnd()}).on("click",()=>{z.onToggleSelect("gauge",l),w.current?.({value:f,min:p,max:d,label:b})}),k.append("text").attr("text-anchor","middle").attr("y",.15*-s).attr("font-size",v?24:32).attr("font-weight",700).attr("pointer-events","none").text(`${f}${y}`),k.append("text").attr("text-anchor","middle").attr("y",.08*s).attr("font-size",12).attr("fill","rgba(0,0,0,0.5)").attr("pointer-events","none").text(b),k.append("text").attr("x",-s).attr("y",18).attr("font-size",11).attr("fill","rgba(0,0,0,0.45)").text(String(p)),k.append("text").attr("x",s).attr("y",18).attr("text-anchor","end").attr("font-size",11).attr("fill","rgba(0,0,0,0.45)").text(String(d)),()=>{V.on("mouseenter mousemove mouseleave click",null)}},[v,$,z.onHover,z.onHoverEnd,z.onPointerMove,z.onToggleSelect,b,d,p,y,f]),t(s,{title:g,description:x,height:v?Math.min($,220):$,compact:v,...l(z),svgRef:j})}export{f as GaugeChart}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { HeatmapChartProps } from './types';
|
|
2
|
-
export declare function HeatmapChart({ data, rows, columns, title, description, height, compact, rowAxisLabel, columnAxisLabel, onCellClick }: Readonly<HeatmapChartProps>): import("react").JSX.Element;
|
|
2
|
+
export declare function HeatmapChart({ data, rows, columns, title, description, height, compact, rowAxisLabel, columnAxisLabel, valueLabel, hoverHint, onCellClick }: Readonly<HeatmapChartProps>): import("react").JSX.Element;
|