@moderneinc/react-charts 1.2.0-next.73a364 → 1.2.0-next.932db3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/components/chrono-chart/chrono-chart.component.d.ts +10 -0
  2. package/dist/components/chrono-chart/chrono-chart.types.d.ts +114 -0
  3. package/dist/components/chrono-chart/components/category-table.component.d.ts +13 -0
  4. package/dist/components/chrono-chart/components/category-table.types.d.ts +42 -0
  5. package/dist/components/chrono-chart/utils/data-transformer.d.ts +41 -0
  6. package/dist/components/d3-stacked-area-chart/d3-stacked-area-chart.component.d.ts +7 -0
  7. package/dist/components/d3-stacked-area-chart/d3-stacked-area-chart.types.d.ts +89 -0
  8. package/dist/components/d3-stacked-area-chart/hooks/use-d3-stacked-area.hook.d.ts +34 -0
  9. package/dist/components/morph-chart/hooks/shared/computations.d.ts +29 -0
  10. package/dist/components/morph-chart/hooks/shared/types.d.ts +24 -0
  11. package/dist/components/morph-chart/hooks/use-morph-chart.hook.d.ts +85 -0
  12. package/dist/components/morph-chart/index.d.ts +2 -0
  13. package/dist/components/morph-chart/morph-chart.component.d.ts +14 -0
  14. package/dist/components/morph-chart/morph-chart.types.d.ts +154 -0
  15. package/dist/components/morph-chart/utils/accordion-generator.d.ts +102 -0
  16. package/dist/components/morph-chart/utils/animation-constants.d.ts +23 -0
  17. package/dist/components/morph-chart/utils/animation-utils.d.ts +44 -0
  18. package/dist/components/morph-chart/utils/arc-path-calculator.d.ts +53 -0
  19. package/dist/components/morph-chart/utils/area-renderer.d.ts +24 -0
  20. package/dist/components/morph-chart/utils/bar-renderer.d.ts +19 -0
  21. package/dist/components/morph-chart/utils/gsap-orchestrator.d.ts +291 -0
  22. package/dist/components/morph-chart/utils/morph-interpolator.d.ts +96 -0
  23. package/dist/components/morph-chart/utils/parliament-renderer.d.ts +23 -0
  24. package/dist/components/morph-chart/utils/parliament-seat-extractor.d.ts +33 -0
  25. package/dist/components/morph-chart/utils/position-mapper.d.ts +48 -0
  26. package/dist/components/morph-chart/utils/segment-transformer.d.ts +70 -0
  27. package/dist/components/morph-chart/utils/slinky-3d-generator.d.ts +35 -0
  28. package/dist/components/morph-chart/utils/svg-patterns.d.ts +19 -0
  29. package/dist/components/morph-chart/utils/svg-slinky-generator.d.ts +25 -0
  30. package/dist/components/parliament-chart/hooks/use-parliament-chart.hook.d.ts +5 -1
  31. package/dist/components/parliament-chart/parliament-chart.types.d.ts +5 -0
  32. package/dist/components/parliament-chart/utils/parliament-animation.d.ts +13 -0
  33. package/dist/components/stacked-area-chart/utils/color.utils.d.ts +0 -5
  34. package/dist/components/timeline-chart/timeline-chart.types.d.ts +29 -0
  35. package/dist/index.cjs +109 -71
  36. package/dist/index.d.ts +7 -0
  37. package/dist/index.js +24066 -16304
  38. package/dist/theme/default-colors.d.ts +0 -4
  39. package/dist/theme/timeline-defaults.d.ts +33 -1
  40. package/package.json +29 -9
