PageSourceSearch

https://theglobaljukebox.org/js/gjb-wheel.js

js theglobaljukebox.org collected 2026-10-02 06:15:20 UTC 24,575 bytes, 451 lines download raw bytes

1"use strict";
2var Gjb;
3(function (Gjb) {
4    var WheelNewClass = (function () {
5        function WheelNewClass() {
6            this._globeDataPath = 'data/worldtaxo/world-110m.json';
7            this._cx = 500;
8            this._cy = 450;
9            this._ringRotation = { region: 0, division: 0, subregion: 0, province: 0 };
10            this._globeAnimation = { startTime: 0, current: { lat: 0, lng: 0 }, target: { lat: 0, lng: 0 } };
11            this._isShowingNewWheel = true;
12            this._newWheelHtml = '<div id="newWheelContainer" class="wheel-container">' +
13                '  <div id="wheelElems">' +
14                '    <div id="wheelTaxoMenu"></div>' +
15                '    <div id="wheelBase" style="width: 1000px; height: 1000px; margin: 0 auto 0 auto;"></div>' +
16                '    <div id="wheelTextBase" class="new-wheel-text-area">' +
17                '       <div id="wheelNewTextHeader" class="new-wheel-text-header">The World</div>' +
18                '       <div class="new-wheel-text-separator"></div>' +
19                '       <div id="wheelNewTextSubhead" class="new-wheel-text-subhead"> </div>' +
20                '    <div>' +
21                '  </div>' +
22                '</div>';
23            $('#wheelNew').html(this._newWheelHtml);
24            this._projection = d3.geo.orthographic()
25                .translate([this._cx, this._cy])
26                .clipAngle(90);
27            this._path = d3.geo.path()
28                .projection(this._projection);
29        }
30        WheelNewClass.prototype._getNodeById = function (id) {
31            return ((isNaN(id) || (id !== Math.floor(id)) || (id <= 0)) ? undefined :
32                (id < 100) ? Gjb.newWorldRoot.allRegionsById[id] :
33                    (id < 10000) ? Gjb.newWorldRoot.allDivisionsById[id] :
34                        (id < 1000000) ? Gjb.newWorldRoot.allSubregionById[id] :
35                            (id < 100000000) ? Gjb.newWorldRoot.allProvincesById[id] : undefined);
36        };
37        WheelNewClass.prototype._getIndexOfNode = function (node) {
38            var index = node.selfAndSiblings.indexOf(node);
39            return index;
40        };
41        WheelNewClass.prototype._getChildrenOfNode = function (node) {
42            switch (node.nodeType) {
43                case 'worldroot': return node.regions;
44                case 'region': return node.divisions;
45                case 'division': return node.subregions;
46                case 'subregion': return node.provinces;
47                case 'province': return node.cultures;
48                default:
49                    console.error("* Wheel._getChildrenOfNode() failed; id ".concat(node.id, ", type ").concat(node.nodeType, ", name ").concat(node.name));
50                    return undefined;
51            }
52        };
53        WheelNewClass.prototype._createAnimationEl = function (type, from, to, dur, fill) {
54            var anim = document.createElementNS('http://www.w3.org/2000/svg', 'animateTransform');
55            anim.setAttributeNS(null, 'attributeName', 'transform');
56            anim.setAttributeNS(null, 'type', type);
57            anim.setAttributeNS(null, 'from', from.toString());
58            anim.setAttributeNS(null, 'to', to.toString());
59            anim.setAttributeNS(null, 'dur', dur.toString());
60            anim.setAttributeNS(null, 'fill', fill);
61            return anim;
62        };
63        WheelNewClass.prototype._buildGlobe = function () {
64            var _this = this;
65            d3.json(this._globeDataPath, function (error, world) {
66                d3.select('#globeRoot').append('g').append('path')
67                    .datum(topojson.object(world, world.objects.land))
68                    .attr('id', 'newWheelLand')
69                    .attr('class', 'land-new')
70                    .attr('d', _this._path)
71                    .attr('transform', function () { return 'translate(100, 90), scale(0.80)'; })
72                    .style('opacity', 1);
73            });
74        };
75        WheelNewClass.prototype._setGlobeColor = function (worldNode) {
76            var _a, _b;
77            var $globeBgCenterColor = document.getElementById('globeBgCenterColor');
78            var $globeBgEdgeColor = document.getElementById('globeBgEdgeColor');
79            if ($globeBgCenterColor && $globeBgEdgeColor) {
80                var centerColor = ((_a = worldNode === null || worldNode === void 0 ? void 0 : worldNode.colors) === null || _a === void 0 ? void 0 : _a.lighter) || "#aaa";
81                var edgeColor = ((_b = worldNode === null || worldNode === void 0 ? void 0 : worldNode.colors) === null || _b === void 0 ? void 0 : _b.darker) || "#444";
82                $globeBgCenterColor.setAttribute('stop-color', centerColor);
83                $globeBgEdgeColor.setAttribute('stop-color', edgeColor);
84            }
85        };
86        WheelNewClass.prototype._setGlobeTo = function (target) {
87            var _this = this;
88            this._globeAnimation.target.lat = (target || this._globeAnimation.target).lat;
89            this._globeAnimation.target.lng = (target || this._globeAnimation.target).lng;
90            var dLat = this._globeAnimation.target.lat - this._globeAnimation.current.lat;
91            var dLng = this._globeAnimation.target.lng - this._globeAnimation.current.lng;
92            var now = Date.now();
93            if ((Math.abs(dLat) < 0.01) && (Math.abs(dLng) < 0.01)) {
94                this._globeAnimation.current.lat = this._globeAnimation.target.lat;
95                this._globeAnimation.current.lng = this._globeAnimation.target.lng;
96                this._globeAnimation.startTime = 0;
97            }
98            else {
99                if (!this._globeAnimation.startTime) {
100                    this._globeAnimation.startTime = now;
101                }
102                var dt_msec = now - this._globeAnimation.startTime;
103                var spinupTime_msec = 1000;
104                var maxRateDegPerSec = 20 * Math.min(1, dt_msec / spinupTime_msec);
105                this._globeAnimation.current.lat += Math.min(maxRateDegPerSec, Math.max(-maxRateDegPerSec, dLat * 0.5));
106                this._globeAnimation.current.lng += Math.min(maxRateDegPerSec, Math.max(-maxRateDegPerSec, dLng * 0.5));
107                setTimeout(function () { _this._setGlobeTo(); }, 1000.0 / 30.0);
108            }
109            this._projection.rotate([-this._globeAnimation.current.lng, -this._globeAnimation.current.lat]);
110            d3.select('#wheelNew svg').selectAll('.land-new').attr('d', this._path);
111        };
112        WheelNewClass.prototype._updateGlobe = function () {
113            var worldNode = this._currentNode;
114            while (!worldNode.latLng && worldNode.parent) {
115                worldNode = worldNode.parent;
116            }
117            this._setGlobeColor(worldNode);
118            this._setGlobeTo(worldNode.latLng);
119            $('#wheelNewTextHeader').html(worldNode ? worldNode.localName : '');
120        };
121        WheelNewClass.prototype._updateTaxoMenu = function () {
122            var rootColor = '#D4CDC9';
123            var html = "<ul class=\"plain-list-left\"><h4 style=\"color: ".concat(rootColor, "\">") +
124                "  <span id=\"wheelTaxoMenu-the-world\" class=\"a-like\" style=\"color:".concat(rootColor, "\"") +
125                "    onclick=\"Gjb.WheelNew._onTaxoMenuItemClick('worldroot');\">" +
126                "  The World</span></h4>";
127            for (var _i = 0, _a = Gjb.newWorldRoot.regions; _i < _a.length; _i++) {
128                var region = _a[_i];
129                html += this._addNodeToTaxoMenuHtml(region);
130            }
131            html += "</ul>";
132            $('#wheelTaxoMenu').html(html);
133        };
134        WheelNewClass.prototype._addNodeToTaxoMenuHtml = function (node) {
135            var htmlId = "wheelTaxoMenu-".concat(node.nodeType, "-").concat(node.id);
136            var html = "<li id=\"".concat(htmlId, "\" class=\"culture-item-left\">") +
137                "  <span id=\"".concat(htmlId, "-self\" class=\"a-like").concat((node === this._currentNode) ? ' selected-taxo-item' : '', "\"") +
138                "    onclick=\"Gjb.WheelNew._onTaxoMenuItemClick(".concat(node.id, ");\"") +
139                "    style=\"color: ".concat(node.color, "\">
139").concat(node.name, "</span>");
140            if (this._isNodeInSelectedPath(node) && (node.nodeType !== 'province')) {
141                html += "<span id=\"".concat(htmlId, "-children\"><ul>");
142                for (var _i = 0, _a = this._getChildrenOfNode(node); _i < _a.length; _i++) {
143                    var childNode = _a[_i];
144                    html += this._addNodeToTaxoMenuHtml(childNode);
145                }
146                html += "</ul></span>";
147            }
148            html += "</li>";
149            return html;
150        };
151        WheelNewClass.prototype._isNodeInSelectedPath = function (node) {
152            var selectedNode = this._currentNode;
153            while (selectedNode.nodeType !== 'worldroot') {
154                if (node === selectedNode) {
155                    return true;
156                }
157                selectedNode = selectedNode.parent;
158            }
159            return false;
160        };
161        WheelNewClass.prototype._onTaxoMenuItemClick = function (nodeId) {
162            var node = (nodeId === 'worldroot') ? Gjb.newWorldRoot : this._getNodeById(nodeId);
163            if (node === this._currentNode) {
164                if (node.nodeType === 'worldroot') {
165                    return;
166                }
167                node = node.parent;
168            }
169            this.setWheelSelection(node, true);
170        };
171        WheelNewClass.prototype._onWedgeElMouseOver = function (nodeId) {
172            var node = this._getNodeById(nodeId);
173            $('#wheelNewTextSubhead').html(node.localName);
174        };
175        WheelNewClass.prototype._onWedgeElMouseOut = function () {
176            $('#wheelNewTextSubhead').html('');
177        };
178        WheelNewClass.prototype._onWedgeElClick = function (nodeId) {
179            var node = this._getNodeById(nodeId);
180            if (node === this._currentNode) {
181                node = node.parent;
182            }
183            this.setWheelSelection(node, true);
184        };
185        WheelNewClass.prototype._reduceRingRotationAngle = function (newAngle, oldAngle) {
186            var netRotation = Math.abs(newAngle - oldAngle);
187            if (netRotation > 180) {
188                newAngle = (newAngle > oldAngle) ? (newAngle - 360) : (newAngle + 360);
189            }
190            return (netRotation <= 180) ? newAngle : this._reduceRingRotationAngle(newAngle, oldAngle);
191        };
192        WheelNewClass.prototype._getRingKeyNodes = function (node) {
193            if ((node === null || node === void 0 ? void 0 : node.nodeType) === 'province') {
194                var p = node;
195                return [p.subregion.division.region, p.subregion.division, p.subregion, p];
196            }
197            else if ((node === null || node === void 0 ? void 0 : node.nodeType) === 'subregion') {
198                var s = node;
199                return [s.division.region, s.division, s, s.provinces[0]];
200            }
201            else if ((node === null || node === void 0 ? void 0 : node.nodeType) === 'division') {
202                var d = node;
203                return [d.region, d, d.subregions[0], undefined];
204            }
205            else if ((node === null || node === void 0 ? void 0 : node.nodeType) === 'region') {
206                var r = node;
207                return [r, r.divisions[0], undefined, undefined];
208            }
209            else {
210                return [Gjb.newWorldRoot.regions[0], undefined, undefined, undefined];
211            }
212        };
213        WheelNewClass.prototype._updateRings = function (prevCurrentNode) {
214            var isFirstUpdate = (prevCurrentNode === undefined);
215            var prevRingKeyNodes = this._getRingKeyNodes(prevCurrentNode);
216            var ringKeyNodes = this._getRingKeyNodes(this._currentNode);
217            var rings = ['region', 'division', 'subregion', 'province'];
218            var r_vals = [220, 208, 196, 184];
219            var w_vals = [200, 176, 152, 128];
220            for (var i = 0; i < 4; i++) {
221                var node = ringKeyNodes[i];
222                var ring = rings[i];
223                var ringRootEl = document.getElementById("".concat(ring, "RingRoot"));
224                if (node) {
225                    var nodes = node.selfAndSiblings;
226                    var index = this._getIndexOfNode(node);
227                    var numWedges = nodes.length;
228                    var ringNeedsMaking = isFirstUpdate || !prevRingKeyNodes[i] ||
229                        (nodes[0] !== prevRingKeyNodes[i].selfAndSiblings[0]);
230                    if (ringNeedsMaking) {
231                        this._removeRingChildren(ringRootEl);
232                        this._ringRotation[ring] = 0;
233                        var r = r_vals[i];
234                        var w = w_vals[i];
235                        var wegdeStep = (r * Math.PI * 2) / numWedges;
236                        var wedgeSkip = wegdeStep * (numWedges - 1);
237                        var initialOffset = ((r * Math.PI) + wegdeStep) / 2;
238                        for (var j = 0; j < nodes.length; j++) {
239                            var offset = initialOffset - (wegdeStep * j);
240                            var wedge = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
241                            wedge.setAttributeNS(null, 'r', "".concat(r));
242                            wedge.setAttributeNS(null, 'fill', "none");
243                            wedge.setAttributeNS(null, 'style', "stroke:".concat(nodes[j].color, ";stroke-width:").concat(w, ";stroke-dasharray:").concat(wegdeStep, " ").concat(wedgeSkip, ";") +
244                                "stroke-dashoffset:".concat(offset, ";cursor:pointer"));
245                            wedge.setAttributeNS(null, 'onmouseover', "Gjb.WheelNew._onWedgeElMouseOver(".concat(nodes[j].id, ");"));
246                            wedge.setAttributeNS(null, 'onmouseout', "Gjb.WheelNew._onWedgeElMouseOut();");
247                            wedge.setAttributeNS(null, 'onclick', "Gjb.WheelNew._onWedgeElClick(".concat(nodes[j].id, ");"));
248                            ringRootEl.appendChild(wedge);
249                        }
250                        var anim = this._createAnimationEl('scale', 0.1, 1.0, 0.4, 'freeze');
251                        ringRootEl.appendChild(anim);
252                        anim.beginElement();
253                    }
254                    var oldAngle = this._ringRotation[ring];
255                    var newAngle = this._reduceRingRotationAngle(360 * index / -numWedges, oldAngle);
256                    var absRotation = Math.abs(newAngle - oldAngle);
257                    if (absRotation > 0) {
258                        var duration = 0.25 + (absRotation / 500);
259                        var anim = this._createAnimationEl('rotate', oldAngle, newAngle, duration, 'freeze');
260                        ringRootEl.appendChild(anim);
261                        anim.beginElement();
262                        this._ringRotation[ring] = newAngle;
263                    }
264                }
265                else {
266                    var animate = prevRingKeyNodes[i] ? true : false;
267                    if (animate) {
268                        var anim = this._createAnimationEl('scale', 1.0, 0.1, 0.25, 'freeze');
269                        ringRootEl.appendChild(anim);
270                        anim.beginElement();
271                    }
272                    else {
273                        this._removeRingChildren(ringRootEl);
274                    }
275                }
276            }
277        };
278        WheelNewClass.prototype._removeRingChildren = function (ringRootEl) {
279            for (var i = (ringRootEl.children.length - 1); i >= 0; i--) {
280                var child = ringRootEl.children[i];
281                ringRootEl.removeChild(child);
282            }
283        };
284        WheelNewClass.prototype.makeWheel = function () {
285            var ringHtml = "<svg height=\"1000\" width=\"1000\">\n            <g transform=\"translate(".concat(this._cx, " ").concat(this._cy, ")\">\n              <g id=\"regionRingRoot\"></g>\n              <g id=\"divisionRingRoot\"></g>\n              <g id=\"subregionRingRoot\"></g>\n              <g id=\"provinceRingRoot\"></g>\n              <g id=\"globeBackDisc\">\n                <defs>\n                  <radialGradient id=\"wheelBgGrad\" fx=\"50%\" fy=\"50%\" r=\"50%\">\n                    <stop id=\"globeBgCenterColor\" offset=\"0%\" stop-color=\"#aaa\" stop-opacity=\"1\" />\n                    <stop id=\"globeBgEdgeColor\" offset=\"100%\" stop-color=\"#444\" stop-opacity=\"1\" />\n                  </radialGradient>\n                </defs>\n                <circle r=\"120\" fill=\"url(#wheelBgGrad)\"></circle>\n              </g>\n            </g>\n            <g id=\"globeRoot\"></g>\n          </svg>");
286            $('#wheelBase').append(ringHtml);
287            this._buildGlobe();
288            this._currentNode = undefined;
289            this.setWheelSelection(Gjb.newWorldRoot);
290        };
291        WheelNewClass.prototype.setWheelSelection = function (node, isUserAction, autoPlaySongs, fromFeature) {
292            if (isUserAction === void 0) { isUserAction = false; }
293            if (autoPlaySongs === void 0) { autoPlaySongs = true; }
294            if (fromFeature === void 0) { fromFeature = false; }
295            if (this.isShowingNewWheel) {
296                if (node === this._currentNode) {
297                    return;
298                }
299                if (isUserAction && Gjb.Core.selectedCulture) {
300                    Gjb.Core.clearCulture();
301                }
302                var prevCurrentNode = this._currentNode;
303                this._currentNode = node;
304                this._updateTaxoMenu();
305                this._updateRings(prevCurrentNode);
306                this._updateGlobe();
307                if (!fromFeature && (node.nodeType !== 'region')) {
308                    if (Gjb.Core.isSimilarityMode) {
309                        console.log("setWheelSelection - is similiarities mode, not from feature");
310                        Gjb.Similarities.setState(this._currentNode);
311                    }
312                    else if (Gjb.Core.isProfilesMode) {
313                        console.log("setWheelSelection - is profiles mode, not from feature");
314                        Gjb.Profiles.setState(this._currentNode);
315                    }
316                }
317                if (node.nodeType === 'province') {
318                    if (!Gjb.Core.isSimilarityMode) {
319                        this._currentProvince = node;
320                        if (isUserAction) {
321                            Gjb.Core.selectProvince(this._currentProvince, autoPlaySongs);
322                        }
323                    }
324                }
325                else if (this._currentProvince) {
326                    if (isUserAction) {
327                        Gjb.Core.closeProvinceFromMapOrWheel(this._currentProvince, true);
328                    }
329                    this._currentProvince = undefined;
330                }
331                if (node.nodeType === 'region') {
332                    if (Gjb.Core.isProfilesMode || Gjb.Core.isSimilarityMode) {
333                        for (var _i = 0, _a = Gjb.TaxoData.currentWorldRoot.allCultures; _i < _a.length; _i++) {
334                            var culture = _a[_i];
335                            if (culture.region === node) {
336                                if (Gjb.Core.isProfilesMode) {
337                                    Gjb.Profiles.onNewSelectedCulture(culture);
338                                }
339                                else if (Gjb.Core.isSimilarityMode) {
340                                    Gjb.Similarities.onNewSelectedCulture(culture);
341                                }
342                                break;
343                            }
344                        }
345                    }
346                }
347                if (isUserAction) {
348                    Gjb.Routes.onWheelSelection();
349                }
350            }
351        };
352        WheelNewClass.prototype.validateWheelSelection = function (wheelNodeId) {
353            return (wheelNodeId === 'worldroot') ? Gjb.newWorldRoot : this._getNodeById(parseInt(wheelNodeId));
354        };
355        WheelNewClass.prototype.updateSelectedNodeFromFeature = function (subjectNode) {
356            if (this.isShowingNewWheel) {
357                if (subjectNode === this._currentNode) {
358                    return;
359                }
360                var selectionCulture = undefined;
361                if (subjectNode.nodeType === 'people') {
362                    selectionCulture = subjectNode.cultures[0];
363                }
364                else if (subjectNode.nodeType === 'culture') {
365                    selectionCulture = subjectNode;
366                }
367                else if (subjectNode.nodeType === 'song') {
368                    selectionCulture = subjectNode.culture;
369                }
370                if (selectionCulture) {
371                    this.setWheelSelection((selectionCulture === null || selectionCulture === void 0 ? void 0 : selectionCulture.province) || subjectNode, false, false, true);
372                    this._setGlobeTo(selectionCulture.latLng || selectionCulture.province.latLng);
373                }
374                else {
375                    this.setWheelSelection((selectionCulture === null || selectionCulture === void 0 ? void 0 : selectionCulture.province) || subjectNode, false, true, true);
376                }
377            }
378        };
379        WheelNewClass.prototype.selectProvince = function (province, autoPlaySongs) {
380            if (autoPlaySongs === void 0) { autoPlaySongs = true; }
381            if (this.isShowingNewWheel) {
382                this.setWheelSelection(province, false, autoPlaySongs);
383            }
384        };
385        WheelNewClass.prototype.closeProvince = function (province) {
386            if (this.isShowingNewWheel) {
387                this._currentProvince = undefined;
388                if (this._currentNode.nodeType === 'province') {
389                    this.setWheelSelection(this._currentNode.parent);
390                }
391            }
392        };
393        WheelNewClass.prototype.updateWheelCulture = function (culture) {
394            if (this.isShowingNewWheel) {
395                if (culture) {
396                    this.setWheelSelection(culture.province);
397                    this._setGlobeTo(culture.latLng || culture.province.latLng);
398                }
399            }
400        };
401        WheelNewClass.prototype.resetWheel = function () {
402            this.setWheelSelection(Gjb.newWorldRoot);
403        };
404        WheelNewClass.prototype.switchEducationStyle = function () {
405            var $newWheelContainer = $('#newWheelContainer');
406            if (Gjb.Core.isEducationMode) {
407                $newWheelContainer.removeClass('wheel-container');
408                $newWheelContainer.addClass('wheel-container-edu');
409                $('#wheelTaxoMenu').addClass('culture-menu-bg-edu');
410            }
411            else {
412                $newWheelContainer.removeClass('wheel-container-edu');
413                $newWheelContainer.addClass('wheel-container');
414                $('#wheelTaxoMenu').removeClass('culture-menu-bg-edu');
415            }
416        };
417        Object.defineProperty(WheelNewClass.prototype, "isShowingNewWheel", {
418            get: function () {
419                return this._isShowingNewWheel;
420            },
421            enumerable: false,
422            configurable: true
423        });
424        WheelNewClass.prototype.showNewWheel = function () {
425            this._isShowingNewWheel = true;
426            if (Gjb.Core.activeView === Gjb.ViewTypes.wheel) {
427                $('#wheelNew').css('visibility', 'visible');
428                $('#wheelOld').css('visibility', 'hidden');
429            }
430        };
431        WheelNewClass.prototype.showOldWheel = function () {
432            this._isShowingNewWheel = false;
433            if (!Gjb.WheelOld) {
434                Gjb.WheelOld = new Gjb.WheelOldClass();
435            }
436            if (Gjb.Core.activeView === Gjb.ViewTypes.wheel) {
437                $('#wheelNew').css('visibility', 'hidden');
438                $('#wheelOld').css('visibility', 'visible');
439            }
440        };
441        Object.defineProperty(WheelNewClass.prototype, "wheelSelection", {
442            get: function () {
443                return { type: 'wheel', selectedNode: this._currentNode };
444            },
445            enumerable: false,
446            configurable: true
447        });
448        return WheelNewClass;
449    }());
450    Gjb.WheelNewClass = WheelNewClass;
451})(Gjb || (Gjb = {}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.