diff --git a/index.html b/index.html deleted file mode 100644 index 52a386532143f2359126f49b1ed09b805791e65d..0000000000000000000000000000000000000000 --- a/index.html +++ /dev/null @@ -1,427 +0,0 @@ -<!DOCTYPE html> -<html lang="es"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Proyecto Visualización</title> - <script src="https://d3js.org/d3.v7.min.js"></script> - <style> - body { - font-family: Arial, sans-serif; - justify-content: center; - align-items: center; - height: 100%; - margin: 0; - background-color: #fff; - } - - .div-histograma { - border: 0em solid #222222; - width: 40em; - height: 20em; - text-align: center; - margin: 1em; - padding: 2em; - color: #f9f9f9; - font-weight: bold; - border-radius: 0em; - box-shadow: 0 1em 3em rgba(22, 22, 22, 0.6); - transition: transform 0.3s; - } - - .div-histograma:hover { - transform: scale(1.05); - } - - #div1 { - background-color: #fff; - } - - #div2 { - background-color: #fff; - } - - #dropdownDiv { - display: flex; - flex-direction: column; - align-items: flex-start; - margin: 1em; - padding: 1em; - border: 0em solid #222222; - border-radius: 0em; - box-shadow: 0 1em 3em rgba(22, 22, 22, 0.6); - background-color: #f9f9f9; - transition: transform 0.3s; - } - - #keyDropdown { - margin-top: 0.5em; - padding: 0.5em; - border-radius: 0em; - border: 0em solid #ccc; - font-size: 1em; - transition: transform 0.3s; - } - - #opcinesDiv1 { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - margin: 1em; - padding: 0em; - } - - #sliderAnimationContainer, - #sliderBarrasContainer, - #checkboxContainer, - #distributionCheckboxContainer { - width: max-content; - height: fit-content; - display: block; - margin: 1em 1em 1em 1em; - padding: 1em; - border: 0em solid #222222; - border-radius: 0em; - box-shadow: 0 1em 3em rgba(22, 22, 22, 0.6); - background-color: #f9f9f9; - transition: transform 0.3s; - } - - #dropdownDiv:hover, - #keyDropdown:hover, - #checkboxContainer:hover, - #sliderAnimationContainer:hover, - #sliderBarrasContainer:hover, - #distributionCheckboxContainer:hover { - transform: scale(1.05); - } - - label { - font-weight: bold; - margin-bottom: 0.5em; - } - </style> -</head> - -<body> - <div style="text-align: center"> - <h1 style="color: #222222; font-size: 2em; font-weight: bold;">Resultados de simulaciones de un proceso - estocástico</h1> - <p style="color: #555555; font-size: 1em;">Visualización de las distribuciones que determinan la duración y - estado del sistema al finalizar el proceso</p> - </div> - <div style="display:flex; justify-content: center; align-items: center;margin:5em;"> - <div id="histogramas" style="display:flex"> - <div id="div1" class="div-histograma"></div> - <div id="div2" class="div-histograma"></div> - </div> - <div id="dropdownDiv"> - <label for="keyDropdown">Tamaño<br>sistema:</label> - <select id="keyDropdown" onchange="onDropdownChange(this)"></select> - </div> - </div> - <div id="opcinesDiv1"> - <div id="checkboxContainer"> - <label for="mediaCheckbox">Mostrar media:</label> - <input type="checkbox" id="mediaCheckbox" onchange="onCheckboxMediaChange()"> - </div> - <div id="distributionCheckboxContainer"> - <label for="distributionCheckbox">Mostrar distribución:</label> - <input type="checkbox" id="distributionCheckbox" onchange="onCheckboxDistributionChange()"> - </div> - <div id="sliderAnimationContainer"> - <label for="animationSlider">Tiempo animación:</label> - <input type="range" id="animationSlider" min="0" max="2000" step="100" value="600" - oninput="onSliderChange()" onchange="onSliderChange()"> - <span id="animationTimeValue">1000 ms</span> - </div> - - <div id="sliderBarrasContainer"> - <label for="barsSlider">Barras:</label> - <input type="range" id="barsSlider" min="5" max="100" step="1" value="20" oninput="onBarsSliderChange()" - onchange="onBarsSliderChange()"> - <span id="barsCountValue">10</span> - </div> - </div> - - <script type="text/javascript"> - const datasetFolder = "./dataset/" - const fileNamesList = ['10 1', '10 10', '10 11', '10 12', '10 13', '10 14', '10 15', '10 2', '10 3', '10 4', '10 5', '10 6', '10 7', '10 8', '10 9', '11 1', '11 10', '11 11', '11 12', '11 13', '11 14', '11 15', '11 2', '11 3', '11 4', '11 5', '11 6', '11 7', '11 8', '11 9', '12 1', '12 12', '12 2', '12 3', '12 4', '12 5', '12 6', '13 1', '13 10', '13 11', '13 12', '13 13', '13 14', '13 15', '13 2', '13 3', '13 4', '13 5', '13 6', '13 7', '13 8', '13 9', '14 1', '14 10', '14 11', '14 12', '14 13', '14 14', '14 15', '14 2', '14 3', '14 4', '14 5', '14 6', '14 7', '14 8', '14 9', '15 1', '15 10', '15 11', '15 12', '15 13', '15 14', '15 15', '15 2', '15 3', '15 4', '15 5', '15 6', '15 7', '15 8', '15 9', '16 1', '16 10', '16 11', '16 12', '16 13', '16 14', '16 15', '16 16', '16 2', '16 3', '16 4', '16 5', '16 6', '16 7', '16 8', '16 9', '17 1', '17 10', '17 11', '17 12', '17 13', '17 14', '17 15', '17 16', '17 17', '17 2', '17 3', '17 4', '17 5', '17 6', '17 7', '17 8', '17 9', '18 1', '18 18', '18 2', '18 3', '18 4', '18 5', '18 6', '18 7', '19 1', '19 19', '20 1', '20 20', '21 1', '21 21', '22 1', '22 22', '23 1', '23 23', '24 1', '24 24', '25 1', '25 25', '26 1', '26 26', '27 1', '27 27', '28 1', '28 28', '29 1', '29 29', '3 1', '3 3', '30 1', '30 30', '31 1', '31 31', '32 1', '32 32', '33 1', '33 33', '34 1', '34 34', '35 1', '35 35', '36 1', '36 36', '37 1', '37 37', '38 1', '38 38', '39 1', '39 39', '4 1', '4 4', '40 1', '40 40', '41 1', '41 41', '42 1', '42 42', '43 1', '43 43', '44 1', '44 44', '45 1', '45 45', '46 1', '46 46', '47 1', '47 47', '48 1', '48 48', '49 1', '5 1', '5 10', '5 11', '5 12', '5 13', '5 14', '5 15', '5 2', '5 3', '5 4', '5 5', '5 6', '5 7', '5 8', '5 9', '6 1', '6 10', '6 11', '6 12', '6 13', '6 14', '6 15', '6 2', '6 3', '6 4', '6 5', '6 6', '6 7', '6 8', '6 9', '7 1', '7 10', '7 11', '7 12', '7 13', '7 14', '7 15', '7 2', '7 3', '7 4', '7 5', '7 6', '7 7', '7 8', '7 9', '8 1', '8 10', '8 11', '8 12', '8 13', '8 14', '8 15', '8 2', '8 3', '8 4', '8 5', '8 6', '8 7', '8 8', '8 9', '9 1', '9 10', '9 11', '9 12', '9 13', '9 14', '9 15', '9 2', '9 3', '9 4', '9 5', '9 6', '9 7', '9 8', '9 9']; - fileNamesList.sort((a, b) => a.split(" ")[0] - b.split(" ")[0] || a.split(" ")[1] - b.split(" ")[1]); - const dropdown = document.getElementById("keyDropdown"); - const mediaCheckbox = document.getElementById("mediaCheckbox"); - const distributionCheckbox = document.getElementById("distributionCheckbox"); - const animationSlider = document.getElementById("animationSlider"); - const animationTimeValue = document.getElementById("animationTimeValue"); - const barsSlider = document.getElementById("barsSlider"); - const barsCountValue = document.getElementById("barsCountValue"); - - var key = fileNamesList[107]; - var animationTime = 600; - var bins = 10; - var currentData = null; - var currentKey = null; - - async function getData(key) { - try { - const response = await fetch(datasetFolder + key + ".json"); - if (!response.ok) { - throw new Error("Error: " + response.status); - } - const data = await response.json(); - return data[key]; - } catch (error) { - console.error('Error:', error); - alert(error); - } - } - - async function start() { - if (currentKey !== key) { - currentData = await getData(key); - currentKey = key; - } - histograma(currentData[0], "div1", bins, "Iteraciones"); - histograma(currentData[1], "div2", bins, "Cantidad elementos"); - } - - function histograma(data, div, binNumber, label) { - const container = document.getElementById(div); - const width = container.clientWidth; - const height = container.clientHeight; - const heightFactor = 1.1; - const axisXOffset = 100; - const axisYOffset = 40; - - const bins = d3.bin() - .thresholds(binNumber) - .value((d) => d)(data); - - const x = d3.scaleLinear() - .domain([bins[0].x0, bins[bins.length - 1].x1]) - .range([axisXOffset, width - axisXOffset]); - - const yMax = d3.max(bins, d => d.length) * heightFactor; - - const y = d3.scaleLinear() - .domain([0, yMax]) - .range([height - axisYOffset, 0]); - - let svg = d3.select("#" + div).select("svg"); - if (svg.empty()) { - svg = d3.select("#" + div) - .append("svg") - .attr("width", width) - .attr("height", height) - .attr("viewBox", [0, 0, width, height]) - .attr("style", "max-width: 100%; height: auto;"); - } - - //Construir las barras - const bars = svg.selectAll("rect") - .data(bins, d => d.x0); - - bars.exit() - .transition() - .duration(0) - .ease(d3.easeCubicInOut) - .attr("y", height - axisYOffset) - .attr("height", 0) - .remove(); - - bars.transition() - .duration(animationTime) - .ease(d3.easeElasticOut.amplitude(2).period(1.5)) - .attr("x", (d) => x(d.x0) + 1) - .attr("width", (d) => Math.max(0, x(d.x1) - x(d.x0) - 3)) - .attr("y", (d) => y(d.length)) - .attr("height", (d) => y(0) - y(d.length)) - .attr("fill", "#055902"); - - bars.enter() - .append("rect") - .attr("x", (d) => x(d.x0) + 1) - .attr("width", (d) => Math.max(0, x(d.x1) - x(d.x0) - 3)) - .attr("y", height - axisYOffset) - .attr("height", 0) - .attr("fill", "#ff7f0e") - .transition() - .delay((d, i) => i * (animationTime / 10)) - .duration(animationTime) - .ease(d3.easeCubicInOut) - .attr("y", (d) => y(d.length)) - .attr("height", (d) => y(0) - y(d.length)) - .attr("fill", "#055902"); - - //Ejes x e y - svg.selectAll(".x-axis").remove(); - svg.append("g") - .attr("class", "x-axis") - .attr("transform", "translate(0," + (height - axisYOffset) + ")") - .call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0)) - .call((g) => g.selectAll("path, line").style("stroke", "#222222")) - .call((g) => g.selectAll("text").style("fill", "#222222")).style("font-size", "0.8em") - .call((g) => g.append("text") - .attr("x", width / 2) - .attr("y", 35) - .attr("fill", "#222222") - .attr("text-anchor", "middle") - .text(label)); - - svg.selectAll(".y-axis").remove(); - svg.append("g") - .attr("class", "y-axis") - .attr("transform", "translate(" + axisXOffset + ",0)") - .call(d3.axisLeft(y).ticks(height / 70)) - .call((g) => g.select(".domain").remove()) - .call((g) => g.selectAll("path, line").style("stroke", "#222222")) - .call((g) => g.selectAll("text").style("fill", "#222222")).style("font-size", "0.8em") - .call((g) => g.append("text") - .attr("x", -height / 2) - .attr("y", -70) - .attr("fill", "#222222") - .attr("text-anchor", "middle") - .attr("transform", "rotate(-90)") - .text("Simulaciones")); - - // Mostrar lÃnea de la media - svg.selectAll(".media") - .attr("y1", 0) - .transition() - .duration(animationTime) - .ease(d3.easeCubicInOut) - .style("opacity", 0) - .attr("y1", height - axisYOffset) - .remove(); - if (mediaCheckbox.checked) { - const average = d3.mean(data); - - svg.append("line") - .attr("class", "media") - .attr("x1", x(average)) - .attr("x2", x(average)) - .attr("y1", height - axisYOffset) - .attr("y2", height - axisYOffset) - .attr("stroke", "#1e90ff") - .attr("stroke-width", 4) - .transition() - .duration(animationTime) - .ease(d3.easeCubicInOut) - .attr("y1", 0); - - svg.append("text") - .attr("class", "media") - .attr("x", x(average) + 5) - .attr("y", 15) - .attr("fill", "#333333") - .style("font-size", "1em") - .style("font-weight", "bold") - .text("Media: " + average.toFixed(2)) - .style("opacity", 0) - .transition() - .duration(animationTime) - .ease(d3.easeCubicInOut) - .style("opacity", 1); - } - - // Mostrar curva de distribución - svg.selectAll(".distribution") - .transition() - .duration(animationTime) - .ease(d3.easeCubicInOut) - .attr("stroke-dashoffset", function () { return this.getTotalLength(); }) - .remove(); - if (distributionCheckbox.checked) { - const density = kde(epanechnikov(10), x.ticks(40), data.filter((_, index) => index % 30 === 0)); - - const yDist = d3.scaleLinear() - .domain([0, d3.max(density, d => d[1]) * heightFactor]) - .range([height - axisYOffset, 0]); - - const line = d3.line() - .curve(d3.curveBasis) - .x(d => x(d[0])) - .y(d => yDist(d[1])); - - svg.append("path") - .datum(density) - .attr("class", "distribution") - .attr("fill", "none") - .attr("stroke", "#222222") - .attr("stroke-width", 2) - .attr("stroke-linejoin", "round") - .attr("stroke-linecap", "round") - .attr("d", line) - .attr("stroke-dasharray", function () { return this.getTotalLength(); }) - .attr("stroke-dashoffset", function () { return this.getTotalLength(); }) - .transition() - .duration(animationTime) - .ease(d3.easeCubicInOut) - .attr("stroke-dashoffset", 0); - } - } - - //Funciones que se ejecutan al ocurrir eventos - function onDropdownChange() { - key = dropdown.value; - start(); - } - - function onCheckboxMediaChange() { - start(); - } - - function onCheckboxDistributionChange() { - start(); - } - - function onSliderChange() { - updateAnimationTime(parseInt(animationSlider.value)); - } - - function onBarsSliderChange() { - updateBarsCount(parseInt(barsSlider.value)); - start(); - } - - function updateAnimationTime(newAnimationTime) { - animationTime = newAnimationTime; - animationTimeValue.textContent = animationTime + " ms"; - } - - function updateBarsCount(newBins) { - bins = newBins; - barsCountValue.textContent = bins; - } - - //Funciones para calcular la distribución de probabilidad - function kde(kernel, thresholds, data) { - return thresholds.map(t => [t, d3.mean(data, d => kernel(t - d))]); - } - - function epanechnikov(bandwidth) { - return x => Math.abs(x /= bandwidth) <= 1 ? 0.75 * (1 - x * x) / bandwidth : 0; - } - - //Inicializar documento - fileNamesList.forEach((fileName) => { - const option = document.createElement("option"); - option.value = fileName; - option.textContent = fileName; - dropdown.appendChild(option); - }); - - dropdown.value = key; - mediaCheckbox.checked = true; - distributionCheckbox.checked = false; - animationSlider.value = 600; - updateAnimationTime(600); - updateBarsCount(20); - barsSlider.value = 10; - start(); - </script> -</body> - -</html> \ No newline at end of file