More actions
Bez shrnutí editace |
IE 11 |
||
Riadok 1: | Riadok 1: | ||
(function () { | (function () { | ||
var tippyInstancia = tippy(document.createElement("div")); | |||
/** | /** | ||
* Vytvorí JSON pojmovej mapy z obsahu stránky. | |||
* | |||
* @param {HTMLElement} poznamkyElement Element, ktorý obsahuje poznámky. | |||
* @returns {object} JSON reprezentácia pojmovej mapy. | |||
**/ | |||
function vytvoritDataMapy(poznamkyElement) { | function vytvoritDataMapy(poznamkyElement) { | ||
var nadpisy = poznamkyElement.querySelectorAll("h1, h2, h3, h4, h5, h6"); | |||
var mapa = { | |||
vrcholy: [], | |||
hrany: [] | |||
}; | |||
// Zoznam, ktorý uchováva posledný nadpis na každej úrovni | // Zoznam, ktorý uchováva posledný nadpis na každej úrovni | ||
var posledneNadpisy = []; | |||
for (var i = 0; i < nadpisy.length; i++) { | |||
for ( | var nadpis = nadpisy[i]; | ||
var aktualnyLevel = ziskatLevelNadpisu(nadpis); | |||
var idVrchola = i + 1; | |||
var nazov = nadpis.querySelector(".mw-headline").innerText.slice(2); | |||
var idRodica = posledneNadpisy[aktualnyLevel - 1] || 1; | |||
mapa.vrcholy.push({ | |||
id: idVrchola, | |||
label: nazov, | |||
color: generovatFarbu(idRodica * aktualnyLevel), | |||
tooltip: obsahNadpisu(nadpis) | |||
}); | |||
if (aktualnyLevel > 1) { | |||
mapa.hrany.push({ | |||
from: idRodica, | |||
to: idVrchola | |||
}); | }); | ||
} | |||
// Aktualizujte posledný nadpis na úrovni | |||
posledneNadpisy[aktualnyLevel] = idVrchola; | |||
// Vymažte všetky nadpisy na vyšších úrovniach | |||
for (var j = aktualnyLevel + 1; j < posledneNadpisy.length; j++) { | |||
delete posledneNadpisy[j]; | |||
} | |||
} | } | ||
return mapa; | return mapa; | ||
} | } | ||
/** | /** | ||
* Získa obsah nadpisu a všetkých nasledujúcich elementov, ktoré nie sú nadpisy. | |||
* Obsah je v HTML formáte. | |||
* | |||
* @param {HTMLElement} nadpisElement HTML element nadpisu. | |||
* @returns {string} Obsah nadpisu a všetkých nasledujúcich elementov, ktoré nie sú nadpisy. | |||
**/ | |||
function obsahNadpisu(nadpisElement) { | function obsahNadpisu(nadpisElement) { | ||
var obsah = ""; | |||
var element = nadpisElement.nextElementSibling; | |||
while (element && !["H1", "H2", "H3", "H4", "H5", "H6"].includes(element.tagName)) { | |||
while ( | obsah += element.outerHTML; | ||
element = element.nextElementSibling; | |||
} | } | ||
return obsah; | return obsah; | ||
} | } | ||
/** | |||
* Vygeneruje zobrazenie pojmovej mapy. | |||
* | |||
* @param {HTMLElement} elementMapy Element, do ktorého sa vloží zobrazenie pojmovej mapy. | |||
* @param {object} jsonMapy JSON reprezentácia pojmovej mapy. | |||
* @returns {object} Objekt pojmovej mapy (vis-network). | |||
**/ | |||
function vykreslitMapu(elementMapy, jsonMapy) { | |||
var sirkaZobrazenia = window.innerWidth; | |||
var jeSirokeZobrazenie = sirkaZobrazenia > 768; | |||
var dataSiete = { | |||
nodes: new vis.DataSet(jsonMapy.vrcholy), | |||
edges: new vis.DataSet(jsonMapy.hrany) | |||
}; | }; | ||
var nastavenia = { | |||
interaction: { | |||
hover: true, | |||
keyboard: { | |||
enabled: true, | |||
bindToWindow: false, | |||
autoFocus: false | |||
} | |||
}, | |||
nodes: { | |||
shape: "box", | |||
widthConstraint: { | |||
maximum: 200 | |||
}, | }, | ||
margin: 10, | |||
labelHighlightBold: false | |||
}, | |||
edges: { | |||
smooth: { | |||
type: "dynamic", | |||
roundness: 0.5 | |||
}, | }, | ||
width: 0.75, | |||
arrows: { | |||
to: { | |||
enabled: true | |||
} | |||
} | |||
}, | |||
layout: { | |||
hierarchical: { | |||
enabled: true, | |||
direction: jeSirokeZobrazenie ? "UD" : "LR", | |||
sortMethod: "directed", | |||
nodeSpacing: jeSirokeZobrazenie ? 220 : 100, | |||
levelSeparation: jeSirokeZobrazenie ? 100 : 250, | |||
shakeTowards: "roots" | |||
} | |||
}, | |||
physics: false | |||
}; | }; | ||
pojmova_mapa = new vis.Network(elementMapy, dataSiete, nastavenia); | pojmova_mapa = new vis.Network(elementMapy, dataSiete, nastavenia); | ||
pojmova_mapa.on("hoverNode", function (parametre) { | |||
pojmova_mapa.on("hoverNode", (parametre) | var obsah = jsonMapy.vrcholy.find(function (vrchol) { | ||
return vrchol.id === parametre.node; | |||
}).tooltip; | |||
if (!parametre.node || !obsah) return; | |||
tippyInstancia.setProps({ | |||
triggerTarget: elementMapy, | |||
maxWidth: "90vw", | |||
allowHTML: true, | |||
getReferenceClientRect: function getReferenceClientRect() { | |||
return { | |||
width: 0, | |||
height: 0, | |||
left: window.innerWidth / 2, | |||
right: window.innerWidth / 2, | |||
top: window.innerHeight - 10 | |||
}; | |||
}, | |||
interact: true | |||
}); | |||
tippyInstancia.setContent("<div style=\"padding: 1rem 0.5rem; font-size: 12px;\">".concat(obsah, "</div>")); | |||
tippyInstancia.show(); | |||
MathJax.typesetPromise([tippyInstancia.popper]); | |||
}); | }); | ||
pojmova_mapa.on("blurNode", function () { | |||
pojmova_mapa.on("blurNode", () | tippyInstancia.hide(); | ||
}); | }); | ||
return pojmova_mapa; | return pojmova_mapa; | ||
} | } | ||
/** | /** | ||
* Získa úroveň nadpisu (h1, h2, atď.). | |||
* | |||
* @param {HTMLElement} nadpis HTML element nadpisu. | |||
* @returns {number} Číselná reprezentácia úrovne nadpisu. | |||
**/ | |||
function ziskatLevelNadpisu(nadpis) { | function ziskatLevelNadpisu(nadpis) { | ||
return parseInt(nadpis.tagName.substring(1), 10); | return parseInt(nadpis.tagName.substring(1), 10); | ||
} | } | ||
/** | |||
* Generuje náhodné číslo z čísla (seed). Rovnaký seed vždy vygeneruje rovnaké "náhodné" číslo v určenom rozsahu. | |||
* | |||
* https://stackoverflow.com/a/63599906 | |||
* | |||
* @param {number} seed Číslo, z ktorého sa generuje náhodné číslo. | |||
* @param {number[]} rozsah Rozsah, v ktorom sa náhodné číslo generuje. | |||
* @returns {number} Náhodné číslo. | |||
**/ | |||
function nahodneCislo(seed) { | |||
var rozsah = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0, 255]; | |||
seed = String(seed).split("").reduce(function (c, n) { | |||
return n != 0 ? c * n : c * c; | |||
}); | |||
var od = rozsah[0]; | |||
var po = rozsah[1]; | |||
while (seed < rozsah[0] || seed > rozsah[1]) { | while (seed < rozsah[0] || seed > rozsah[1]) { | ||
if (seed > rozsah[1]) seed = Math.floor(seed / po--); | |||
if (seed < rozsah[0]) seed = Math.floor(seed * od++); | |||
} | } | ||
return seed; | return seed; | ||
} | } | ||
/** | |||
* Generuje náhodnú farbu z čísla. Rovnaké číslo vždy vygeneruje rovnakú farbu. | |||
* | |||
* @param {number} cislo Číslo, z ktorého sa generuje farba. | |||
* @returns {string} Farba v RBG formáte. | |||
**/ | |||
function generovatFarbu() { | |||
var seed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; | |||
var svetla = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | |||
var od = svetla ? 125 : 0; | |||
var po = svetla ? 255 : 125; | |||
r = nahodneCislo(seed + 11, [od, po]); | r = nahodneCislo(seed + 11, [od, po]); | ||
g = nahodneCislo(seed + 12, [od, po]); | g = nahodneCislo(seed + 12, [od, po]); | ||
b = nahodneCislo(seed + 13, [od, po]); | b = nahodneCislo(seed + 13, [od, po]); | ||
return "rgb(".concat(r, ", ").concat(g, ", ").concat(b, ")"); | |||
} | |||
// ---------------------------------------------------------------- | |||
// ---------------------------------------------------------------- | |||
if (elementMapy !== null && poznamkyElement !== null) { | var poznamkyElement = document.getElementById("#mw-content-text .mw-parser-output"); | ||
var elementMapy = document.getElementById("mapa"); | |||
if (elementMapy !== null && poznamkyElement !== null) { | |||
var jsonMapy = vytvoritDataMapy(poznamkyElement); | |||
vykreslitMapu(elementMapy, jsonMapy); | vykreslitMapu(elementMapy, jsonMapy); | ||
} | } | ||
})(); | })(); |
Verzia z 19:24, 13. apríl 2024
(function () {
var tippyInstancia = tippy(document.createElement("div"));
/**
* Vytvorí JSON pojmovej mapy z obsahu stránky.
*
* @param {HTMLElement} poznamkyElement Element, ktorý obsahuje poznámky.
* @returns {object} JSON reprezentácia pojmovej mapy.
**/
function vytvoritDataMapy(poznamkyElement) {
var nadpisy = poznamkyElement.querySelectorAll("h1, h2, h3, h4, h5, h6");
var mapa = {
vrcholy: [],
hrany: []
};
// Zoznam, ktorý uchováva posledný nadpis na každej úrovni
var posledneNadpisy = [];
for (var i = 0; i < nadpisy.length; i++) {
var nadpis = nadpisy[i];
var aktualnyLevel = ziskatLevelNadpisu(nadpis);
var idVrchola = i + 1;
var nazov = nadpis.querySelector(".mw-headline").innerText.slice(2);
var idRodica = posledneNadpisy[aktualnyLevel - 1] || 1;
mapa.vrcholy.push({
id: idVrchola,
label: nazov,
color: generovatFarbu(idRodica * aktualnyLevel),
tooltip: obsahNadpisu(nadpis)
});
if (aktualnyLevel > 1) {
mapa.hrany.push({
from: idRodica,
to: idVrchola
});
}
// Aktualizujte posledný nadpis na úrovni
posledneNadpisy[aktualnyLevel] = idVrchola;
// Vymažte všetky nadpisy na vyšších úrovniach
for (var j = aktualnyLevel + 1; j < posledneNadpisy.length; j++) {
delete posledneNadpisy[j];
}
}
return mapa;
}
/**
* Získa obsah nadpisu a všetkých nasledujúcich elementov, ktoré nie sú nadpisy.
* Obsah je v HTML formáte.
*
* @param {HTMLElement} nadpisElement HTML element nadpisu.
* @returns {string} Obsah nadpisu a všetkých nasledujúcich elementov, ktoré nie sú nadpisy.
**/
function obsahNadpisu(nadpisElement) {
var obsah = "";
var element = nadpisElement.nextElementSibling;
while (element && !["H1", "H2", "H3", "H4", "H5", "H6"].includes(element.tagName)) {
obsah += element.outerHTML;
element = element.nextElementSibling;
}
return obsah;
}
/**
* Vygeneruje zobrazenie pojmovej mapy.
*
* @param {HTMLElement} elementMapy Element, do ktorého sa vloží zobrazenie pojmovej mapy.
* @param {object} jsonMapy JSON reprezentácia pojmovej mapy.
* @returns {object} Objekt pojmovej mapy (vis-network).
**/
function vykreslitMapu(elementMapy, jsonMapy) {
var sirkaZobrazenia = window.innerWidth;
var jeSirokeZobrazenie = sirkaZobrazenia > 768;
var dataSiete = {
nodes: new vis.DataSet(jsonMapy.vrcholy),
edges: new vis.DataSet(jsonMapy.hrany)
};
var nastavenia = {
interaction: {
hover: true,
keyboard: {
enabled: true,
bindToWindow: false,
autoFocus: false
}
},
nodes: {
shape: "box",
widthConstraint: {
maximum: 200
},
margin: 10,
labelHighlightBold: false
},
edges: {
smooth: {
type: "dynamic",
roundness: 0.5
},
width: 0.75,
arrows: {
to: {
enabled: true
}
}
},
layout: {
hierarchical: {
enabled: true,
direction: jeSirokeZobrazenie ? "UD" : "LR",
sortMethod: "directed",
nodeSpacing: jeSirokeZobrazenie ? 220 : 100,
levelSeparation: jeSirokeZobrazenie ? 100 : 250,
shakeTowards: "roots"
}
},
physics: false
};
pojmova_mapa = new vis.Network(elementMapy, dataSiete, nastavenia);
pojmova_mapa.on("hoverNode", function (parametre) {
var obsah = jsonMapy.vrcholy.find(function (vrchol) {
return vrchol.id === parametre.node;
}).tooltip;
if (!parametre.node || !obsah) return;
tippyInstancia.setProps({
triggerTarget: elementMapy,
maxWidth: "90vw",
allowHTML: true,
getReferenceClientRect: function getReferenceClientRect() {
return {
width: 0,
height: 0,
left: window.innerWidth / 2,
right: window.innerWidth / 2,
top: window.innerHeight - 10
};
},
interact: true
});
tippyInstancia.setContent("<div style=\"padding: 1rem 0.5rem; font-size: 12px;\">".concat(obsah, "</div>"));
tippyInstancia.show();
MathJax.typesetPromise([tippyInstancia.popper]);
});
pojmova_mapa.on("blurNode", function () {
tippyInstancia.hide();
});
return pojmova_mapa;
}
/**
* Získa úroveň nadpisu (h1, h2, atď.).
*
* @param {HTMLElement} nadpis HTML element nadpisu.
* @returns {number} Číselná reprezentácia úrovne nadpisu.
**/
function ziskatLevelNadpisu(nadpis) {
return parseInt(nadpis.tagName.substring(1), 10);
}
/**
* Generuje náhodné číslo z čísla (seed). Rovnaký seed vždy vygeneruje rovnaké "náhodné" číslo v určenom rozsahu.
*
* https://stackoverflow.com/a/63599906
*
* @param {number} seed Číslo, z ktorého sa generuje náhodné číslo.
* @param {number[]} rozsah Rozsah, v ktorom sa náhodné číslo generuje.
* @returns {number} Náhodné číslo.
**/
function nahodneCislo(seed) {
var rozsah = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0, 255];
seed = String(seed).split("").reduce(function (c, n) {
return n != 0 ? c * n : c * c;
});
var od = rozsah[0];
var po = rozsah[1];
while (seed < rozsah[0] || seed > rozsah[1]) {
if (seed > rozsah[1]) seed = Math.floor(seed / po--);
if (seed < rozsah[0]) seed = Math.floor(seed * od++);
}
return seed;
}
/**
* Generuje náhodnú farbu z čísla. Rovnaké číslo vždy vygeneruje rovnakú farbu.
*
* @param {number} cislo Číslo, z ktorého sa generuje farba.
* @returns {string} Farba v RBG formáte.
**/
function generovatFarbu() {
var seed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
var svetla = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var od = svetla ? 125 : 0;
var po = svetla ? 255 : 125;
r = nahodneCislo(seed + 11, [od, po]);
g = nahodneCislo(seed + 12, [od, po]);
b = nahodneCislo(seed + 13, [od, po]);
return "rgb(".concat(r, ", ").concat(g, ", ").concat(b, ")");
}
// ----------------------------------------------------------------
var poznamkyElement = document.getElementById("#mw-content-text .mw-parser-output");
var elementMapy = document.getElementById("mapa");
if (elementMapy !== null && poznamkyElement !== null) {
var jsonMapy = vytvoritDataMapy(poznamkyElement);
vykreslitMapu(elementMapy, jsonMapy);
}
})();