@principal-ai/file-city-react 0.3.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/builder/cityDataUtils.d.ts +15 -0
- package/dist/builder/cityDataUtils.d.ts.map +1 -0
- package/dist/builder/cityDataUtils.js +348 -0
- package/dist/components/ArchitectureMapHighlightLayers.d.ts +63 -0
- package/dist/components/ArchitectureMapHighlightLayers.d.ts.map +1 -0
- package/dist/components/ArchitectureMapHighlightLayers.js +1040 -0
- package/dist/components/CityViewWithReactFlow.d.ts +14 -0
- package/dist/components/CityViewWithReactFlow.d.ts.map +1 -0
- package/dist/components/CityViewWithReactFlow.js +266 -0
- package/dist/config/files.json +996 -0
- package/dist/hooks/useCodeCityData.d.ts +21 -0
- package/dist/hooks/useCodeCityData.d.ts.map +1 -0
- package/dist/hooks/useCodeCityData.js +57 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/render/client/drawLayeredBuildings.d.ts +51 -0
- package/dist/render/client/drawLayeredBuildings.d.ts.map +1 -0
- package/dist/render/client/drawLayeredBuildings.js +650 -0
- package/dist/stories/ArchitectureMapGridLayout.stories.d.ts +73 -0
- package/dist/stories/ArchitectureMapGridLayout.stories.d.ts.map +1 -0
- package/dist/stories/ArchitectureMapGridLayout.stories.js +345 -0
- package/dist/stories/ArchitectureMapHighlightLayers.stories.d.ts +78 -0
- package/dist/stories/ArchitectureMapHighlightLayers.stories.d.ts.map +1 -0
- package/dist/stories/ArchitectureMapHighlightLayers.stories.js +270 -0
- package/dist/stories/CityViewWithReactFlow.stories.d.ts +24 -0
- package/dist/stories/CityViewWithReactFlow.stories.d.ts.map +1 -0
- package/dist/stories/CityViewWithReactFlow.stories.js +778 -0
- package/dist/stories/sample-data.d.ts +4 -0
- package/dist/stories/sample-data.d.ts.map +1 -0
- package/dist/stories/sample-data.js +268 -0
- package/dist/types/react-types.d.ts +17 -0
- package/dist/types/react-types.d.ts.map +1 -0
- package/dist/types/react-types.js +4 -0
- package/dist/utils/fileColorHighlightLayers.d.ts +86 -0
- package/dist/utils/fileColorHighlightLayers.d.ts.map +1 -0
- package/dist/utils/fileColorHighlightLayers.js +283 -0
- package/package.json +49 -0
- package/src/builder/cityDataUtils.ts +430 -0
- package/src/components/ArchitectureMapHighlightLayers.tsx +1518 -0
- package/src/components/CityViewWithReactFlow.tsx +365 -0
- package/src/config/files.json +996 -0
- package/src/hooks/useCodeCityData.ts +82 -0
- package/src/index.ts +64 -0
- package/src/render/client/drawLayeredBuildings.ts +946 -0
- package/src/stories/ArchitectureMapGridLayout.stories.tsx +410 -0
- package/src/stories/ArchitectureMapHighlightLayers.stories.tsx +312 -0
- package/src/stories/CityViewWithReactFlow.stories.tsx +787 -0
- package/src/stories/sample-data.ts +301 -0
- package/src/types/react-types.ts +18 -0
- package/src/utils/fileColorHighlightLayers.ts +378 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CityData, SelectiveRenderOptions } from '@principal-ai/file-city-builder';
|
|
2
|
+
export declare const filterCityDataForSelectiveRender: (cityData: CityData, selectiveRender?: SelectiveRenderOptions) => CityData;
|
|
3
|
+
/**
|
|
4
|
+
* Filter city data to only include a subdirectory and optionally remap coordinates
|
|
5
|
+
* to make the subdirectory the new origin (0,0)
|
|
6
|
+
*/
|
|
7
|
+
export declare const filterCityDataForSubdirectory: (cityData: CityData, subdirectoryPath: string, autoCenter?: boolean) => CityData;
|
|
8
|
+
/**
|
|
9
|
+
* Filter city data based on multiple directory filters with include/exclude modes
|
|
10
|
+
*/
|
|
11
|
+
export declare const filterCityDataForMultipleDirectories: (cityData: CityData, filters: Array<{
|
|
12
|
+
path: string;
|
|
13
|
+
mode: "include" | "exclude";
|
|
14
|
+
}>, autoCenter?: boolean, combineMode?: "union" | "intersection") => CityData;
|
|
15
|
+
//# sourceMappingURL=cityDataUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cityDataUtils.d.ts","sourceRoot":"","sources":["../../src/builder/cityDataUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAER,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;AAGzC,eAAO,MAAM,gCAAgC,GAC3C,UAAU,QAAQ,EAClB,kBAAkB,sBAAsB,KACvC,QAqBF,CAAC;AA6GF;;;GAGG;AACH,eAAO,MAAM,6BAA6B,GACxC,UAAU,QAAQ,EAClB,kBAAkB,MAAM,EACxB,aAAY,OAAc,KACzB,QA6HF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oCAAoC,GAC/C,UAAU,QAAQ,EAClB,SAAS,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,CAAC,EAC7D,aAAY,OAAc,EAC1B,cAAa,OAAO,GAAG,cAAwB,KAC9C,QAiJF,CAAC"}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterCityDataForMultipleDirectories = exports.filterCityDataForSubdirectory = exports.filterCityDataForSelectiveRender = void 0;
|
|
4
|
+
// Utility functions for selective rendering
|
|
5
|
+
const filterCityDataForSelectiveRender = (cityData, selectiveRender) => {
|
|
6
|
+
if (!selectiveRender || selectiveRender.mode === 'all') {
|
|
7
|
+
return cityData;
|
|
8
|
+
}
|
|
9
|
+
const { mode, directories, rootDirectory, showParentContext } = selectiveRender;
|
|
10
|
+
switch (mode) {
|
|
11
|
+
case 'filter':
|
|
12
|
+
return filterCityData(cityData, directories || new Set());
|
|
13
|
+
case 'focus':
|
|
14
|
+
// Focus mode doesn't filter data, just affects rendering
|
|
15
|
+
return cityData;
|
|
16
|
+
case 'drilldown':
|
|
17
|
+
return drilldownCityData(cityData, rootDirectory || '', showParentContext || false);
|
|
18
|
+
default:
|
|
19
|
+
return cityData;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
exports.filterCityDataForSelectiveRender = filterCityDataForSelectiveRender;
|
|
23
|
+
const filterCityData = (cityData, visibleDirectories) => {
|
|
24
|
+
const filteredBuildings = cityData.buildings.filter(building => {
|
|
25
|
+
// Check if building is in any of the visible directories
|
|
26
|
+
return Array.from(visibleDirectories).some(dir => building.path.startsWith(dir + '/') || building.path === dir);
|
|
27
|
+
});
|
|
28
|
+
const filteredDistricts = cityData.districts.filter(district => {
|
|
29
|
+
// Include district if it's in the visible set or is a parent of a visible directory
|
|
30
|
+
return Array.from(visibleDirectories).some(dir => district.path === dir ||
|
|
31
|
+
dir.startsWith(district.path + '/') ||
|
|
32
|
+
district.path.startsWith(dir + '/'));
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
...cityData,
|
|
36
|
+
buildings: filteredBuildings,
|
|
37
|
+
districts: filteredDistricts,
|
|
38
|
+
bounds: recalculateBounds(filteredBuildings, filteredDistricts),
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const drilldownCityData = (cityData, rootDirectory, showParentContext) => {
|
|
42
|
+
if (!rootDirectory)
|
|
43
|
+
return cityData;
|
|
44
|
+
// Filter buildings to only those within the root directory
|
|
45
|
+
const filteredBuildings = cityData.buildings
|
|
46
|
+
.filter(building => building.path.startsWith(rootDirectory + '/') || building.path === rootDirectory)
|
|
47
|
+
.map(building => ({
|
|
48
|
+
...building,
|
|
49
|
+
// Adjust path to be relative to the new root
|
|
50
|
+
path: building.path.startsWith(rootDirectory + '/')
|
|
51
|
+
? building.path.substring(rootDirectory.length + 1)
|
|
52
|
+
: building.path,
|
|
53
|
+
}));
|
|
54
|
+
// Filter districts to only those within the root directory
|
|
55
|
+
const filteredDistricts = cityData.districts
|
|
56
|
+
.filter(district => district.path.startsWith(rootDirectory + '/') || district.path === rootDirectory)
|
|
57
|
+
.map(district => ({
|
|
58
|
+
...district,
|
|
59
|
+
// Adjust path to be relative to the new root
|
|
60
|
+
path: district.path.startsWith(rootDirectory + '/')
|
|
61
|
+
? district.path.substring(rootDirectory.length + 1)
|
|
62
|
+
: district.path === rootDirectory
|
|
63
|
+
? ''
|
|
64
|
+
: district.path,
|
|
65
|
+
}));
|
|
66
|
+
// If showing parent context, add immediate parent district
|
|
67
|
+
if (showParentContext && rootDirectory) {
|
|
68
|
+
const parentPath = rootDirectory.split('/').slice(0, -1).join('/');
|
|
69
|
+
const parentDistrict = cityData.districts.find(d => d.path === parentPath);
|
|
70
|
+
if (parentDistrict) {
|
|
71
|
+
filteredDistricts.unshift({
|
|
72
|
+
...parentDistrict,
|
|
73
|
+
path: '../' + parentDistrict.path.split('/').pop(),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
...cityData,
|
|
79
|
+
buildings: filteredBuildings,
|
|
80
|
+
districts: filteredDistricts,
|
|
81
|
+
bounds: recalculateBounds(filteredBuildings, filteredDistricts),
|
|
82
|
+
metadata: {
|
|
83
|
+
...cityData.metadata,
|
|
84
|
+
rootPath: rootDirectory,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const recalculateBounds = (buildings, districts) => {
|
|
89
|
+
if (buildings.length === 0 && districts.length === 0) {
|
|
90
|
+
return { minX: 0, maxX: 100, minZ: 0, maxZ: 100 };
|
|
91
|
+
}
|
|
92
|
+
const allX = [
|
|
93
|
+
...buildings.map(b => b.position.x),
|
|
94
|
+
...districts.flatMap(d => [d.worldBounds.minX, d.worldBounds.maxX]),
|
|
95
|
+
];
|
|
96
|
+
const allZ = [
|
|
97
|
+
...buildings.map(b => b.position.z),
|
|
98
|
+
...districts.flatMap(d => [d.worldBounds.minZ, d.worldBounds.maxZ]),
|
|
99
|
+
];
|
|
100
|
+
return {
|
|
101
|
+
minX: Math.min(...allX),
|
|
102
|
+
maxX: Math.max(...allX),
|
|
103
|
+
minZ: Math.min(...allZ),
|
|
104
|
+
maxZ: Math.max(...allZ),
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Filter city data to only include a subdirectory and optionally remap coordinates
|
|
109
|
+
* to make the subdirectory the new origin (0,0)
|
|
110
|
+
*/
|
|
111
|
+
const filterCityDataForSubdirectory = (cityData, subdirectoryPath, autoCenter = true) => {
|
|
112
|
+
if (!subdirectoryPath)
|
|
113
|
+
return cityData;
|
|
114
|
+
// Normalize path - remove leading/trailing slashes
|
|
115
|
+
const normalizedPath = subdirectoryPath.replace(/^\/+|\/+$/g, '');
|
|
116
|
+
// Filter buildings to only those within the subdirectory
|
|
117
|
+
const filteredBuildings = cityData.buildings.filter(building => building.path === normalizedPath ||
|
|
118
|
+
building.path.startsWith(normalizedPath + '/') ||
|
|
119
|
+
building.path.startsWith(`/${normalizedPath}`));
|
|
120
|
+
// Filter districts to only those within the subdirectory
|
|
121
|
+
const filteredDistricts = cityData.districts.filter(district => district.path === normalizedPath ||
|
|
122
|
+
district.path.startsWith(normalizedPath + '/') ||
|
|
123
|
+
district.path.startsWith(`/${normalizedPath}`));
|
|
124
|
+
// Find the subdirectory district to get its bounds
|
|
125
|
+
const subdirectoryDistrict = cityData.districts.find(d => d.path === normalizedPath);
|
|
126
|
+
if (!subdirectoryDistrict && filteredBuildings.length === 0) {
|
|
127
|
+
// Subdirectory not found or empty
|
|
128
|
+
return {
|
|
129
|
+
...cityData,
|
|
130
|
+
buildings: [],
|
|
131
|
+
districts: [],
|
|
132
|
+
bounds: { minX: 0, maxX: 100, minZ: 0, maxZ: 100 },
|
|
133
|
+
metadata: {
|
|
134
|
+
...cityData.metadata,
|
|
135
|
+
rootPath: normalizedPath,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// Calculate the bounds of the subdirectory content
|
|
140
|
+
const contentBounds = recalculateBounds(filteredBuildings, filteredDistricts);
|
|
141
|
+
let remappedBuildings;
|
|
142
|
+
let remappedDistricts;
|
|
143
|
+
let newBounds;
|
|
144
|
+
if (autoCenter) {
|
|
145
|
+
// Calculate offset to make subdirectory origin (0,0)
|
|
146
|
+
const offsetX = -contentBounds.minX;
|
|
147
|
+
const offsetZ = -contentBounds.minZ;
|
|
148
|
+
// Remap building coordinates relative to subdirectory origin
|
|
149
|
+
remappedBuildings = filteredBuildings.map(building => ({
|
|
150
|
+
...building,
|
|
151
|
+
position: {
|
|
152
|
+
...building.position,
|
|
153
|
+
x: building.position.x + offsetX,
|
|
154
|
+
z: building.position.z + offsetZ,
|
|
155
|
+
},
|
|
156
|
+
// Make path relative to subdirectory
|
|
157
|
+
path: building.path === normalizedPath
|
|
158
|
+
? building.path.split('/').pop() || building.path
|
|
159
|
+
: building.path.substring(normalizedPath.length + 1),
|
|
160
|
+
}));
|
|
161
|
+
// Remap district coordinates relative to subdirectory origin
|
|
162
|
+
remappedDistricts = filteredDistricts.map(district => ({
|
|
163
|
+
...district,
|
|
164
|
+
worldBounds: {
|
|
165
|
+
minX: district.worldBounds.minX + offsetX,
|
|
166
|
+
maxX: district.worldBounds.maxX + offsetX,
|
|
167
|
+
minZ: district.worldBounds.minZ + offsetZ,
|
|
168
|
+
maxZ: district.worldBounds.maxZ + offsetZ,
|
|
169
|
+
},
|
|
170
|
+
// Make path relative to subdirectory
|
|
171
|
+
path: district.path === normalizedPath
|
|
172
|
+
? '' // The subdirectory itself becomes the root
|
|
173
|
+
: district.path.substring(normalizedPath.length + 1),
|
|
174
|
+
}));
|
|
175
|
+
// New bounds with origin at (0,0)
|
|
176
|
+
newBounds = {
|
|
177
|
+
minX: 0,
|
|
178
|
+
maxX: contentBounds.maxX - contentBounds.minX,
|
|
179
|
+
minZ: 0,
|
|
180
|
+
maxZ: contentBounds.maxZ - contentBounds.minZ,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// Preserve original coordinates when autoCenter is disabled
|
|
185
|
+
remappedBuildings = filteredBuildings.map(building => ({
|
|
186
|
+
...building,
|
|
187
|
+
// Make path relative to subdirectory
|
|
188
|
+
path: building.path === normalizedPath
|
|
189
|
+
? building.path.split('/').pop() || building.path
|
|
190
|
+
: building.path.substring(normalizedPath.length + 1),
|
|
191
|
+
}));
|
|
192
|
+
remappedDistricts = filteredDistricts.map(district => ({
|
|
193
|
+
...district,
|
|
194
|
+
// Make path relative to subdirectory
|
|
195
|
+
path: district.path === normalizedPath
|
|
196
|
+
? '' // The subdirectory itself becomes the root
|
|
197
|
+
: district.path.substring(normalizedPath.length + 1),
|
|
198
|
+
}));
|
|
199
|
+
// Preserve original full city bounds to maintain spatial context
|
|
200
|
+
newBounds = cityData.bounds;
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
...cityData,
|
|
204
|
+
buildings: remappedBuildings,
|
|
205
|
+
districts: remappedDistricts,
|
|
206
|
+
bounds: newBounds,
|
|
207
|
+
metadata: {
|
|
208
|
+
...cityData.metadata,
|
|
209
|
+
rootPath: normalizedPath,
|
|
210
|
+
totalFiles: filteredBuildings.length,
|
|
211
|
+
totalDirectories: filteredDistricts.length,
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
exports.filterCityDataForSubdirectory = filterCityDataForSubdirectory;
|
|
216
|
+
/**
|
|
217
|
+
* Filter city data based on multiple directory filters with include/exclude modes
|
|
218
|
+
*/
|
|
219
|
+
const filterCityDataForMultipleDirectories = (cityData, filters, autoCenter = true, combineMode = 'union') => {
|
|
220
|
+
if (!filters || filters.length === 0)
|
|
221
|
+
return cityData;
|
|
222
|
+
// Normalize all filter paths
|
|
223
|
+
const normalizedFilters = filters.map(filter => ({
|
|
224
|
+
...filter,
|
|
225
|
+
path: filter.path.replace(/^\/+|\/+$/g, ''),
|
|
226
|
+
}));
|
|
227
|
+
const includeFilters = normalizedFilters.filter(f => f.mode === 'include');
|
|
228
|
+
const excludeFilters = normalizedFilters.filter(f => f.mode === 'exclude');
|
|
229
|
+
// Helper function to check if a path matches a filter
|
|
230
|
+
const matchesFilter = (itemPath, filterPath) => {
|
|
231
|
+
const normalizedItemPath = itemPath.replace(/^\/+/, '');
|
|
232
|
+
return normalizedItemPath === filterPath || normalizedItemPath.startsWith(filterPath + '/');
|
|
233
|
+
};
|
|
234
|
+
// Filter buildings based on include/exclude rules
|
|
235
|
+
const filteredBuildings = cityData.buildings.filter(building => {
|
|
236
|
+
// Check excludes first (they take precedence)
|
|
237
|
+
for (const filter of excludeFilters) {
|
|
238
|
+
if (matchesFilter(building.path, filter.path)) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// If we have includes, must match based on combine mode
|
|
243
|
+
if (includeFilters.length > 0) {
|
|
244
|
+
if (combineMode === 'union') {
|
|
245
|
+
// Union: match any include filter
|
|
246
|
+
return includeFilters.some(filter => matchesFilter(building.path, filter.path));
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// Intersection: must match all include filters (rare use case)
|
|
250
|
+
return includeFilters.every(filter => matchesFilter(building.path, filter.path));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// No includes means include everything (except excludes)
|
|
254
|
+
return true;
|
|
255
|
+
});
|
|
256
|
+
// Filter districts with the same logic
|
|
257
|
+
const filteredDistricts = cityData.districts.filter(district => {
|
|
258
|
+
// Check excludes first
|
|
259
|
+
for (const filter of excludeFilters) {
|
|
260
|
+
if (matchesFilter(district.path, filter.path)) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Check if district contains any included content
|
|
265
|
+
if (includeFilters.length > 0) {
|
|
266
|
+
if (combineMode === 'union') {
|
|
267
|
+
// Include district if it matches any filter or contains matching content
|
|
268
|
+
return includeFilters.some(filter => matchesFilter(district.path, filter.path) || matchesFilter(filter.path, district.path));
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
// Intersection mode for districts is complex - simplify to union behavior
|
|
272
|
+
return includeFilters.some(filter => matchesFilter(district.path, filter.path) || matchesFilter(filter.path, district.path));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return true;
|
|
276
|
+
});
|
|
277
|
+
// If nothing matches, return empty city
|
|
278
|
+
if (filteredBuildings.length === 0 && filteredDistricts.length === 0) {
|
|
279
|
+
return {
|
|
280
|
+
...cityData,
|
|
281
|
+
buildings: [],
|
|
282
|
+
districts: [],
|
|
283
|
+
bounds: { minX: 0, maxX: 100, minZ: 0, maxZ: 100 },
|
|
284
|
+
metadata: {
|
|
285
|
+
...cityData.metadata,
|
|
286
|
+
rootPath: filters.map(f => `${f.mode}:${f.path}`).join(', '),
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
// Calculate bounds and optionally recenter
|
|
291
|
+
const contentBounds = recalculateBounds(filteredBuildings, filteredDistricts);
|
|
292
|
+
if (autoCenter) {
|
|
293
|
+
// Calculate offset to center the content
|
|
294
|
+
const offsetX = -contentBounds.minX;
|
|
295
|
+
const offsetZ = -contentBounds.minZ;
|
|
296
|
+
// Remap coordinates
|
|
297
|
+
const remappedBuildings = filteredBuildings.map(building => ({
|
|
298
|
+
...building,
|
|
299
|
+
position: {
|
|
300
|
+
...building.position,
|
|
301
|
+
x: building.position.x + offsetX,
|
|
302
|
+
z: building.position.z + offsetZ,
|
|
303
|
+
},
|
|
304
|
+
}));
|
|
305
|
+
const remappedDistricts = filteredDistricts.map(district => ({
|
|
306
|
+
...district,
|
|
307
|
+
worldBounds: {
|
|
308
|
+
minX: district.worldBounds.minX + offsetX,
|
|
309
|
+
maxX: district.worldBounds.maxX + offsetX,
|
|
310
|
+
minZ: district.worldBounds.minZ + offsetZ,
|
|
311
|
+
maxZ: district.worldBounds.maxZ + offsetZ,
|
|
312
|
+
},
|
|
313
|
+
}));
|
|
314
|
+
return {
|
|
315
|
+
...cityData,
|
|
316
|
+
buildings: remappedBuildings,
|
|
317
|
+
districts: remappedDistricts,
|
|
318
|
+
bounds: {
|
|
319
|
+
minX: 0,
|
|
320
|
+
maxX: contentBounds.maxX - contentBounds.minX,
|
|
321
|
+
minZ: 0,
|
|
322
|
+
maxZ: contentBounds.maxZ - contentBounds.minZ,
|
|
323
|
+
},
|
|
324
|
+
metadata: {
|
|
325
|
+
...cityData.metadata,
|
|
326
|
+
rootPath: filters.map(f => `${f.mode}:${f.path}`).join(', '),
|
|
327
|
+
totalFiles: remappedBuildings.length,
|
|
328
|
+
totalDirectories: remappedDistricts.length,
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
// Return filtered data with original coordinates and bounds
|
|
334
|
+
return {
|
|
335
|
+
...cityData,
|
|
336
|
+
buildings: filteredBuildings,
|
|
337
|
+
districts: filteredDistricts,
|
|
338
|
+
bounds: cityData.bounds, // Preserve original bounds when autoCenter is false
|
|
339
|
+
metadata: {
|
|
340
|
+
...cityData.metadata,
|
|
341
|
+
rootPath: filters.map(f => `${f.mode}:${f.path}`).join(', '),
|
|
342
|
+
totalFiles: filteredBuildings.length,
|
|
343
|
+
totalDirectories: filteredDistricts.length,
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
exports.filterCityDataForMultipleDirectories = filterCityDataForMultipleDirectories;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HighlightLayer } from '../render/client/drawLayeredBuildings';
|
|
3
|
+
import { CityData, CityBuilding, CityDistrict, SelectiveRenderOptions } from '@principal-ai/file-city-builder';
|
|
4
|
+
export interface ArchitectureMapHighlightLayersProps {
|
|
5
|
+
cityData?: CityData;
|
|
6
|
+
highlightLayers?: HighlightLayer[];
|
|
7
|
+
onLayerToggle?: (layerId: string, enabled: boolean) => void;
|
|
8
|
+
showLayerControls?: boolean;
|
|
9
|
+
defaultBuildingColor?: string;
|
|
10
|
+
focusDirectory?: string | null;
|
|
11
|
+
rootDirectoryName?: string;
|
|
12
|
+
onDirectorySelect?: (directory: string | null) => void;
|
|
13
|
+
onFileClick?: (path: string, type: 'file' | 'directory') => void;
|
|
14
|
+
enableZoom?: boolean;
|
|
15
|
+
fullSize?: boolean;
|
|
16
|
+
showGrid?: boolean;
|
|
17
|
+
showFileNames?: boolean;
|
|
18
|
+
className?: string;
|
|
19
|
+
selectiveRender?: SelectiveRenderOptions;
|
|
20
|
+
canvasBackgroundColor?: string;
|
|
21
|
+
hoverBorderColor?: string;
|
|
22
|
+
disableOpacityDimming?: boolean;
|
|
23
|
+
defaultDirectoryColor?: string;
|
|
24
|
+
subdirectoryMode?: {
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
rootPath?: string;
|
|
27
|
+
autoCenter?: boolean;
|
|
28
|
+
filters?: Array<{
|
|
29
|
+
path: string;
|
|
30
|
+
mode: 'include' | 'exclude';
|
|
31
|
+
}>;
|
|
32
|
+
combineMode?: 'union' | 'intersection';
|
|
33
|
+
} | null;
|
|
34
|
+
showFileTypeIcons?: boolean;
|
|
35
|
+
showDirectoryLabels?: boolean;
|
|
36
|
+
transform?: {
|
|
37
|
+
rotation?: 0 | 90 | 180 | 270;
|
|
38
|
+
flipHorizontal?: boolean;
|
|
39
|
+
flipVertical?: boolean;
|
|
40
|
+
};
|
|
41
|
+
onHover?: (info: {
|
|
42
|
+
hoveredDistrict: CityDistrict | null;
|
|
43
|
+
hoveredBuilding: CityBuilding | null;
|
|
44
|
+
mousePos: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
};
|
|
48
|
+
fileTooltip: {
|
|
49
|
+
text: string;
|
|
50
|
+
} | null;
|
|
51
|
+
directoryTooltip: {
|
|
52
|
+
text: string;
|
|
53
|
+
} | null;
|
|
54
|
+
fileCount: number | null;
|
|
55
|
+
}) => void;
|
|
56
|
+
buildingBorderRadius?: number;
|
|
57
|
+
districtBorderRadius?: number;
|
|
58
|
+
}
|
|
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
|
|
60
|
+
onHover, buildingBorderRadius, districtBorderRadius, }: ArchitectureMapHighlightLayersProps): React.JSX.Element;
|
|
61
|
+
export declare const ArchitectureMapHighlightLayers: typeof ArchitectureMapHighlightLayersInner;
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=ArchitectureMapHighlightLayers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArchitectureMapHighlightLayers.d.ts","sourceRoot":"","sources":["../../src/components/ArchitectureMapHighlightLayers.tsx"],"names":[],"mappings":"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"}
|