@@ -0,0 +1,33 @@
1
+ import { ParliamentLayout } from '../morph-chart.types';
2
+ type Party = {
3
+ id: string | number;
4
+ name: string;
5
+ seats: number;
6
+ colour: string;
7
+ };
8
+ type ParliamentOptions = {
9
+ arcAngle: number;
10
+ arcAngleFlexibility?: number;
11
+ radius: number;
12
+ seatSize: number;
13
+ minSeatSize: number;
14
+ maxSeatSize: number;
15
+ spacing: number;
16
+ innerRadiusRatio: number;
17
+ };
18
+ /**
19
+ * Generate parliament layout with seat positions
20
+ * Based on the logic from parliament-svg-enhanced.ts but returns position data
21
+ * instead of SVG elements
22
+ */
23
+ export declare function generateParliamentLayout(parties: Party[], options: ParliamentOptions): ParliamentLayout;
24
+ /**
25
+ * Convert category data to parliament party format
26
+ */
27
+ export declare function categoriesToParties(categories: Array<{
28
+ dataKey: string;
29
+ label: string;
30
+ color: string;
31
+ value: number;
32
+ }>, totalRepositories: number, maxSeats: number): Party[];
33
+ export {};
@@ -0,0 +1,48 @@
1
+ import { ScaleLinear, ScaleTime } from 'd3-scale';
2
+ import { ParliamentLayout, SeatPosition } from '../morph-chart.types';
3
+ /**
4
+ * Map parliament seats to their target positions at the right edge of the stacked area chart
5
+ * Seats can be positioned at the top (y1) or distributed vertically within their category's segment
6
+ *
7
+ * NOTE: stackData uses dataKey, but parliamentLayout.seats use category labels.
8
+ * We need to match by label, so stackData must contain label information.
9
+ *
10
+ * @param distributeVertically - If true, seats are spread between y0 and y1; if false, all seats at y1
11
+ */
12
+ export declare function mapSeatsToStackEdge(parliamentLayout: ParliamentLayout, stackData: Array<{
13
+ dataKey: string;
14
+ label?: string;
15
+ y0: number;
16
+ y1: number;
17
+ timestamp?: number;
18
+ isSpecialCategory?: boolean;
19
+ }>, xScale: ScaleTime<number, number>, yScale: ScaleLinear<number, number>, chartWidth: number, chartHeight: number, distributeVertically?: boolean): Map<SeatPosition, {
20
+ x: number;
21
+ y: number;
22
+ }>;
23
+ /**
24
+ * Extract the rightmost slice of stacked area data
25
+ * This represents the same point-in-time as the parliament chart
26
+ *
27
+ * IMPORTANT: The stack is generated using original category order.
28
+ * We build the slice in original order to match the stack generation.
29
+ */
30
+ export declare function extractRightmostStackSlice(data: Array<{
31
+ timestamp: number;
32
+ [key: string]: number;
33
+ }>, categories: Array<{
34
+ dataKey: string;
35
+ label: string;
36
+ color: string;
37
+ parliamentMapping?: {
38
+ isSpecialCategory?: boolean;
39
+ };
40
+ }>, _yScale: ScaleLinear<number, number>): Array<{
41
+ dataKey: string;
42
+ label: string;
43
+ y0: number;
44
+ y1: number;
45
+ value: number;
46
+ timestamp: number;
47
+ isSpecialCategory?: boolean;
48
+ }>;
@@ -0,0 +1,70 @@
1
+ import { ScaleLinear, ScaleTime } from 'd3-scale';
2
+ import { MorphChartCategory } from '../morph-chart.types';
3
+ interface StackedSeriesDataPoint {
4
+ data: {
5
+ timestamp: number;
6
+ };
7
+ 0: number;
8
+ 1: number;
9
+ }
10
+ export type SegmentTransform = {
11
+ segmentId: string;
12
+ dataKey: string;
13
+ timestamp: number;
14
+ x: number;
15
+ y: number;
16
+ rotation: number;
17
+ length: number;
18
+ };
19
+ /**
20
+ * Calculate curve data for stacked area chart
21
+ * Generates the curved path data that segments will transform into
22
+ *
23
+ * @param stackedData - D3 stacked data
24
+ * @param categories - Category definitions
25
+ * @param xScale - X scale (time)
26
+ * @param yScale - Y scale (values)
27
+ * @returns Array of curve data for each category
28
+ */
29
+ export declare function calculateStackedCurveData(stackedData: StackedSeriesDataPoint[][], categories: MorphChartCategory[], xScale: ScaleTime<number, number>, yScale: ScaleLinear<number, number>): Array<{
30
+ dataKey: string;
31
+ category: string;
32
+ points: Array<{
33
+ x: number;
34
+ y: number;
35
+ timestamp: number;
36
+ }>;
37
+ pathData: string;
38
+ }>;
39
+ /**
40
+ * Calculate transformations for horizontal bar top segments to align with curves
41
+ * Each segment gets position, rotation, and length data
42
+ *
43
+ * @param barSegments - Array of bar segments with their positions
44
+ * @param curveData - Calculated curve data for all categories
45
+ * @param segmentLength - Desired length of each segment
46
+ * @returns Array of transformation data for each segment
47
+ */
48
+ export declare function calculateSegmentTransforms(barSegments: Array<{
49
+ dataKey: string;
50
+ timestamp: number;
51
+ x: number;
52
+ y: number;
53
+ width: number;
54
+ }>, curveData: ReturnType<typeof calculateStackedCurveData>, segmentLength: number): SegmentTransform[];
55
+ /**
56
+ * Extract bar top segment positions from rendered bars
57
+ * Identifies the top edge of each bar segment for transformation
58
+ *
59
+ * @param svg - SVG container with bar elements
60
+ * @returns Array of segment position data
61
+ */
62
+ export declare function extractBarTopPositions(svg: SVGSVGElement): Array<{
63
+ dataKey: string;
64
+ timestamp: number;
65
+ x: number;
66
+ y: number;
67
+ width: number;
68
+ element: SVGElement;
69
+ }>;
70
+ export {};
@@ -0,0 +1,35 @@
1
+ import { Selection } from 'd3-selection';
2
+ export interface Slinky3DConfig {
3
+ categories: Array<{
4
+ name: string;
5
+ color: string;
6
+ seatCount: number;
7
+ }>;
8
+ centerX: number;
9
+ centerY: number;
10
+ radius: number;
11
+ arcAngle: number;
12
+ }
13
+ /**
14
+ * Generate HTML content for 3D slinky rings
15
+ */
16
+ export declare function generate3DSlinkyHTML(categories: Array<{
17
+ name: string;
18
+ color: string;
19
+ seatCount: number;
20
+ }>): string;
21
+ /**
22
+ * Generate CSS styles for 3D slinky effect
23
+ */
24
+ export declare function generate3DSlinkyStyles(instanceId: string): string;
25
+ /**
26
+ * Create 3D slinky elements in SVG using foreignObject
27
+ */
28
+ export declare function create3DSlinky(container: Selection<SVGGElement, unknown, null, undefined>, config: Slinky3DConfig, instanceId: string): {
29
+ wrapper: Selection<SVGForeignObjectElement, unknown, null, undefined>;
30
+ cleanup: () => void;
31
+ };
32
+ /**
33
+ * Animate 3D slinky compression using GSAP
34
+ */
35
+ export declare function animate3DSlinkyCompression(instanceId: string, timeline: gsap.core.Timeline, startTime: string, duration: number, targetX: number, targetY: number): void;
@@ -0,0 +1,19 @@
1
+ import { Selection } from 'd3-selection';
2
+ /**
3
+ * Add all hatch pattern definitions to an SVG's <defs> element
4
+ * Call this once when setting up the SVG
5
+ * @param svg - The SVG selection to add patterns to
6
+ * @param instancePrefix - Unique prefix for this instance to avoid ID conflicts
7
+ */
8
+ export declare function addHatchPatternDefs(svg: Selection<SVGSVGElement, unknown, null, undefined>, instancePrefix: string): void;
9
+ /**
10
+ * Transform a color to use instance-specific pattern IDs
11
+ * Converts 'url(#patternName)' to 'url(#prefix-patternName)'
12
+ */
13
+ export declare function transformColorForInstance(color: string, instancePrefix: string): string;
14
+ /**
15
+ * Get the display color for a category, handling pattern URLs
16
+ * Returns the line color for patterns (better visibility in hover states)
17
+ * Works with both instance-specific and generic pattern URLs
18
+ */
19
+ export declare function getDisplayColor(color: string): string;
@@ -0,0 +1,25 @@
1
+ import { Selection } from 'd3-selection';
2
+ export interface SvgSlinkyConfig {
3
+ categories: Array<{
4
+ name: string;
5
+ color: string;
6
+ seatCount: number;
7
+ }>;
8
+ centerX: number;
9
+ centerY: number;
10
+ radius: number;
11
+ innerRadius: number;
12
+ arcAngle: number;
13
+ }
14
+ /**
15
+ * Create SVG slinky coils
16
+ */
17
+ export declare function createSvgSlinky(container: Selection<SVGGElement, unknown, null, undefined>, config: SvgSlinkyConfig, instanceId: string): {
18
+ slinkyGroup: Selection<SVGGElement, unknown, null, undefined>;
19
+ cleanup: () => void;
20
+ };
21
+ /**
22
+ * Animate SVG slinky closing - stacks rings vertically into a bar on the right
23
+ * Uses staggered animation phases to create realistic slinky walking effect
24
+ */
25
+ export declare function animateSvgSlinkyCompression(slinkyGroup: Selection<SVGGElement, unknown, null, undefined>, timeline: gsap.core.Timeline, startTime: string, duration: number, targetX: number, targetY: number): void;
@@ -1,5 +1,6 @@
1
1
  import { RefObject } from 'react';
