@@ -6,161 +6,123 @@ const example = '[0[3216291:t;9219219;4608:s[156546;1612196;219621:~;321965149:4
6export interface ChartPoint {
6export interface ChartPoint {
7 patp: string,
7 patp: string,
8 dominion: ('l1' | 'l2' | 'spawn'),
8 dominion: ('l1' | 'l2' | 'spawn'),
10− pickedChildren?: boolean,
11− pickedSponsees?: boolean,
12 sponsor?: string,
9 sponsor?: string,
13 parent?: string,
10 parent?: string,
14 children?: ChartPoint[],
11 children?: ChartPoint[],
15 sponsees?: ChartPoint[],
12 sponsees?: ChartPoint[],
18−interface ChartSubs {
15+function parseMetaString(metaString: string): ChartPoint {
19− children: ChartPoint[],
16+ let idString, subMetaString = '';
20− sponsees: ChartPoint[],
17+ const colIndex = metaString.indexOf(':');
21−}
18+ if (colIndex === -1) {
22−
19+ idString = metaString;
23−class ChartDataParser {
20+ } else {
24− filter: Set<string>;
21+ idString = metaString.slice(0, colIndex);
25−
22+ subMetaString = metaString.slice(colIndex + 1);
26− constructor(filter: Set<string>) {
27− this.filter = filter;
29−
24+ const meta: ChartPoint = {
30− parseMetaString(metaString: string): ChartPoint {
31− let idString, subMetaString = '';
32− const colIndex = metaString.indexOf(':');
33− if (colIndex === -1) {
34− idString = metaString;
36− idString = metaString.slice(0, colIndex);
37− subMetaString = metaString.slice(colIndex + 1);
39− const patp = '~' + idString;
25+ patp: '~' + idString,
40− const meta: ChartPoint = {
42− picked: !this.filter ? true : (this.filter.has(patp)),
43− dominion: 'l1',
26+ dominion: 'l1',
29+ const firstChar = subMetaString[0];
30+ if (firstChar === 't') {
31+ meta.dominion = 'l2';
32+ subMetaString = subMetaString.slice(1);
33+ } else if (firstChar === 's') {
34+ meta.dominion = 'spawn';
35+ subMetaString = subMetaString.slice(1);
45 if (subMetaString) {
37 if (subMetaString) {
46− const firstChar = subMetaString[0];
47− if (firstChar === 't') {
48− meta.dominion = 'l2';
49− subMetaString = subMetaString.slice(1);
38+ if (subMetaString[0] === '~') {
50− } else if (firstChar === 's') {
51− meta.dominion = 'spawn';
52− subMetaString = subMetaString.slice(1);
55− if (subMetaString[0] === '~') {
56− meta.sponsor = null;
39+ meta.sponsor = null;
58− let [sponsor, parent] = subMetaString.slice(1).split('!');
41+ let [sponsor, parent] = subMetaString.slice(1).split('!');
59− meta.sponsor = '~' + sponsor;
42+ meta.sponsor = '~' + sponsor;
60− meta.parent = '~' + parent;
43+ meta.parent = '~' + parent;
67− extractMeta(data: string): [ChartPoint, string] {
50+function extractMeta(data: string): [ChartPoint, string] {
68− const index = data.search(/[[;]/);
51+ const index = data.search(/[[;]/);
69− if (index === -1) {
52+ if (index === -1) {
70− throw new Error(`No point meta present in ${data}`);
53+ throw new Error(`No point meta present in ${data}`);
72− const metaString = data.slice(0, index);
73− data = data.slice(index);
74− return [this.parseMetaString(metaString), data];
55+ const metaString = data.slice(0, index);
56+ data = data.slice(index);
57+ return [parseMetaString(metaString), data];
77− extractChildren(data: string, sup: string = undefined): [ChartSubs, string] {
60+function extractChildren(data: string, sup: string = undefined): [ChartPoint[], ChartPoint[], string] {
82− }, data.slice(1)];
61+ if (data[0] === ';') return [[], [], data.slice(1)];
83− if (data[0] !== '[') throw new Error('Invalid children in data: ' + data.slice(0, 20));
62+ if (data[0] !== '[') throw new Error('Invalid children in data: ' + data.slice(0, 20));
85− let endFound = false;
64+ let endFound = false;
86− let counter = 0;
65+ let counter = 0;
87− data = data.slice(1);
66+ data = data.slice(1);
88− const children = [];
67+ const children = [];
89− const sponsees = [];
68+ const sponsees = [];
90− while (!endFound && data.length && counter < 20000) {
69+ while (!endFound && data.length && counter < 20000) {
91− if (data[0] === ']') {
70+ if (data[0] === ']') {
92− endFound = true;
71+ endFound = true;
93− data = data.slice(1);
72+ data = data.slice(1);
96− [sub, data] = this.extractChartPoint(data);
75+ [sub, data] = extractChartPoint(data);
97− if (!sub.parent || sub.parent === sup)
76+ if (!sub.parent || sub.parent === sup)
98− children.push(sub);
77+ children.push(sub);
99− if (sub.sponsor === undefined || sub.sponsor === sup)
78+ if (sub.sponsor === undefined || sub.sponsor === sup)
100− sponsees.push(sub);
79+ sponsees.push(sub);
104− return [{ children, sponsees }, data];
81+ counter++;
107− extractChartPoint(data: string): [ChartPoint, string] {
109− [point, data] = this.extractMeta(data);
110− [subs, data] = this.extractChildren(data, point.patp);
115− return [point, data];
83+ return [children, sponsees, data];
118− linkChartData(points: ChartPoint[], store: any): ChartPoint[] {
86+function extractChartPoint(data: string): [ChartPoint, string] {
119− if (!points) return points;
87+ let point, children, sponsees;
120− return points.map(point => {
88+ [point, data] = extractMeta(data);
121− if (!store[point.patp]) return point;
89+ [children, sponsees, data] = extractChildren(data, point.patp);
122− if (!point.children?.length) {
90+ point.children = children;
123− point.children = this.linkChartData(store[point.patp].children, store);
91+ point.sponsees = sponsees;
124− let picked = point.children.filter(child => child.picked || child.pickedChildren);
125− point.pickedChildren = picked.length > 0;
127− if (!point.sponsees?.length) {
128− point.sponsees = this.linkChartData(store[point.patp].sponsees, store);
129− let picked = point.sponsees.filter(child => child.picked || child.pickedSponsees);
130− point.pickedSponsees = picked.length > 0;
132− return point;
92+ return [point, data];
136− parse(str: string): ChartSubs {
95+function linkChartData(points: ChartPoint[], store: any): ChartPoint[] {
137− if (!str) return { children: [], sponsees: [] };
96+ if (!points) return points;
138− let [{ children: baseChildren }, _] = this.extractChildren(str, undefined);
97+ return points.map(point => {
140− baseChildren.forEach(child => {
141− store[child.patp] = {
98+ if (!store[point.patp]) return point;
142− children: child.children,
99+ if (!point.children?.length) {
143− sponsees: child.sponsees,
100+ point.children = linkChartData(store[point.patp].children, store);
146− let base: ChartPoint = {
151−
102+ if (!point.sponsees?.length) {
152− let points = this.linkChartData([base], store);
103+ point.sponsees = linkChartData(store[point.patp].sponsees, store);
154− children: points[0].children || [],
155− sponsees: points[0].sponsees || [],
109+function _parseChartData(str: string): ChartPoint[] {
110+ if (!str) return [];
111+ let [baseChildren, _] = extractChildren(str);
113+ baseChildren.forEach(child => {
114+ store[child.patp] = {
115+ children: child.children,
116+ sponsees: child.sponsees,
120+ return linkChartData(store['~base'].children, store);
160−export function parseChartData(data: string, filter: Set<string>): ChartSubs {
123+export function parseChartData(data: string): ChartPoint[] {
161 let start = Date.now();
124 let start = Date.now();
162− let parser = new ChartDataParser(filter);
125+ let parsed = _parseChartData(data);
163− let parsed = parser.parse(data);
164 // console.log(`finished parsing chart data to js object in ${Date.now() - start} ms`);
126 // console.log(`finished parsing chart data to js object in ${Date.now() - start} ms`);
165 return parsed;
127 return parsed;
@@ -226,23 +188,16 @@ export function arrangePointsInSpirals(
226 minDistanceBetween,
188 minDistanceBetween,
229−type childKey = ('sponsees' | 'children');
191+
230−export function populateGraph(g: Graph, chartSubs: ChartSubs, subsKey: childKey, callback?): Graph {
192+export function populateGraph(g: Graph, chartData: ChartPoint[], bySponsor: boolean, callback?): Graph {
231− let pickedSubsKey = subsKey == 'children' ? 'pickedChildren' : 'pickedSponsees';
232− function pickedColor(point: ChartPoint, normal: string) {
233− return point.picked ? normal : (point[pickedSubsKey] ? colors.SUB_PICKED : colors.NOT_PICKED);
235− function pickedArmColor(point: ChartPoint, normal: string) {
236− return point[pickedSubsKey] ? normal : colors.NOT_PICKED;
238− let points = chartSubs[subsKey];
239− if (!(points instanceof Array)) return;
193+ if (!(chartData instanceof Array)) return;
240 if (!g) {
194 if (!g) {
241 g = new Graph();
195 g = new Graph();
243 g.clear();
197 g.clear();
200+ let subsKey = bySponsor ? 'sponsees' : 'children';
246 let sponsorEdges = [];
201 let sponsorEdges = [];
248 let offsetX = 0;
203 let offsetX = 0;
@@ -252,7 +207,7 @@ export function populateGraph(g: Graph, chartSubs: ChartSubs, subsKey: childKey,
252 let b = 9000000;
207 let b = 9000000;
253 let theta = 0;
208 let theta = 0;
255− points.forEach((galaxy, gi) => {
210+ chartData.forEach((galaxy, gi) => {
256 offsetX = 0 + (a + b * theta) * Math.cos(theta);
211 offsetX = 0 + (a + b * theta) * Math.cos(theta);
257 offsetY = 0 + (a + b * theta) * Math.sin(theta);
212 offsetY = 0 + (a + b * theta) * Math.sin(theta);
@@ -262,7 +217,7 @@ export function populateGraph(g: Graph, chartSubs: ChartSubs, subsKey: childKey,
262 g.addNode(gPatp, {
217 g.addNode(gPatp, {
263 label: gPatp,
218 label: gPatp,
265− color: itsYou ? colors.YOU : pickedColor(galaxy, colors.WHITE),
220+ color: itsYou ? colors.YOU : colors.WHITE,
266 x: offsetX,
221 x: offsetX,
267 y: offsetY,
222 y: offsetY,
268 zIndex: 10,
223 zIndex: 10,
@@ -287,7 +242,6 @@ export function populateGraph(g: Graph, chartSubs: ChartSubs, subsKey: childKey,
288 let lastStarArm = null;
243 let lastStarArm = null;
289 let lastStarPatp = null;
244 let lastStarPatp = null;
290− let GSarmColor = pickedArmColor(galaxy, colors.LGREY)
291 stars.forEach((star, si) => {
245 stars.forEach((star, si) => {
292 const sPatp = star.patp;
246 const sPatp = star.patp;
@@ -302,20 +256,20 @@ export function populateGraph(g: Graph, chartSubs: ChartSubs, subsKey: childKey,
302 g.addNode(sPatp, {
256 g.addNode(sPatp, {
303 label: sPatp,
257 label: sPatp,
304 size: starSize,
258 size: starSize,
305− color: itsYou ? colors.YOU : pickedColor(star, colors.GOLDT2),
259+ color: itsYou ? colors.YOU : colors.GOLDT2,
306 x: starX,
260 x: starX,
307 y: starY,
261 y: starY,
308 zIndex: 8,
262 zIndex: 8,
310 if (lastStarArm == arm) {
264 if (lastStarArm == arm) {
311 g.addEdge(sPatp, lastStarPatp, {
265 g.addEdge(sPatp, lastStarPatp, {
312− color: GSarmColor,
266+ color: colors.LGREY,
313 size: 0.1,
267 size: 0.1,
314 zIndex: 7,
268 zIndex: 7,
317 g.addEdge(sPatp, gPatp, {
271 g.addEdge(sPatp, gPatp, {
318− color: GSarmColor,
272+ color: colors.LGREY,
319 size: 0.2,
273 size: 0.2,
320 zIndex: 9,
274 zIndex: 9,
@@ -350,8 +304,7 @@ export function populateGraph(g: Graph, chartSubs: ChartSubs, subsKey: childKey,
351 let lastPlanetArm = null;
305 let lastPlanetArm = null;
352 let lastPlanetPatp = null;
306 let lastPlanetPatp = null;
353− let SParmColor = pickedArmColor(star, colors.DGREY)
354− planets.forEach((planet, pi) => {
307+ planets.forEach((planet, pi) => {
355 const pPatp = planet.patp;
308 const pPatp = planet.patp;
356 const [planetX, planetY] = planetCoords[pi].coords;
309 const [planetX, planetY] = planetCoords[pi].coords;
357 const arm = planetCoords[pi].arm;
310 const arm = planetCoords[pi].arm;
@@ -366,21 +319,21 @@ export function populateGraph(g: Graph, chartSubs: ChartSubs, subsKey: childKey,
366 g.addNode(pPatp, {
319 g.addNode(pPatp, {
367 label: pPatp,
320 label: pPatp,
368 size: planetSize,
321 size: planetSize,
369− color: itsYou ? colors.YOU : pickedColor(planet, planet.dominion == 'l2' ? colors.GREEN : colors.BLUE),
322+ color: itsYou ? colors.YOU : (planet.dominion == 'l2' ? colors.GREEN : colors.BLUE),
370 x: planetX,
323 x: planetX,
371 y: planetY,
324 y: planetY,
372 zIndex: 6,
325 zIndex: 6,
374 if (lastPlanetArm == arm) {
327 if (lastPlanetArm == arm) {
375 g.addEdge(pPatp, lastPlanetPatp, {
328 g.addEdge(pPatp, lastPlanetPatp, {
376− color: SParmColor,
329+ color: colors.DGREY,
377 size: planetEdgeSize,
330 size: planetEdgeSize,
378 zIndex: 5,
331 zIndex: 5,
381 if (numPlanetArms == 1) {
334 if (numPlanetArms == 1) {
382 g.addEdge(pPatp, sPatp, {
335 g.addEdge(pPatp, sPatp, {
383− color: SParmColor,
336+ color: colors.DGREY,
384 size: planetEdgeSize,
337 size: planetEdgeSize,
385 zIndex: 5,
338 zIndex: 5,