@sybilion/uilib 1.3.21 → 1.3.23

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 (26) hide show
  1. package/dist/esm/components/ui/Chat/ChatSheet/useChatPanelChromeModel.js +21 -4
  2. package/dist/esm/components/widgets/DriversComparisonChart/DriversComparisonChart.js +139 -0
  3. package/dist/esm/components/widgets/DriversComparisonChart/DriversComparisonChart.styl.js +7 -0
  4. package/dist/esm/components/widgets/DriversComparisonChart/driversComparisonChart.helpers.js +159 -0
  5. package/dist/esm/index.js +2 -0
  6. package/dist/esm/types/src/components/ui/Chat/ChatEmptyState/ChatEmptyState.types.d.ts +9 -1
  7. package/dist/esm/types/src/components/ui/Chat/ChatSheet/useChatPanelChromeModel.d.ts +2 -2
  8. package/dist/esm/types/src/components/ui/Chat/index.d.ts +1 -0
  9. package/dist/esm/types/src/components/widgets/DriversComparisonChart/DriversComparisonChart.d.ts +18 -0
  10. package/dist/esm/types/src/components/widgets/DriversComparisonChart/driversComparisonChart.helpers.d.ts +26 -0
  11. package/dist/esm/types/src/components/widgets/DriversComparisonChart/index.d.ts +2 -0
  12. package/dist/esm/types/src/docs/pages/DriversComparisonChartPage.d.ts +1 -0
  13. package/dist/esm/types/src/index.d.ts +1 -0
  14. package/dist/esm/utils/chartConnectionPoint.js +9 -1
  15. package/package.json +1 -1
  16. package/src/components/ui/Chat/ChatEmptyState/ChatEmptyState.types.ts +17 -1
  17. package/src/components/ui/Chat/ChatSheet/useChatPanelChromeModel.tsx +23 -4
  18. package/src/components/ui/Chat/index.ts +5 -0
  19. package/src/components/widgets/DriversComparisonChart/DriversComparisonChart.styl +145 -0
  20. package/src/components/widgets/DriversComparisonChart/DriversComparisonChart.styl.d.ts +29 -0
  21. package/src/components/widgets/DriversComparisonChart/DriversComparisonChart.tsx +325 -0
  22. package/src/components/widgets/DriversComparisonChart/driversComparisonChart.helpers.ts +206 -0
  23. package/src/components/widgets/DriversComparisonChart/index.ts +13 -0
  24. package/src/docs/pages/DriversComparisonChartPage.tsx +174 -0
  25. package/src/docs/registry.ts +6 -0
  26. package/src/index.ts +1 -0