2
2
  import { ChartConfig, HoveredData, ProcessedDataItem } from '../parliament-chart.types';
3
+ import { ArcSweepDirection } from '../utils/parliament-animation';
3
4
  type UseParliamentChartProps = {
4
5
  containerRef: RefObject<HTMLDivElement>;
5
6
  processedData: ProcessedDataItem[];
@@ -12,11 +13,14 @@ type UseParliamentChartProps = {
12
13
  setActivePartyName: (name: string | null) => void;
13
14
  chartConfig: ChartConfig;
14
15
  seatSize: number;
16
+ shouldAnimate?: boolean;
17
+ animationDirection?: ArcSweepDirection;
18
+ onAnimationComplete?: () => void;
15
19
  };
16
20
  /**
17
21
  * Hook that manages parliament chart rendering and interactivity.
18
22
  * Generates SVG visualization with seat circles and handles hover states
19
23
  * for displaying repository statistics.
20
24
  */
21
- export declare const useParliamentChart: ({ containerRef, processedData, totalRepositories, arcAngle, useEnhanced, maxSeats, setHoveredData, activePartyName, setActivePartyName, chartConfig, seatSize }: UseParliamentChartProps) => void;
25
+ export declare const useParliamentChart: ({ containerRef, processedData, totalRepositories, arcAngle, useEnhanced, maxSeats, setHoveredData, activePartyName, setActivePartyName, chartConfig, seatSize, shouldAnimate, animationDirection, onAnimationComplete }: UseParliamentChartProps) => void;
22
26
  export {};
@@ -1,4 +1,5 @@
1
1
  import { ParliamentChartTheme } from '../../theme/default-colors';
2
+ import { ArcSweepDirection } from './utils/parliament-animation';
2
3
  type ParliamentDataSeries = {
3
4
  value: number;
4
5
  label: string;
@@ -12,6 +13,10 @@ export type ParliamentChartProps = {
12
13
  arcAngle?: number;
13
14
  useEnhanced?: boolean;
14
15
  theme?: ParliamentChartTheme;
16
+ showTable?: boolean;
17
+ shouldAnimate?: boolean;
18
+ animationDirection?: ArcSweepDirection;
19
+ onAnimationComplete?: () => void;
15
20
  };
16
21
  export type ProcessedDataItem = {
17
22
  id: string | number;
@@ -0,0 +1,13 @@
1
+ export type ArcSweepDirection = 'left-to-right' | 'right-to-left';
2
+ /**
3
+ * Animates the parliament chart with an arc sweep reveal effect.
4
+ * Creates a clipPath that progressively reveals or collapses seats.
5
+ *
6
+ * @param svgElement - The SVG element containing the parliament chart
7
+ * @param arcAngle - The arc angle in degrees (e.g., 200)
8
+ * @param radius - The radius of the parliament arc
9
+ * @param direction - Direction of the sweep: 'left-to-right' (expand) or 'right-to-left' (collapse)
10
+ * @param duration - Animation duration in milliseconds (default: 900ms)
11
+ * @param onComplete - Optional callback fired when animation completes
12
+ */
13
+ export declare function animateArcSweep(svgElement: SVGSVGElement, arcAngle: number, radius: number, direction?: ArcSweepDirection, duration?: number, onComplete?: () => void): void;
@@ -1,8 +1,3 @@
1
- /**
2
- * Maps category index to a color from the measure gradient.
3
- * Mirrors ParliamentChart logic - first category gets worst color (red), last gets best (green).
4
- */
5
- export declare function getMeasureGradientColor(index: number, totalCategories: number): string;
6
1
  /**
7
2
  * Generates gradient colors for categories, ordered from worst (red) to best (green).
8
3
  */
@@ -3,12 +3,20 @@ export type TimelineEvent = {
3
3
  date: Date;
4
4
  timestamp: number;
5
5
  eventName: string;
6
+ /**
7
+ * Optional color for the event marker.
8
+ * If not provided, defaults to #2F42FF (Digital Blue 500).
9
+ * Accepts any valid CSS color string.
10
+ */
11
+ color?: string;
6
12
  [key: string]: unknown;
7
13
  };
8
14
  export type TimelineSelection = {
9
15
  start: number | null;
10
16
  end: number | null;
11
17
  };
18
+ export type DragHandleType = 'start' | 'end' | 'body' | null;
19
+ export type DragHandleVariant = 'arrow' | 'grip';
12
20
  export type TimelineChartSlotProps = {
13
21
  /** Props for the header container (Stack) */
14
22
  header?: StackProps;
@@ -26,6 +34,10 @@ export type TimelineChartSlotProps = {
26
34
  event?: BoxProps;
27
35
  /** Props for the selection highlight overlay (Box) */
28
36
  selection?: BoxProps;
37
+ /** Props for the start drag handle (Box) */
38
+ startHandle?: BoxProps;
39
+ /** Props for the end drag handle (Box) */
40
+ endHandle?: BoxProps;
29
41
  /** Props for the hover tooltip container (Box) */
30
42
  tooltip?: BoxProps;
31
43
  /** Props for the tooltip event name Typography component */
@@ -42,6 +54,13 @@ export type TimelineChartProps = {
42
54
  selectedRange?: TimelineSelection;
43
55
  /** Height of the timeline container in pixels (default: 32) */
44
56
  height?: number;
57
+ /** Margin around the timeline drawable area (for alignment with other charts) */
58
+ margin?: {
59
+ top: number;
60
+ right: number;
61
+ bottom: number;
62
+ left: number;
63
+ };
45
64
  /** Custom date formatter */
46
65
  formatDate?: (timestamp: number) => string;
47
66
  /** Custom month/year formatter */
@@ -52,6 +71,10 @@ export type TimelineChartProps = {
52
71
  monthLabelCount?: number;
53
72
  /** Enable zoom with mouse wheel */
54
73
  enableZoom?: boolean;
74
+ /** Drag handle style variant (default: 'arrow') */
75
+ dragHandleVariant?: DragHandleVariant;
76
+ /** Color for drag handles (default: '#4B5563' for arrow, '#9CA3AF' for grip) */
77
+ dragHandleColor?: string;
55
78
  /** Show header title and instructions (default: true) */
56
79
  showHeader?: boolean;
57
80
  /** Custom title for the header */
@@ -95,12 +118,14 @@ export type UseTimelineChartProps = {
95
118
  export type UseTimelineChartReturn = {
96
119
  isDragging: boolean;
97
120
  dragStart: number | null;
121
+ dragHandleType: DragHandleType;
98
122
  internalSelectedRange: TimelineSelection;
99
123
  internalVisibleRange: TimelineSelection;
100
124
  hoveredEvent: TimelineEvent | null;
101
125
  minDate: number;
102
126
  maxDate: number;
103
127
  timeSpan: number;
128
+ timelineContainerRef: React.RefObject<HTMLDivElement>;
104
129
  getPositionFromTimestamp: (timestamp: number) => number;
105
130
  getTimestampFromPosition: (x: number, containerWidth: number) => number;
106
131
  handleMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
@@ -108,9 +133,13 @@ export type UseTimelineChartReturn = {
108
133
  handleMouseUp: () => void;
109
134
  handleWheel: (e: React.WheelEvent<HTMLDivElement>) => void;
110
135
  handleDoubleClick: () => void;
136
+ handleStartHandleMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
137
+ handleEndHandleMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
138
+ handleSelectionBodyMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
111
139
  setHoveredEvent: (event: TimelineEvent | null) => void;
112
140
  getEventsInRange: () => TimelineEvent[];
113
141
  resetZoom: () => void;
142
+ showHandles: boolean;
114
143
  };
115
144
  export type TimelineSelectedEventsProps = {
116
145
  /** Array of selected events to display */