Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions 2023/day90/spider_web_map.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Spider Web Map (Radar) - DevOps Skills</title>
<link rel="preconnect" href="https://cdn.jsdelivr.net" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js" integrity="sha384-xjFAjVxq+myHkZrC5pv2J7YcuwZfZ2y0xE5Y6H3g0y5h4bS2lO3qGJ+M8k3Ptg7x" crossorigin="anonymous"></script>
<style>
:root {
color-scheme: light dark;
}
body {
font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
margin: 0;
padding: 24px;
line-height: 1.5;
}
.container {
max-width: 960px;
margin: 0 auto;
}
header {
margin-bottom: 16px;
}
.card {
background: canvas;
border: 1px solid rgba(127,127,127,.24);
border-radius: 12px;
padding: 16px;
box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.row {
display: flex;
gap: 16px;
flex-wrap: wrap;
align-items: center;
}
.row > * { flex: 1 1 280px; }
canvas { width: 100%; height: auto; }
.muted { opacity: .72; }
.controls { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
button, select, input[type="number"] {
padding: 8px 12px;
border-radius: 8px;
border: 1px solid rgba(127,127,127,.35);
background: canvas;
color: inherit;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 8px 12px;
margin-top: 8px;
}
label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
</style>
</head>
<body>
<div class="container">
<header>
<h1>Spider Web Map (Radar)</h1>
<p class="muted">A simple radar chart to visualize DevOps skill areas. Edit values and click Update.</p>
</header>

<div class="card">
<div class="row">
<div>
<div class="controls">
<button id="downloadPngBtn" type="button">Download PNG</button>
<label class="muted" style="flex:0 0 auto;">Scale max
<input id="scaleMaxInput" type="number" min="10" max="200" step="10" value="100" />
</label>
</div>
<canvas id="radarChart" width="720" height="480" aria-label="Spider web map radar chart" role="img"></canvas>
</div>
<div>
<div class="grid" id="inputsGrid"></div>
<div class="controls" style="margin-top:12px;">
<button id="updateBtn" type="button">Update</button>
<button id="resetBtn" type="button">Reset</button>
</div>
</div>
</div>
</div>

<p class="muted" style="margin-top:12px;">Tip: Adjust values (0–100 by default). Categories are editable in the code if you want to customize.</p>
</div>

<script>
const defaultLabels = [
"Linux",
"Git",
"CI/CD",
"Cloud",
"Docker",
"Kubernetes",
"Monitoring",
"Scripting",
"Security"
];

const defaultValues = [80, 75, 70, 85, 90, 65, 60, 80, 70];

const state = {
labels: [...defaultLabels],
values: [...defaultValues],
max: 100
};

const inputsGrid = document.getElementById("inputsGrid");
function renderInputs() {
inputsGrid.innerHTML = "";
state.labels.forEach((label, index) => {
const wrapper = document.createElement("label");
const title = document.createElement("span");
title.textContent = label;
const input = document.createElement("input");
input.type = "number";
input.min = "0";
input.max = String(state.max);
input.step = "1";
input.value = String(state.values[index]);
input.dataset.index = String(index);
input.addEventListener("input", (e) => {
const target = e.currentTarget;
const i = Number(target.dataset.index);
const val = Number(target.value);
state.values[i] = Number.isFinite(val) ? val : 0;
});
wrapper.appendChild(title);
wrapper.appendChild(input);
inputsGrid.appendChild(wrapper);
});
}

const ctx = document.getElementById("radarChart");
let radarChart;

function createChart() {
if (radarChart) radarChart.destroy();
radarChart = new Chart(ctx, {
type: "radar",
data: {
labels: state.labels,
datasets: [{
label: "Skill Level",
data: state.values,
fill: true,
backgroundColor: "rgba(59, 130, 246, 0.2)",
borderColor: "rgba(59, 130, 246, 1)",
pointBackgroundColor: "rgba(59, 130, 246, 1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(59, 130, 246, 1)"
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
r: {
beginAtZero: true,
suggestedMin: 0,
suggestedMax: state.max,
grid: { color: "rgba(127,127,127,.35)" },
angleLines: { color: "rgba(127,127,127,.35)" },
pointLabels: {
font: { size: 12 }
}
}
},
plugins: {
legend: { display: false },
tooltip: { enabled: true }
},
animation: { duration: 300 }
}
});
}

function updateScaleMaxFromInput() {
const maxInput = document.getElementById("scaleMaxInput");
const newMax = Number(maxInput.value);
if (Number.isFinite(newMax) && newMax > 0) {
state.max = newMax;
}
}

function downloadChartPng() {
const link = document.createElement("a");
link.download = "spider_web_map.png";
link.href = radarChart.toBase64Image();
link.click();
}

document.getElementById("updateBtn").addEventListener("click", () => {
updateScaleMaxFromInput();
renderInputs();
createChart();
});

document.getElementById("resetBtn").addEventListener("click", () => {
state.labels = [...defaultLabels];
state.values = [...defaultValues];
state.max = 100;
document.getElementById("scaleMaxInput").value = String(state.max);
renderInputs();
createChart();
});

document.getElementById("downloadPngBtn").addEventListener("click", downloadChartPng);

renderInputs();
createChart();
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ https://bit.ly/devops-batch-2
<a href = "https://github.com/LondheShubham153/90DaysOfDevOps/graphs/contributors">
<img src = "https://contrib.rocks/image?repo=LondheShubham153/90DaysOfDevOps"/>
</a>

---

Quick Demo: Spider Web (Radar) Map
- Open `2023/day90/spider_web_map.html` in your browser to view and edit the interactive chart.