@principal-ai/file-city-react 0.3.0 → 0.4.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.
- package/dist/components/ArchitectureMapHighlightLayers.d.ts +4 -1
- package/dist/components/ArchitectureMapHighlightLayers.d.ts.map +1 -1
- package/dist/components/ArchitectureMapHighlightLayers.js +133 -1
- package/dist/stories/sample-data.d.ts.map +1 -1
- package/dist/stories/sample-data.js +101 -258
- package/package.json +6 -10
- package/src/components/ArchitectureMapHighlightLayers.tsx +176 -0
- package/src/stories/ArchitectureMapGridLayout.stories.tsx +8 -7
- package/src/stories/ArchitectureMapHighlightLayers.stories.tsx +194 -1
- package/src/stories/sample-data.ts +129 -289
- package/dist/stories/ArchitectureMapGridLayout.stories.d.ts +0 -73
- package/dist/stories/ArchitectureMapGridLayout.stories.d.ts.map +0 -1
- package/dist/stories/ArchitectureMapGridLayout.stories.js +0 -345
- package/dist/stories/ArchitectureMapHighlightLayers.stories.d.ts +0 -78
- package/dist/stories/ArchitectureMapHighlightLayers.stories.d.ts.map +0 -1
- package/dist/stories/ArchitectureMapHighlightLayers.stories.js +0 -270
- package/dist/stories/CityViewWithReactFlow.stories.d.ts +0 -24
- package/dist/stories/CityViewWithReactFlow.stories.d.ts.map +0 -1
- package/dist/stories/CityViewWithReactFlow.stories.js +0 -778
|
@@ -12,6 +12,9 @@ export interface ArchitectureMapHighlightLayersProps {
|
|
|
12
12
|
onDirectorySelect?: (directory: string | null) => void;
|
|
13
13
|
onFileClick?: (path: string, type: 'file' | 'directory') => void;
|
|
14
14
|
enableZoom?: boolean;
|
|
15
|
+
zoomToPath?: string | null;
|
|
16
|
+
onZoomComplete?: () => void;
|
|
17
|
+
zoomAnimationSpeed?: number;
|
|
15
18
|
fullSize?: boolean;
|
|
16
19
|
showGrid?: boolean;
|
|
17
20
|
showFileNames?: boolean;
|
|
@@ -56,7 +59,7 @@ export interface ArchitectureMapHighlightLayersProps {
|
|
|
56
59
|
buildingBorderRadius?: number;
|
|
57
60
|
districtBorderRadius?: number;
|
|
58
61
|
}
|
|
59
|
-
declare function ArchitectureMapHighlightLayersInner({ cityData, highlightLayers, onLayerToggle, focusDirectory, rootDirectoryName, onDirectorySelect, onFileClick, enableZoom, fullSize, showGrid, showFileNames, className, selectiveRender, canvasBackgroundColor, hoverBorderColor, disableOpacityDimming, defaultDirectoryColor, defaultBuildingColor, subdirectoryMode, showLayerControls, showFileTypeIcons, showDirectoryLabels, transform, // Default to no rotation
|
|
62
|
+
declare function ArchitectureMapHighlightLayersInner({ cityData, highlightLayers, onLayerToggle, focusDirectory, rootDirectoryName, onDirectorySelect, onFileClick, enableZoom, zoomToPath, onZoomComplete, zoomAnimationSpeed, fullSize, showGrid, showFileNames, className, selectiveRender, canvasBackgroundColor, hoverBorderColor, disableOpacityDimming, defaultDirectoryColor, defaultBuildingColor, subdirectoryMode, showLayerControls, showFileTypeIcons, showDirectoryLabels, transform, // Default to no rotation
|
|
60
63
|
onHover, buildingBorderRadius, districtBorderRadius, }: ArchitectureMapHighlightLayersProps): React.JSX.Element;
|
|
61
64
|
export declare const ArchitectureMapHighlightLayers: typeof ArchitectureMapHighlightLayersInner;
|
|
62
65
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArchitectureMapHighlightLayers.d.ts","sourceRoot":"","sources":["../../src/components/ArchitectureMapHighlightLayers.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ArchitectureMapHighlightLayers.d.ts","sourceRoot":"","sources":["../../src/components/ArchitectureMapHighlightLayers.tsx"],"names":[],"mappings":"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"}
|
|
@@ -117,7 +117,7 @@ class SpatialGrid {
|
|
|
117
117
|
this.grid.clear();
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
function ArchitectureMapHighlightLayersInner({ cityData, highlightLayers = [], onLayerToggle, focusDirectory = null, rootDirectoryName, onDirectorySelect, onFileClick, enableZoom = false, fullSize = false, showGrid = false, showFileNames = false, className = '', selectiveRender, canvasBackgroundColor, hoverBorderColor, disableOpacityDimming = true, defaultDirectoryColor, defaultBuildingColor, subdirectoryMode, showLayerControls = false, showFileTypeIcons = true, showDirectoryLabels = true, transform = { rotation: 0 }, // Default to no rotation
|
|
120
|
+
function ArchitectureMapHighlightLayersInner({ cityData, highlightLayers = [], onLayerToggle, focusDirectory = null, rootDirectoryName, onDirectorySelect, onFileClick, enableZoom = false, zoomToPath = null, onZoomComplete, zoomAnimationSpeed = 0.12, fullSize = false, showGrid = false, showFileNames = false, className = '', selectiveRender, canvasBackgroundColor, hoverBorderColor, disableOpacityDimming = true, defaultDirectoryColor, defaultBuildingColor, subdirectoryMode, showLayerControls = false, showFileTypeIcons = true, showDirectoryLabels = true, transform = { rotation: 0 }, // Default to no rotation
|
|
121
121
|
onHover, buildingBorderRadius = 0, districtBorderRadius = 0, }) {
|
|
122
122
|
const { theme } = (0, industry_theme_1.useTheme)();
|
|
123
123
|
// Use theme colors as defaults, with prop overrides
|
|
@@ -140,6 +140,10 @@ onHover, buildingBorderRadius = 0, districtBorderRadius = 0, }) {
|
|
|
140
140
|
lastMousePos: { x: 0, y: 0 },
|
|
141
141
|
hasMouseMoved: false,
|
|
142
142
|
});
|
|
143
|
+
// Target zoom state for animated transitions
|
|
144
|
+
const [targetZoom, setTargetZoom] = (0, react_1.useState)(null);
|
|
145
|
+
// Track the last zoomToPath to detect changes
|
|
146
|
+
const lastZoomToPathRef = (0, react_1.useRef)(null);
|
|
143
147
|
(0, react_1.useEffect)(() => {
|
|
144
148
|
if (!enableZoom) {
|
|
145
149
|
setZoomState(prev => ({
|
|
@@ -150,8 +154,46 @@ onHover, buildingBorderRadius = 0, districtBorderRadius = 0, }) {
|
|
|
150
154
|
isDragging: false,
|
|
151
155
|
hasMouseMoved: false,
|
|
152
156
|
}));
|
|
157
|
+
setTargetZoom(null);
|
|
153
158
|
}
|
|
154
159
|
}, [enableZoom]);
|
|
160
|
+
// Animation loop for smooth zoom transitions
|
|
161
|
+
(0, react_1.useEffect)(() => {
|
|
162
|
+
if (!targetZoom)
|
|
163
|
+
return;
|
|
164
|
+
const animate = () => {
|
|
165
|
+
setZoomState(prev => {
|
|
166
|
+
const lerp = (a, b, t) => a + (b - a) * t;
|
|
167
|
+
const easing = zoomAnimationSpeed;
|
|
168
|
+
const newScale = lerp(prev.scale, targetZoom.scale, easing);
|
|
169
|
+
const newOffsetX = lerp(prev.offsetX, targetZoom.offsetX, easing);
|
|
170
|
+
const newOffsetY = lerp(prev.offsetY, targetZoom.offsetY, easing);
|
|
171
|
+
// Check if close enough to target (within 0.1% for scale, 0.5px for offset)
|
|
172
|
+
const scaleDone = Math.abs(newScale - targetZoom.scale) < 0.001;
|
|
173
|
+
const offsetXDone = Math.abs(newOffsetX - targetZoom.offsetX) < 0.5;
|
|
174
|
+
const offsetYDone = Math.abs(newOffsetY - targetZoom.offsetY) < 0.5;
|
|
175
|
+
if (scaleDone && offsetXDone && offsetYDone) {
|
|
176
|
+
// Animation complete - set exact target values
|
|
177
|
+
setTargetZoom(null);
|
|
178
|
+
onZoomComplete?.();
|
|
179
|
+
return {
|
|
180
|
+
...prev,
|
|
181
|
+
scale: targetZoom.scale,
|
|
182
|
+
offsetX: targetZoom.offsetX,
|
|
183
|
+
offsetY: targetZoom.offsetY,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
...prev,
|
|
188
|
+
scale: newScale,
|
|
189
|
+
offsetX: newOffsetX,
|
|
190
|
+
offsetY: newOffsetY,
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
const frameId = requestAnimationFrame(animate);
|
|
195
|
+
return () => cancelAnimationFrame(frameId);
|
|
196
|
+
}, [targetZoom, zoomState, zoomAnimationSpeed, onZoomComplete]);
|
|
155
197
|
const [hitTestCache, setHitTestCache] = (0, react_1.useState)(null);
|
|
156
198
|
const calculateCanvasResolution = (fileCount, _cityBounds) => {
|
|
157
199
|
const minSize = 400;
|
|
@@ -188,6 +230,96 @@ onHover, buildingBorderRadius = 0, districtBorderRadius = 0, }) {
|
|
|
188
230
|
}
|
|
189
231
|
return filteredCityData;
|
|
190
232
|
}, [subdirectoryMode?.enabled, subdirectoryMode?.autoCenter, cityData, filteredCityData]);
|
|
233
|
+
// Handle zoomToPath changes - calculate target zoom to frame the specified path
|
|
234
|
+
(0, react_1.useEffect)(() => {
|
|
235
|
+
// Skip if zoom is not enabled or path hasn't changed
|
|
236
|
+
if (!enableZoom || zoomToPath === lastZoomToPathRef.current) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
lastZoomToPathRef.current = zoomToPath;
|
|
240
|
+
// If zoomToPath is null, reset to default view
|
|
241
|
+
if (zoomToPath === null) {
|
|
242
|
+
setTargetZoom({
|
|
243
|
+
scale: 1,
|
|
244
|
+
offsetX: 0,
|
|
245
|
+
offsetY: 0,
|
|
246
|
+
});
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// Need city data and canvas ref to calculate zoom
|
|
250
|
+
if (!filteredCityData || !canvasRef.current) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
// Get actual display size - the canvas is resized to match this during render
|
|
254
|
+
// so canvas coordinates = display coordinates
|
|
255
|
+
const displayWidth = canvasRef.current.clientWidth || canvasSize.width;
|
|
256
|
+
const displayHeight = canvasRef.current.clientHeight || canvasSize.height;
|
|
257
|
+
if (!displayWidth || !displayHeight) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
// Find the target - first check districts, then buildings
|
|
261
|
+
const normalizedPath = zoomToPath.replace(/^\/+|\/+$/g, '');
|
|
262
|
+
const targetDistrict = filteredCityData.districts.find(d => d.path === normalizedPath || d.path === zoomToPath);
|
|
263
|
+
const targetBuilding = filteredCityData.buildings.find(b => b.path === normalizedPath || b.path === zoomToPath);
|
|
264
|
+
if (!targetDistrict && !targetBuilding) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
// Get the bounds to zoom to
|
|
268
|
+
let targetBounds;
|
|
269
|
+
if (targetDistrict) {
|
|
270
|
+
targetBounds = targetDistrict.worldBounds;
|
|
271
|
+
}
|
|
272
|
+
else if (targetBuilding) {
|
|
273
|
+
// Create bounds around the building with some padding
|
|
274
|
+
const [width, , depth] = targetBuilding.dimensions;
|
|
275
|
+
const padding = Math.max(width, depth) * 2;
|
|
276
|
+
targetBounds = {
|
|
277
|
+
minX: targetBuilding.position.x - width / 2 - padding,
|
|
278
|
+
maxX: targetBuilding.position.x + width / 2 + padding,
|
|
279
|
+
minZ: targetBuilding.position.z - depth / 2 - padding,
|
|
280
|
+
maxZ: targetBuilding.position.z + depth / 2 + padding,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
// Use the same coordinate system as rendering
|
|
287
|
+
const coordinateData = canvasSizingData || filteredCityData;
|
|
288
|
+
const { scale: baseScale, offsetX: baseOffsetX, offsetZ: baseOffsetZ } = calculateScaleAndOffset(coordinateData, displayWidth, displayHeight, displayOptions.padding);
|
|
289
|
+
// Calculate target center in world coordinates
|
|
290
|
+
const targetCenterX = (targetBounds.minX + targetBounds.maxX) / 2;
|
|
291
|
+
const targetCenterZ = (targetBounds.minZ + targetBounds.maxZ) / 2;
|
|
292
|
+
// Calculate target size in screen coordinates (at base zoom)
|
|
293
|
+
const targetScreenWidth = (targetBounds.maxX - targetBounds.minX) * baseScale;
|
|
294
|
+
const targetScreenHeight = (targetBounds.maxZ - targetBounds.minZ) * baseScale;
|
|
295
|
+
// Calculate zoom scale to fit target with padding (80% of display)
|
|
296
|
+
const paddingFactor = 0.8;
|
|
297
|
+
const scaleToFitWidth = (displayWidth * paddingFactor) / targetScreenWidth;
|
|
298
|
+
const scaleToFitHeight = (displayHeight * paddingFactor) / targetScreenHeight;
|
|
299
|
+
const newZoomScale = Math.min(scaleToFitWidth, scaleToFitHeight, 5); // Cap at 5x
|
|
300
|
+
// Calculate the base screen position of target center (before zoom transform)
|
|
301
|
+
// This matches the worldToCanvas formula: ((x - bounds.minX) * scale + offsetX)
|
|
302
|
+
const baseScreenX = (targetCenterX - coordinateData.bounds.minX) * baseScale + baseOffsetX;
|
|
303
|
+
const baseScreenY = (targetCenterZ - coordinateData.bounds.minZ) * baseScale + baseOffsetZ;
|
|
304
|
+
// Calculate offset to center the target
|
|
305
|
+
// Full formula: screenPos = baseScreenPos * zoomScale + zoomOffset
|
|
306
|
+
// To center: displayCenter = baseScreen * zoomScale + zoomOffset
|
|
307
|
+
// Therefore: zoomOffset = displayCenter - baseScreen * zoomScale
|
|
308
|
+
const newOffsetX = displayWidth / 2 - baseScreenX * newZoomScale;
|
|
309
|
+
const newOffsetY = displayHeight / 2 - baseScreenY * newZoomScale;
|
|
310
|
+
setTargetZoom({
|
|
311
|
+
scale: newZoomScale,
|
|
312
|
+
offsetX: newOffsetX,
|
|
313
|
+
offsetY: newOffsetY,
|
|
314
|
+
});
|
|
315
|
+
}, [
|
|
316
|
+
zoomToPath,
|
|
317
|
+
enableZoom,
|
|
318
|
+
filteredCityData,
|
|
319
|
+
canvasSizingData,
|
|
320
|
+
canvasSize,
|
|
321
|
+
displayOptions.padding,
|
|
322
|
+
]);
|
|
191
323
|
// Build hit test cache with spatial indexing
|
|
192
324
|
const buildHitTestCache = (0, react_1.useCallback)((cityData, scale, offsetX, offsetZ, zoomState, abstractedPaths) => {
|
|
193
325
|
const spatialGrid = new SpatialGrid(cityData.bounds);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-data.d.ts","sourceRoot":"","sources":["../../src/stories/sample-data.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"sample-data.d.ts","sourceRoot":"","sources":["../../src/stories/sample-data.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGT,MAAM,iCAAiC,CAAC;AAqFzC,wBAAgB,oBAAoB,IAAI,QAAQ,CAmB/C;AAaD,wBAAgB,yBAAyB,IAAI,QAAQ,CAmBpD"}
|
|
@@ -2,267 +2,110 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createSampleCityData = createSampleCityData;
|
|
4
4
|
exports.createSmallSampleCityData = createSmallSampleCityData;
|
|
5
|
-
|
|
5
|
+
const file_city_builder_1 = require("@principal-ai/file-city-builder");
|
|
6
|
+
// Sample file structure representing a typical project
|
|
7
|
+
const sampleFileStructure = [
|
|
8
|
+
// Source files
|
|
9
|
+
{ path: 'src/index.ts', size: 1500 },
|
|
10
|
+
{ path: 'src/App.tsx', size: 3200 },
|
|
11
|
+
{ path: 'src/components/Header.tsx', size: 1800 },
|
|
12
|
+
{ path: 'src/components/Footer.tsx', size: 1200 },
|
|
13
|
+
{ path: 'src/components/Sidebar.tsx', size: 2100 },
|
|
14
|
+
{ path: 'src/components/Card.tsx', size: 900 },
|
|
15
|
+
{ path: 'src/components/Button.tsx', size: 600 },
|
|
16
|
+
{ path: 'src/utils/helpers.ts', size: 2500 },
|
|
17
|
+
{ path: 'src/utils/api.ts', size: 3100 },
|
|
18
|
+
{ path: 'src/utils/validators.ts', size: 1400 },
|
|
19
|
+
{ path: 'src/hooks/useAuth.ts', size: 800 },
|
|
20
|
+
{ path: 'src/hooks/useData.ts', size: 1100 },
|
|
21
|
+
{ path: 'src/styles/main.css', size: 4500 },
|
|
22
|
+
{ path: 'src/styles/components.css', size: 2800 },
|
|
23
|
+
// Test files
|
|
24
|
+
{ path: 'tests/unit/app.test.ts', size: 2200 },
|
|
25
|
+
{ path: 'tests/unit/header.test.ts', size: 1600 },
|
|
26
|
+
{ path: 'tests/unit/footer.test.tsx', size: 1400 },
|
|
27
|
+
{ path: 'tests/integration/api.test.ts', size: 3400 },
|
|
28
|
+
{ path: '__tests__/components.test.tsx', size: 2900 },
|
|
29
|
+
{ path: '__tests__/utils.test.ts', size: 1900 },
|
|
30
|
+
// Config files
|
|
31
|
+
{ path: 'package.json', size: 1200 },
|
|
32
|
+
{ path: 'tsconfig.json', size: 800 },
|
|
33
|
+
{ path: 'webpack.config.js', size: 2100 },
|
|
34
|
+
{ path: '.eslintrc.js', size: 600 },
|
|
35
|
+
{ path: '.prettierrc', size: 200 },
|
|
36
|
+
{ path: 'README.md', size: 3500 },
|
|
37
|
+
// Documentation
|
|
38
|
+
{ path: 'docs/README.md', size: 4200 },
|
|
39
|
+
{ path: 'docs/API.md', size: 5100 },
|
|
40
|
+
{ path: 'docs/CONTRIBUTING.md', size: 2300 },
|
|
41
|
+
// Build files
|
|
42
|
+
{ path: 'dist/bundle.js', size: 45000 },
|
|
43
|
+
{ path: 'dist/index.html', size: 800 },
|
|
44
|
+
{ path: 'dist/styles.css', size: 12000 },
|
|
45
|
+
// Node modules (sample)
|
|
46
|
+
{ path: 'node_modules/react/index.js', size: 8000 },
|
|
47
|
+
{ path: 'node_modules/react/package.json', size: 1500 },
|
|
48
|
+
{ path: 'node_modules/typescript/lib/typescript.js', size: 65000 },
|
|
49
|
+
{ path: 'node_modules/@types/react/index.d.ts', size: 3200 },
|
|
50
|
+
// Deprecated files
|
|
51
|
+
{ path: 'src/deprecated/OldComponent.tsx', size: 2400 },
|
|
52
|
+
{ path: 'src/deprecated/LegacyAPI.ts', size: 3100 },
|
|
53
|
+
];
|
|
54
|
+
// Convert file structure to FileInfo objects
|
|
55
|
+
function createFileInfoList(files) {
|
|
56
|
+
return files.map(file => ({
|
|
57
|
+
name: file.path.split('/').pop() || file.path,
|
|
58
|
+
path: file.path,
|
|
59
|
+
relativePath: file.path,
|
|
60
|
+
size: file.size,
|
|
61
|
+
extension: file.path.includes('.') ? '.' + (file.path.split('.').pop() || '') : '',
|
|
62
|
+
lastModified: new Date(),
|
|
63
|
+
isDirectory: false,
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
// Cache the city data to avoid rebuilding on every render
|
|
67
|
+
let cachedCityData = null;
|
|
68
|
+
// Helper function to create sample city data for stories using the real treemap builder
|
|
6
69
|
function createSampleCityData() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
{ path: 'src/utils/api.ts', size: 3100 },
|
|
21
|
-
{ path: 'src/utils/validators.ts', size: 1400 },
|
|
22
|
-
{ path: 'src/hooks/useAuth.ts', size: 800 },
|
|
23
|
-
{ path: 'src/hooks/useData.ts', size: 1100 },
|
|
24
|
-
{ path: 'src/styles/main.css', size: 4500 },
|
|
25
|
-
{ path: 'src/styles/components.css', size: 2800 },
|
|
26
|
-
// Test files
|
|
27
|
-
{ path: 'tests/unit/app.test.ts', size: 2200 },
|
|
28
|
-
{ path: 'tests/unit/header.test.ts', size: 1600 },
|
|
29
|
-
{ path: 'tests/unit/footer.test.tsx', size: 1400 },
|
|
30
|
-
{ path: 'tests/integration/api.test.ts', size: 3400 },
|
|
31
|
-
{ path: '__tests__/components.test.tsx', size: 2900 },
|
|
32
|
-
{ path: '__tests__/utils.test.ts', size: 1900 },
|
|
33
|
-
// Config files
|
|
34
|
-
{ path: 'package.json', size: 1200 },
|
|
35
|
-
{ path: 'tsconfig.json', size: 800 },
|
|
36
|
-
{ path: 'webpack.config.js', size: 2100 },
|
|
37
|
-
{ path: '.eslintrc.js', size: 600 },
|
|
38
|
-
{ path: '.prettierrc', size: 200 },
|
|
39
|
-
{ path: 'README.md', size: 3500 },
|
|
40
|
-
// Documentation
|
|
41
|
-
{ path: 'docs/README.md', size: 4200 },
|
|
42
|
-
{ path: 'docs/API.md', size: 5100 },
|
|
43
|
-
{ path: 'docs/CONTRIBUTING.md', size: 2300 },
|
|
44
|
-
// Build files
|
|
45
|
-
{ path: 'dist/bundle.js', size: 45000 },
|
|
46
|
-
{ path: 'dist/index.html', size: 800 },
|
|
47
|
-
{ path: 'dist/styles.css', size: 12000 },
|
|
48
|
-
// Node modules (sample)
|
|
49
|
-
{ path: 'node_modules/react/index.js', size: 8000 },
|
|
50
|
-
{ path: 'node_modules/react/package.json', size: 1500 },
|
|
51
|
-
{ path: 'node_modules/typescript/lib/typescript.js', size: 65000 },
|
|
52
|
-
{ path: 'node_modules/@types/react/index.d.ts', size: 3200 },
|
|
53
|
-
// Deprecated files
|
|
54
|
-
{ path: 'src/deprecated/OldComponent.tsx', size: 2400 },
|
|
55
|
-
{ path: 'src/deprecated/LegacyAPI.ts', size: 3100 },
|
|
56
|
-
];
|
|
57
|
-
// Create a simple grid layout
|
|
58
|
-
let currentX = 0;
|
|
59
|
-
let currentZ = 0;
|
|
60
|
-
const spacing = 2;
|
|
61
|
-
const maxPerRow = 10;
|
|
62
|
-
let itemsInRow = 0;
|
|
63
|
-
// Group files by directory
|
|
64
|
-
const filesByDir = new Map();
|
|
65
|
-
fileStructure.forEach(file => {
|
|
66
|
-
const dir = file.path.includes('/') ? file.path.substring(0, file.path.lastIndexOf('/')) : '';
|
|
67
|
-
if (!filesByDir.has(dir)) {
|
|
68
|
-
filesByDir.set(dir, []);
|
|
69
|
-
}
|
|
70
|
-
const dirFiles = filesByDir.get(dir);
|
|
71
|
-
if (dirFiles) {
|
|
72
|
-
dirFiles.push(file);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
// Track district bounds
|
|
76
|
-
const districtBounds = new Map();
|
|
77
|
-
// Process each directory group
|
|
78
|
-
const sortedDirs = Array.from(filesByDir.keys()).sort();
|
|
79
|
-
let districtStartX = 0;
|
|
80
|
-
sortedDirs.forEach(dir => {
|
|
81
|
-
const files = filesByDir.get(dir);
|
|
82
|
-
if (!files)
|
|
83
|
-
return;
|
|
84
|
-
const districtMinX = currentX;
|
|
85
|
-
const districtMinZ = currentZ;
|
|
86
|
-
files.forEach(file => {
|
|
87
|
-
const extension = file.path.includes('.') ? '.' + (file.path.split('.').pop() || '') : '';
|
|
88
|
-
// Calculate building dimensions based on file size
|
|
89
|
-
const height = Math.log(file.size + 1) * 2;
|
|
90
|
-
const width = Math.sqrt(file.size) / 10;
|
|
91
|
-
const depth = width;
|
|
92
|
-
buildings.push({
|
|
93
|
-
path: file.path,
|
|
94
|
-
position: {
|
|
95
|
-
x: currentX + width / 2,
|
|
96
|
-
y: height / 2,
|
|
97
|
-
z: currentZ + depth / 2,
|
|
98
|
-
},
|
|
99
|
-
dimensions: [width, height, depth],
|
|
100
|
-
type: 'file',
|
|
101
|
-
fileExtension: extension,
|
|
102
|
-
size: file.size,
|
|
103
|
-
lastModified: new Date(),
|
|
104
|
-
});
|
|
105
|
-
// Update position for next building
|
|
106
|
-
currentX += width + spacing;
|
|
107
|
-
itemsInRow++;
|
|
108
|
-
if (itemsInRow >= maxPerRow) {
|
|
109
|
-
currentX = districtStartX;
|
|
110
|
-
currentZ += depth + spacing;
|
|
111
|
-
itemsInRow = 0;
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
// Create district bounds
|
|
115
|
-
if (dir) {
|
|
116
|
-
const districtMaxX = currentX > districtMinX ? currentX : districtMinX + 10;
|
|
117
|
-
const districtMaxZ = currentZ > districtMinZ ? currentZ + 5 : districtMinZ + 10;
|
|
118
|
-
districtBounds.set(dir, {
|
|
119
|
-
minX: districtMinX - 1,
|
|
120
|
-
maxX: districtMaxX + 1,
|
|
121
|
-
minZ: districtMinZ - 1,
|
|
122
|
-
maxZ: districtMaxZ + 1,
|
|
123
|
-
});
|
|
124
|
-
// Move to next district area
|
|
125
|
-
currentX = districtMaxX + spacing * 3;
|
|
126
|
-
if (currentX > 100) {
|
|
127
|
-
currentX = 0;
|
|
128
|
-
currentZ = districtMaxZ + spacing * 3;
|
|
129
|
-
}
|
|
130
|
-
districtStartX = currentX;
|
|
131
|
-
itemsInRow = 0;
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
// Create districts from bounds
|
|
135
|
-
const allPaths = new Set(districtBounds.keys());
|
|
136
|
-
const processedPaths = new Set();
|
|
137
|
-
// Helper to create all parent paths
|
|
138
|
-
const getParentPaths = (path) => {
|
|
139
|
-
const parts = path.split('/');
|
|
140
|
-
const parents = [];
|
|
141
|
-
for (let i = 1; i < parts.length; i++) {
|
|
142
|
-
parents.push(parts.slice(0, i).join('/'));
|
|
143
|
-
}
|
|
144
|
-
return parents;
|
|
145
|
-
};
|
|
146
|
-
// Add all parent paths to the set
|
|
147
|
-
allPaths.forEach(path => {
|
|
148
|
-
getParentPaths(path).forEach(parent => allPaths.add(parent));
|
|
70
|
+
if (cachedCityData) {
|
|
71
|
+
return cachedCityData;
|
|
72
|
+
}
|
|
73
|
+
const fileInfos = createFileInfoList(sampleFileStructure);
|
|
74
|
+
const fileTree = (0, file_city_builder_1.buildFileSystemTreeFromFileInfoList)(fileInfos, 'sample-project');
|
|
75
|
+
const builder = new file_city_builder_1.CodeCityBuilderWithGrid();
|
|
76
|
+
cachedCityData = builder.buildCityFromFileSystem(fileTree, '', {
|
|
77
|
+
paddingTop: 2,
|
|
78
|
+
paddingBottom: 2,
|
|
79
|
+
paddingLeft: 2,
|
|
80
|
+
paddingRight: 2,
|
|
81
|
+
paddingInner: 1,
|
|
82
|
+
paddingOuter: 3,
|
|
149
83
|
});
|
|
150
|
-
|
|
151
|
-
allPaths.forEach(path => {
|
|
152
|
-
if (processedPaths.has(path))
|
|
153
|
-
return;
|
|
154
|
-
// Find all children of this path
|
|
155
|
-
const children = Array.from(districtBounds.keys()).filter(p => p.startsWith(path + '/') && !p.slice(path.length + 1).includes('/'));
|
|
156
|
-
let bounds;
|
|
157
|
-
if (districtBounds.has(path)) {
|
|
158
|
-
const pathBounds = districtBounds.get(path);
|
|
159
|
-
if (!pathBounds)
|
|
160
|
-
return;
|
|
161
|
-
bounds = pathBounds;
|
|
162
|
-
}
|
|
163
|
-
else if (children.length > 0) {
|
|
164
|
-
// Calculate bounds from children
|
|
165
|
-
const childBounds = children
|
|
166
|
-
.map(c => districtBounds.get(c))
|
|
167
|
-
.filter((b) => b !== undefined);
|
|
168
|
-
if (childBounds.length === 0)
|
|
169
|
-
return;
|
|
170
|
-
bounds = {
|
|
171
|
-
minX: Math.min(...childBounds.map(c => c.minX)),
|
|
172
|
-
maxX: Math.max(...childBounds.map(c => c.maxX)),
|
|
173
|
-
minZ: Math.min(...childBounds.map(c => c.minZ)),
|
|
174
|
-
maxZ: Math.max(...childBounds.map(c => c.maxZ)),
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
return; // Skip if no bounds
|
|
179
|
-
}
|
|
180
|
-
const fileCount = buildings.filter(b => b.path === path || b.path.startsWith(path + '/')).length;
|
|
181
|
-
districts.push({
|
|
182
|
-
path,
|
|
183
|
-
worldBounds: bounds,
|
|
184
|
-
fileCount,
|
|
185
|
-
type: 'directory',
|
|
186
|
-
});
|
|
187
|
-
processedPaths.add(path);
|
|
188
|
-
});
|
|
189
|
-
// Calculate overall bounds
|
|
190
|
-
const allX = buildings.map(b => b.position.x);
|
|
191
|
-
const allZ = buildings.map(b => b.position.z);
|
|
192
|
-
const bounds = {
|
|
193
|
-
minX: Math.min(...allX) - 5,
|
|
194
|
-
maxX: Math.max(...allX) + 5,
|
|
195
|
-
minZ: Math.min(...allZ) - 5,
|
|
196
|
-
maxZ: Math.max(...allZ) + 5,
|
|
197
|
-
};
|
|
198
|
-
return {
|
|
199
|
-
buildings,
|
|
200
|
-
districts,
|
|
201
|
-
bounds,
|
|
202
|
-
metadata: {
|
|
203
|
-
totalFiles: buildings.length,
|
|
204
|
-
totalDirectories: districts.length,
|
|
205
|
-
analyzedAt: new Date(),
|
|
206
|
-
rootPath: '/',
|
|
207
|
-
layoutConfig: {
|
|
208
|
-
paddingTop: 2,
|
|
209
|
-
paddingBottom: 2,
|
|
210
|
-
paddingLeft: 2,
|
|
211
|
-
paddingRight: 2,
|
|
212
|
-
paddingInner: 1,
|
|
213
|
-
paddingOuter: 3,
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
};
|
|
84
|
+
return cachedCityData;
|
|
217
85
|
}
|
|
86
|
+
// Smaller sample file structure
|
|
87
|
+
const smallFileStructure = [
|
|
88
|
+
{ path: 'src/index.ts', size: 1500 },
|
|
89
|
+
{ path: 'src/App.tsx', size: 3200 },
|
|
90
|
+
{ path: 'src/utils/helpers.ts', size: 800 },
|
|
91
|
+
{ path: 'package.json', size: 1200 },
|
|
92
|
+
];
|
|
93
|
+
let cachedSmallCityData = null;
|
|
218
94
|
// Create a smaller sample for performance testing
|
|
219
95
|
function createSmallSampleCityData() {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
fileExtension: '.tsx',
|
|
236
|
-
size: 3200,
|
|
237
|
-
lastModified: new Date(),
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
path: 'utils/helpers.ts',
|
|
241
|
-
position: { x: 5, y: 2.5, z: 15 },
|
|
242
|
-
dimensions: [3, 5, 3],
|
|
243
|
-
type: 'file',
|
|
244
|
-
fileExtension: '.ts',
|
|
245
|
-
size: 800,
|
|
246
|
-
lastModified: new Date(),
|
|
247
|
-
},
|
|
248
|
-
];
|
|
249
|
-
const districts = [
|
|
250
|
-
{
|
|
251
|
-
path: 'utils',
|
|
252
|
-
worldBounds: { minX: 2, maxX: 10, minZ: 12, maxZ: 20 },
|
|
253
|
-
fileCount: 1,
|
|
254
|
-
type: 'directory',
|
|
255
|
-
},
|
|
256
|
-
];
|
|
257
|
-
return {
|
|
258
|
-
buildings,
|
|
259
|
-
districts,
|
|
260
|
-
bounds: { minX: 0, maxX: 20, minZ: 0, maxZ: 25 },
|
|
261
|
-
metadata: {
|
|
262
|
-
totalFiles: buildings.length,
|
|
263
|
-
totalDirectories: districts.length,
|
|
264
|
-
analyzedAt: new Date(),
|
|
265
|
-
rootPath: '/',
|
|
266
|
-
},
|
|
267
|
-
};
|
|
96
|
+
if (cachedSmallCityData) {
|
|
97
|
+
return cachedSmallCityData;
|
|
98
|
+
}
|
|
99
|
+
const fileInfos = createFileInfoList(smallFileStructure);
|
|
100
|
+
const fileTree = (0, file_city_builder_1.buildFileSystemTreeFromFileInfoList)(fileInfos, 'small-sample');
|
|
101
|
+
const builder = new file_city_builder_1.CodeCityBuilderWithGrid();
|
|
102
|
+
cachedSmallCityData = builder.buildCityFromFileSystem(fileTree, '', {
|
|
103
|
+
paddingTop: 2,
|
|
104
|
+
paddingBottom: 2,
|
|
105
|
+
paddingLeft: 2,
|
|
106
|
+
paddingRight: 2,
|
|
107
|
+
paddingInner: 1,
|
|
108
|
+
paddingOuter: 3,
|
|
109
|
+
});
|
|
110
|
+
return cachedSmallCityData;
|
|
268
111
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@principal-ai/file-city-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "React components for File City visualization",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -21,17 +21,13 @@
|
|
|
21
21
|
"react": "^19.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@storybook/addon-
|
|
25
|
-
"@storybook/addon-
|
|
26
|
-
"@storybook/
|
|
27
|
-
"@
|
|
28
|
-
"@storybook/react": "^7.6.0",
|
|
29
|
-
"@storybook/react-vite": "^7.6.0",
|
|
30
|
-
"@storybook/test": "^7.6.0",
|
|
31
|
-
"@types/react": "^18.0.0",
|
|
24
|
+
"@storybook/addon-docs": "^10.1.2",
|
|
25
|
+
"@storybook/addon-links": "^10.1.2",
|
|
26
|
+
"@storybook/react-vite": "^10.1.2",
|
|
27
|
+
"@types/react": "^19.0.0",
|
|
32
28
|
"react": "^19.1.1",
|
|
33
29
|
"react-dom": "^19.1.1",
|
|
34
|
-
"storybook": "^
|
|
30
|
+
"storybook": "^10.1.2",
|
|
35
31
|
"typescript": "^5.0.0",
|
|
36
32
|
"vite": "^5.0.0"
|
|
37
33
|
},
|