-
-
Notifications
You must be signed in to change notification settings - Fork 901
Split label view data #1313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Split label view data #1313
Changes from 4 commits
7bf33b6
dac231f
c467f87
94b638f
689fef0
2379770
471e865
ca6d01f
3ab40ad
6ab2c03
861db87
0d56479
c22e6eb
32e7049
6d99d82
6fa3f78
e174056
ba0ce8e
fd32007
3927a76
fab495f
25824fe
5f35924
967e889
9b4add5
baeab35
5d90b66
470c42a
5c5f6c0
924b537
563e1c9
aa2d4d9
e4a4c92
2bed4d5
c0dcad1
854cefe
6324eb6
3e29f3e
d84292e
701448b
0b772be
368eec0
0433669
33b9599
d4c7fb1
8b98578
fd0bd4d
27e35d4
3664ac8
3aa69bf
de3c861
7cc7a69
5ce7498
e80c859
9eb45be
ec742de
6808bb9
d66d6d2
d1a356b
192a609
74c86b0
84c4ff6
e350027
b791da5
50955d8
2108b9a
18231da
919a766
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,224 @@ | ||
| declare global { | ||
| var Labels: LabelsModule; | ||
| } | ||
|
|
||
| export interface StateLabelData { | ||
|
StempunkDev marked this conversation as resolved.
Outdated
|
||
| i: number; | ||
| type: "state"; | ||
| stateId: number; | ||
| text: string; | ||
| fontSize?: number; | ||
|
StempunkDev marked this conversation as resolved.
|
||
| } | ||
|
|
||
| export interface BurgLabelData { | ||
| i: number; | ||
| type: "burg"; | ||
| burgId: number; | ||
| group: string; | ||
| text: string; | ||
| x: number; | ||
| y: number; | ||
| dx: number; | ||
| dy: number; | ||
| } | ||
|
|
||
| export interface CustomLabelData { | ||
| i: number; | ||
| type: "custom"; | ||
| group: string; | ||
| text: string; | ||
| pathPoints: [number, number][]; | ||
| startOffset?: number; | ||
| fontSize?: number; | ||
| letterSpacing?: number; | ||
| transform?: string; | ||
|
StempunkDev marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| export type LabelData = StateLabelData | BurgLabelData | CustomLabelData; | ||
|
|
||
| class LabelsModule { | ||
| private getNextId(): number { | ||
| const labels = pack.labels; | ||
| if (labels.length === 0) return 0; | ||
|
StempunkDev marked this conversation as resolved.
Outdated
|
||
|
|
||
| const existingIds = labels.map((l) => l.i).sort((a, b) => a - b); | ||
| for (let id = 0; id < existingIds[existingIds.length - 1]; id++) { | ||
| if (!existingIds.includes(id)) return id; | ||
| } | ||
| return existingIds[existingIds.length - 1] + 1; | ||
|
StempunkDev marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| generate() : void { | ||
| this.clear(); | ||
| generateStateLabels(); | ||
| generateBurgLabels(); | ||
| } | ||
|
|
||
| getAll(): LabelData[] { | ||
| return pack.labels; | ||
| } | ||
|
|
||
| get(id: number): LabelData | undefined { | ||
| return pack.labels.find((l) => l.i === id); | ||
| } | ||
|
|
||
| getByType(type: LabelData["type"]): LabelData[] { | ||
|
Azgaar marked this conversation as resolved.
Outdated
|
||
| return pack.labels.filter((l) => l.type === type); | ||
| } | ||
|
|
||
| getByGroup(group: string): LabelData[] { | ||
| return pack.labels.filter( | ||
| (l) => (l.type === "burg" || l.type === "custom") && l.group === group, | ||
| ); | ||
| } | ||
|
|
||
| getStateLabel(stateId: number): StateLabelData | undefined { | ||
|
StempunkDev marked this conversation as resolved.
Outdated
|
||
| return pack.labels.find( | ||
| (l) => l.type === "state" && l.stateId === stateId, | ||
| ) as StateLabelData | undefined; | ||
| } | ||
|
|
||
| getBurgLabel(burgId: number): BurgLabelData | undefined { | ||
| return pack.labels.find( | ||
| (l) => l.type === "burg" && l.burgId === burgId, | ||
| ) as BurgLabelData | undefined; | ||
| } | ||
|
|
||
| addStateLabel( | ||
| data: Omit<StateLabelData, "i" | "type">, | ||
| ): StateLabelData { | ||
| const label: StateLabelData = { i: this.getNextId(), type: "state", ...data }; | ||
| pack.labels.push(label); | ||
| return label; | ||
| } | ||
|
|
||
| addBurgLabel(data: Omit<BurgLabelData, "i" | "type">): BurgLabelData { | ||
| const label: BurgLabelData = { i: this.getNextId(), type: "burg", ...data }; | ||
| pack.labels.push(label); | ||
| return label; | ||
| } | ||
|
|
||
| addCustomLabel( | ||
| data: Omit<CustomLabelData, "i" | "type">, | ||
| ): CustomLabelData { | ||
| const label: CustomLabelData = { i: this.getNextId(), type: "custom", ...data }; | ||
| pack.labels.push(label); | ||
| return label; | ||
| } | ||
|
|
||
| updateLabel(id: number, updates: Partial<LabelData>): void { | ||
|
StempunkDev marked this conversation as resolved.
Outdated
|
||
| const label = pack.labels.find((l) => l.i === id); | ||
| if (!label) return; | ||
|
StempunkDev marked this conversation as resolved.
Outdated
|
||
| Object.assign(label, updates, { i: label.i, type: label.type }); | ||
| } | ||
|
|
||
| removeLabel(id: number): void { | ||
| const index = pack.labels.findIndex((l) => l.i === id); | ||
| if (index !== -1) pack.labels.splice(index, 1); | ||
| } | ||
|
|
||
| removeByType(type: LabelData["type"]): void { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we have only 1
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have tried to reduce the amount of remove methods. I would like to keep these three methods since the other two removes offer shrinking of the labels array. Another way would be to offer a remove method with a function as parameter that would make two. One for single Item removal and one for group removal |
||
| pack.labels = pack.labels.filter((l) => l.type !== type); | ||
| } | ||
|
|
||
| removeByGroup(group: string): void { | ||
| pack.labels = pack.labels.filter( | ||
| (l) => | ||
| !((l.type === "burg" || l.type === "custom") && l.group === group), | ||
| ); | ||
| } | ||
|
|
||
| removeStateLabel(stateId: number): void { | ||
| const index = pack.labels.findIndex( | ||
| (l) => l.type === "state" && l.stateId === stateId, | ||
| ); | ||
| if (index !== -1) pack.labels.splice(index, 1); | ||
| } | ||
|
|
||
| removeBurgLabel(burgId: number): void { | ||
| const index = pack.labels.findIndex( | ||
| (l) => l.type === "burg" && l.burgId === burgId, | ||
| ); | ||
| if (index !== -1) pack.labels.splice(index, 1); | ||
| } | ||
|
|
||
| clear(): void { | ||
| pack.labels = []; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Generate state labels data entries for each state. | ||
| * Only stores essential label data; raycast path calculation happens during rendering. | ||
| * @param list - Optional array of stateIds to regenerate only those | ||
| */ | ||
| export function generateStateLabels(list?: number[]): void { | ||
| if (!TIME) console.time("generateStateLabels"); | ||
| else TIME && console.time("generateStateLabels"); | ||
|
|
||
|
StempunkDev marked this conversation as resolved.
Outdated
|
||
| const { states } = pack; | ||
| const labelsModule = window.Labels; | ||
|
|
||
| // Remove existing state labels that need regeneration | ||
| if (list) { | ||
| list.forEach((stateId) => labelsModule.removeStateLabel(stateId)); | ||
| } else { | ||
| labelsModule.removeByType("state"); | ||
| } | ||
|
|
||
| // Generate new label entries | ||
| for (const state of states) { | ||
| if (!state.i || state.removed || state.lock) continue; | ||
| if (list && !list.includes(state.i)) continue; | ||
|
|
||
| labelsModule.addStateLabel({ | ||
| stateId: state.i, | ||
| text: state.name!, | ||
| fontSize: 100, | ||
| }); | ||
| } | ||
|
|
||
| if (!TIME) console.timeEnd("generateStateLabels"); | ||
| else TIME && console.timeEnd("generateStateLabels"); | ||
| } | ||
|
|
||
| /** | ||
| * Generate burg labels data from burgs. | ||
| * Populates pack.labels with BurgLabelData for each burg. | ||
| */ | ||
| export function generateBurgLabels(): void { | ||
| if (!TIME) console.time("generateBurgLabels"); | ||
| else TIME && console.time("generateBurgLabels"); | ||
|
|
||
| const labelsModule = window.Labels; | ||
|
|
||
| // Remove existing burg labels | ||
| labelsModule.removeByType("burg"); | ||
|
|
||
| // Generate new labels for all active burgs | ||
| for (const burg of pack.burgs) { | ||
| if (!burg.i || burg.removed) continue; | ||
|
|
||
| const group = burg.group || "unmarked"; | ||
|
|
||
| // Get label group offset attributes if they exist (will be set during rendering) | ||
| // For now, use defaults - these will be updated during rendering phase | ||
| const dx = 0; | ||
| const dy = 0; | ||
|
|
||
| labelsModule.addBurgLabel({ | ||
| burgId: burg.i, | ||
| group, | ||
| text: burg.name!, | ||
| x: burg.x, | ||
| y: burg.y, | ||
| dx, | ||
| dy, | ||
| }); | ||
| } | ||
|
|
||
| if (!TIME) console.timeEnd("generateBurgLabels"); | ||
| else TIME && console.timeEnd("generateBurgLabels"); | ||
| } | ||
|
|
||
| window.Labels = new LabelsModule(); | ||
Uh oh!
There was an error while loading. Please reload this page.