@@ -0,0 +1,13 @@
1
+ export {
2
+ DriversComparisonChart,
3
+ type DriversComparisonChartProps,
4
+ } from './DriversComparisonChart';
5
+ export {
6
+ buildDriversComparisonChartData,
7
+ DRIVER_COMPARISON_CHART_LEAD_MONTHS,
8
+ DRIVER_FORECAST_ID_BASE,
9
+ formatSeriesImportance,
10
+ INITIAL_VISIBLE_SERIES_COUNT,
11
+ mergeBacktestsChartData,
12
+ mergeDatasetHistoricalWithBacktestsChartData,
13
+ } from './driversComparisonChart.helpers';
@@ -0,0 +1,174 @@
1
+ import { useMemo, useState } from 'react';
2
+
3
+ import type { ChartDataPoint } from '#uilib/components/ui/ChartAreaInteractive/ChartAreaInteractive.types';
4
+ import { PageContentSection } from '#uilib/components/ui/Page';
5
+ import { Switch } from '#uilib/components/ui/Switch';
6
+ import { TIME_RANGES } from '#uilib/components/ui/TimeRangeControls/TimeRangeControls.constants';
7
+ import { DriversComparisonChart } from '#uilib/components/widgets/DriversComparisonChart';
8
+ import { useTheme } from '#uilib/contexts/theme-context';
9
+ import type { BacktestsComponentPayload } from '@sybilion/platform-sdk';
10
+
11
+ import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
12
+ import { DocsHeaderActions } from '../docsHeaderActions';
13
+
14
+ const ALL_TIME_RANGE = TIME_RANGES[TIME_RANGES.length - 1];
15
+
16
+ function monthKey(year: number, month: number): string {
17
+ return `${year}-${String(month).padStart(2, '0')}-01`;
18
+ }
19
+
20
+ function buildMonthlySeries(
21
+ startYear: number,
22
+ startMonth: number,
23
+ count: number,
24
+ base: number,
25
+ drift = 0.08,
26
+ phase = 0,
27
+ ): Record<string, number> {
28
+ const out: Record<string, number> = {};
29
+ let y = startYear;
30
+ let m = startMonth;
31
+ for (let i = 0; i < count; i++) {
32
+ out[monthKey(y, m)] = base + Math.sin(i * 0.4 + phase) * 0.35 + i * drift;
33
+ m += 1;
34
+ if (m > 12) {
35
+ m = 1;
36
+ y += 1;
37
+ }
38
+ }
39
+ return out;
40
+ }
41
+
42
+ function buildTargetSeries(): Record<string, number> {
43
+ return buildMonthlySeries(2018, 1, 48, 1.0, 0.012, 0.2);
44
+ }
45
+
46
+ const MOCK_PAYLOAD: BacktestsComponentPayload = {
47
+ target: {
48
+ id: 'target',
49
+ name: 'Normalized target',
50
+ normalized_series: buildTargetSeries(),
51
+ },
52
+ drivers: [
53
+ {
54
+ id: 'driver-us-pmi',
55
+ name: 'U.S. manufacturing PMI composite',
56
+ importance: 84.2,
57
+ lag: '1 quarter(s)',
58
+ normalized_series: buildMonthlySeries(2019, 4, 42, 0.45, 0.015, 0),
59
+ },
60
+ {
61
+ id: 'driver-eu-orders',
62
+ name: 'German industrial orders (domestic + foreign)',
63
+ importance: 81.6,
64
+ lag: '2 month(s)',
65
+ normalized_series: buildMonthlySeries(2019, 1, 42, 0.52, -0.006, 1.1),
66
+ },
67
+ {
68
+ id: 'driver-jp-machinery',
69
+ name: 'Japan machinery orders (core private-sector)',
70
+ importance: 77,
71
+ lag: '~1 month(s)',
72
+ normalized_series: buildMonthlySeries(2019, 7, 42, 0.38, 0.01, 2.4),
73
+ },
74
+ {
75
+ id: 'driver-global-risk',
76
+ name: 'Global equity risk appetite composite',
77
+ importance: 66.5,
78
+ lag: 'Unknown',
79
+ normalized_series: buildMonthlySeries(2018, 10, 42, 0.41, 0.004, 3.8),
80
+ },
81
+ {
82
+ id: 'driver-china-credit',
83
+ name: 'China aggregate financing impulse',
84
+ importance: 58.3,
85
+ lag: '3 month(s)',
86
+ normalized_series: buildMonthlySeries(2020, 1, 36, 0.29, 0.018, 4.2),
87
+ },
88
+ ],
89
+ };
90
+
91
+ function buildDatasetHistorical(): ChartDataPoint[] {
92
+ const raw = buildMonthlySeries(2017, 7, 54, 112, 0.9, 0.5);
93
+ return Object.entries(raw).map(([date, historical]) => ({
94
+ date,
95
+ historical,
96
+ }));
97
+ }
98
+
99
+ export default function DriversComparisonChartPage() {
100
+ const { isDarkMode } = useTheme();
101
+ const [loading, setLoading] = useState(false);
102
+ const [runAnalysisHint, setRunAnalysisHint] = useState(false);
103
+ const [emptyPayload, setEmptyPayload] = useState(false);
104
+ const [timeRange, setTimeRange] = useState<string>(ALL_TIME_RANGE);
105
+
106
+ const payload = useMemo(
107
+ () => (emptyPayload ? null : MOCK_PAYLOAD),
108
+ [emptyPayload],
109
+ );
110
+ const datasetHistorical = useMemo(() => buildDatasetHistorical(), []);
111
+
112
+ return (
113
+ <>
114
+ <AppPageHeader
115
+ breadcrumbs={[{ label: 'Drivers comparison chart' }]}
116
+ title="DriversComparisonChart"
117
+ subheader="Normalized target line with driver series; table rows toggle chart visibility."
118
+ actions={<DocsHeaderActions />}
119
+ />
120
+ <PageContentSection>
121
+ <div
122
+ style={{
123
+ display: 'flex',
124
+ flexWrap: 'wrap',
125
+ alignItems: 'center',
126
+ gap: 16,
127
+ marginBottom: 16,
128
+ }}
129
+ >
130
+ <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
131
+ <Switch
132
+ id="loading-overlay"
133
+ checked={loading}
134
+ onCheckedChange={setLoading}
135
+ />
136
+ <label htmlFor="loading-overlay">Loading overlay</label>
137
+ </div>
138
+ <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
139
+ <Switch
140
+ id="run-analysis-hint"
141
+ checked={runAnalysisHint}
142
+ onCheckedChange={setRunAnalysisHint}
143
+ />
144
+ <label htmlFor="run-analysis-hint">Run analysis hint</label>
145
+ </div>
146
+ <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
147
+ <Switch
148
+ id="empty-payload"
149
+ checked={emptyPayload}
150
+ onCheckedChange={setEmptyPayload}
151
+ />
152
+ <label htmlFor="empty-payload">Empty payload</label>
153
+ </div>
154
+ </div>
155
+ <DriversComparisonChart
156
+ payload={payload}
157
+ datasetHistorical={datasetHistorical}
158
+ loading={loading}
159
+ chartLoading={false}
160
+ runAnalysisHint={runAnalysisHint}
161
+ statusHint={
162
+ emptyPayload
163
+ ? 'No normalized driver series in the response yet.'
164
+ : null
165
+ }
166
+ timeRange={timeRange}
167
+ onTimeRangeChange={setTimeRange}
168
+ isDarkTheme={isDarkMode}
169
+ seriesInitKey={emptyPayload ? 'empty' : 'mock'}
170
+ />
171
+ </PageContentSection>
172
+ </>
173
+ );
174
+ }
@@ -145,6 +145,12 @@ export const DOC_REGISTRY: DocEntry[] = [
145
145
  section: 'Widgets',
146
146
  load: () => import('./pages/DriverMapPage'),
147
147
  },
148
+ {
149
+ slug: 'drivers-comparison-chart',
150
+ title: 'DriversComparisonChart',
151
+ section: 'Widgets',
152
+ load: () => import('./pages/DriversComparisonChartPage'),
153
+ },
148
154
  {
149
155
  slug: 'dropdown-menu',
150
156
  title: 'DropdownMenu',
package/src/index.ts CHANGED
@@ -73,6 +73,7 @@ export * from './components/ui/WorkspaceAppSwitcher';
73
73
  export * from './components/widgets/SidebarDatasetsItemsGrouped';
74
74
  export * from './components/widgets/DriverCard';
75
75
  export * from './components/widgets/DriverMap';
76
+ export * from './components/widgets/DriversComparisonChart';
76
77
  export * from './components/widgets/SybilionAppHeader';
77
78
  export * from './components/widgets/SybilionAuthLayout';
78
79
  export * from './components/widgets/SybilionSignInPanel';