Skip to content
Snippets Groups Projects
Commit c80603f1 authored by Daniel García Solla's avatar Daniel García Solla
Browse files

Remove index.html

parent bc566c37
No related branches found
No related tags found
No related merge requests found
Pipeline #12890 failed
<!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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment