ewdlop's picture
Update index.html (#1)
4eaffc4 verified
raw
history blame
19.1 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Decimal Rounding Graph</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
.header {
background: linear-gradient(45deg, #4CAF50, #45a049);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
.header p {
font-size: 1.1em;
opacity: 0.9;
}
.controls {
padding: 30px;
background: #f8f9fa;
border-bottom: 1px solid #e9ecef;
}
.input-group {
display: flex;
gap: 20px;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
.input-container {
display: flex;
flex-direction: column;
gap: 5px;
}
label {
font-weight: 600;
color: #333;
font-size: 14px;
}
input[type="number"] {
padding: 12px 15px;
border: 2px solid #ddd;
border-radius: 8px;
font-size: 16px;
width: 200px;
transition: border-color 0.3s ease;
}
input[type="number"]:focus {
outline: none;
border-color: #4CAF50;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1);
}
.btn {
background: linear-gradient(45deg, #4CAF50, #45a049);
color: white;
border: none;
padding: 12px 30px;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 20px;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);
}
.content {
display: flex;
gap: 30px;
padding: 30px;
}
.graph-container {
flex: 2;
background: white;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
padding: 20px;
min-height: 400px;
}
.data-table {
flex: 1;
background: white;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
padding: 20px;
max-height: 500px;
overflow-y: auto;
}
.graph-title {
text-align: center;
color: #333;
margin-bottom: 20px;
font-size: 1.3em;
font-weight: 600;
}
.graph-svg {
width: 100%;
height: 350px;
border: 1px solid #e9ecef;
border-radius: 8px;
}
.table-title {
text-align: center;
color: #333;
margin-bottom: 15px;
font-size: 1.2em;
font-weight: 600;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #e9ecef;
}
th {
background: #f8f9fa;
font-weight: 600;
color: #333;
}
tr:hover {
background: #f8f9fa;
}
.original-value {
background: #e8f5e8;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
text-align: center;
font-size: 1.1em;
font-weight: 600;
color: #2e7d32;
}
.error {
color: #d32f2f;
text-align: center;
padding: 20px;
font-size: 1.1em;
}
@media (max-width: 768px) {
.content {
flex-direction: column;
}
.input-group {
flex-direction: column;
align-items: stretch;
}
input[type="number"] {
width: 100%;
}
}
.axis-line {
stroke: #333;
stroke-width: 2;
}
.grid-line {
stroke: #e0e0e0;
stroke-width: 1;
}
.data-point {
fill: #4CAF50;
stroke: #2e7d32;
stroke-width: 2;
}
.data-line {
fill: none;
stroke: #4CAF50;
stroke-width: 3;
}
.axis-label {
font-family: Arial, sans-serif;
font-size: 12px;
fill: #333;
}
.axis-title {
font-family: Arial, sans-serif;
font-size: 14px;
font-weight: bold;
fill: #333;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Decimal Rounding Visualizer</h1>
<p>Enter a number and see how rounding to different decimal places affects its value</p>
</div>
<div class="controls">
<div class="input-group">
<div class="input-container">
<label for="numberInput">Enter Number:</label>
<input type="number" id="numberInput" step="any" placeholder="e.g., 3.14159265" value="3.14159265">
</div>
<div class="input-container">
<label for="maxDigits">Maximum Decimal Places:</label>
<input type="number" id="maxDigits" min="1" max="15" value="8" placeholder="e.g., 8">
</div>
<button class="btn" onclick="generateGraph()">Generate Graph</button>
</div>
</div>
<div class="content">
<div class="graph-container">
<div class="graph-title">Rounding Visualization</div>
<div id="originalValue" class="original-value"></div>
<svg class="graph-svg" id="graphSvg"></svg>
</div>
<div class="data-table">
<div class="table-title">Rounded Values</div>
<div id="tableContainer"></div>
</div>
</div>
</div>
<script>
function generateGraph() {
const numberInput = document.getElementById('numberInput').value;
const maxDigits = parseInt(document.getElementById('maxDigits').value);
if (!numberInput || isNaN(parseFloat(numberInput))) {
showError('Please enter a valid number');
return;
}
if (!maxDigits || maxDigits < 1 || maxDigits > 15) {
showError('Please enter a valid number of decimal places (1-15)');
return;
}
const originalNumber = parseFloat(numberInput);
// Show original value
document.getElementById('originalValue').innerHTML =
`Original Value: <strong>${originalNumber}</strong>`;
// Generate rounded values
const data = [];
for (let i = 0; i <= maxDigits; i++) {
const rounded = parseFloat(originalNumber.toFixed(i));
data.push({
digits: i,
value: rounded,
difference: Math.abs(originalNumber - rounded)
});
}
// Create graph
createGraph(data, originalNumber);
// Create table
createTable(data);
}
function createGraph(data, originalValue) {
const svg = document.getElementById('graphSvg');
const width = svg.clientWidth;
const height = 350;
// Clear previous graph
svg.innerHTML = '';
// Set SVG dimensions
svg.setAttribute('viewBox', `0 0 ${width} ${height}`);
// Margins
const margin = { top: 20, right: 40, bottom: 60, left: 60 };
const graphWidth = width - margin.left - margin.right;
const graphHeight = height - margin.top - margin.bottom;
// Find min and max values for Y-axis
const values = data.map(d => d.value);
const minValue = Math.min(...values);
const maxValue = Math.max(...values);
const valueRange = maxValue - minValue;
const yPadding = valueRange * 0.1 || 0.1; // Add 10% padding or minimum 0.1
const yMin = minValue - yPadding;
const yMax = maxValue + yPadding;
// Scale functions
const xScale = (digits) => margin.left + (digits / data.length) * graphWidth;
const yScale = (value) => margin.top + ((yMax - value) / (yMax - yMin)) * graphHeight;
// Create grid lines
const gridLines = 8;
for (let i = 0; i <= gridLines; i++) {
const y = margin.top + (i / gridLines) * graphHeight;
const gridValue = yMax - (i / gridLines) * (yMax - yMin);
// Horizontal grid line
const gridLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
gridLine.setAttribute('x1', margin.left);
gridLine.setAttribute('y1', y);
gridLine.setAttribute('x2', margin.left + graphWidth);
gridLine.setAttribute('y2', y);
gridLine.setAttribute('class', 'grid-line');
svg.appendChild(gridLine);
// Y-axis label
const label = document.createElementNS('http://www.w3.org/2000/svg', 'text');
label.setAttribute('x', margin.left - 10);
label.setAttribute('y', y + 4);
label.setAttribute('text-anchor', 'end');
label.setAttribute('class', 'axis-label');
label.textContent = gridValue.toFixed(6);
svg.appendChild(label);
}
// X-axis
const xAxis = document.createElementNS('http://www.w3.org/2000/svg', 'line');
xAxis.setAttribute('x1', margin.left);
xAxis.setAttribute('y1', margin.top + graphHeight);
xAxis.setAttribute('x2', margin.left + graphWidth);
xAxis.setAttribute('y2', margin.top + graphHeight);
xAxis.setAttribute('class', 'axis-line');
svg.appendChild(xAxis);
// Y-axis
const yAxis = document.createElementNS('http://www.w3.org/2000/svg', 'line');
yAxis.setAttribute('x1', margin.left);
yAxis.setAttribute('y1', margin.top);
yAxis.setAttribute('x2', margin.left);
yAxis.setAttribute('y2', margin.top + graphHeight);
yAxis.setAttribute('class', 'axis-line');
svg.appendChild(yAxis);
// X-axis labels
data.forEach((d, i) => {
const x = margin.left + (i / (data.length - 1)) * graphWidth;
// X-axis tick
const tick = document.createElementNS('http://www.w3.org/2000/svg', 'line');
tick.setAttribute('x1', x);
tick.setAttribute('y1', margin.top + graphHeight);
tick.setAttribute('x2', x);
tick.setAttribute('y2', margin.top + graphHeight + 5);
tick.setAttribute('class', 'axis-line');
svg.appendChild(tick);
// X-axis label
const label = document.createElementNS('http://www.w3.org/2000/svg', 'text');
label.setAttribute('x', x);
label.setAttribute('y', margin.top + graphHeight + 20);
label.setAttribute('text-anchor', 'middle');
label.setAttribute('class', 'axis-label');
label.textContent = d.digits;
svg.appendChild(label);
});
// Create line path
let pathData = '';
data.forEach((d, i) => {
const x = margin.left + (i / (data.length - 1)) * graphWidth;
const y = yScale(d.value);
if (i === 0) {
pathData += `M ${x} ${y}`;
} else {
pathData += ` L ${x} ${y}`;
}
});
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', pathData);
path.setAttribute('class', 'data-line');
svg.appendChild(path);
// Create data points
data.forEach((d, i) => {
const x = margin.left + (i / (data.length - 1)) * graphWidth;
const y = yScale(d.value);
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
circle.setAttribute('cx', x);
circle.setAttribute('cy', y);
circle.setAttribute('r', 4);
circle.setAttribute('class', 'data-point');
// Add hover effect
circle.addEventListener('mouseenter', (e) => {
e.target.setAttribute('r', 6);
// Create tooltip
const tooltip = document.createElementNS('http://www.w3.org/2000/svg', 'g');
tooltip.setAttribute('id', 'tooltip');
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('x', x - 40);
rect.setAttribute('y', y - 35);
rect.setAttribute('width', 80);
rect.setAttribute('height', 25);
rect.setAttribute('fill', '#333');
rect.setAttribute('rx', 4);
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
text.setAttribute('x', x);
text.setAttribute('y', y - 18);
text.setAttribute('text-anchor', 'middle');
text.setAttribute('fill', 'white');
text.setAttribute('font-size', '12');
text.textContent = d.value.toString();
tooltip.appendChild(rect);
tooltip.appendChild(text);
svg.appendChild(tooltip);
});
circle.addEventListener('mouseleave', (e) => {
e.target.setAttribute('r', 4);
const tooltip = document.getElementById('tooltip');
if (tooltip) {
tooltip.remove();
}
});
svg.appendChild(circle);
});
// Add axis titles
const xTitle = document.createElementNS('http://www.w3.org/2000/svg', 'text');
xTitle.setAttribute('x', margin.left + graphWidth / 2);
xTitle.setAttribute('y', height - 10);
xTitle.setAttribute('text-anchor', 'middle');
xTitle.setAttribute('class', 'axis-title');
xTitle.textContent = 'Decimal Places';
svg.appendChild(xTitle);
const yTitle = document.createElementNS('http://www.w3.org/2000/svg', 'text');
yTitle.setAttribute('x', 15);
yTitle.setAttribute('y', margin.top + graphHeight / 2);
yTitle.setAttribute('text-anchor', 'middle');
yTitle.setAttribute('class', 'axis-title');
yTitle.setAttribute('transform', `rotate(-90, 15, ${margin.top + graphHeight / 2})`);
yTitle.textContent = 'Rounded Value';
svg.appendChild(yTitle);
// Add original value line
const originalY = yScale(originalValue);
const originalLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
originalLine.setAttribute('x1', margin.left);
originalLine.setAttribute('y1', originalY);
originalLine.setAttribute('x2', margin.left + graphWidth);
originalLine.setAttribute('y2', originalY);
originalLine.setAttribute('stroke', '#ff5722');
originalLine.setAttribute('stroke-width', 2);
originalLine.setAttribute('stroke-dasharray', '5,5');
svg.appendChild(originalLine);
}
function createTable(data) {
const container = document.getElementById('tableContainer');
let html = `
<table>
<thead>
<tr>
<th>Decimal Places</th>
<th>Rounded Value</th>
<th>Difference</th>
</tr>
</thead>
<tbody>
`;
data.forEach(d => {
html += `
<tr>
<td>${d.digits}</td>
<td>${d.value}</td>
<td>${d.difference.toExponential(3)}</td>
</tr>
`;
});
html += `
</tbody>
</table>
`;
container.innerHTML = html;
}
function showError(message) {
document.getElementById('originalValue').innerHTML = '';
document.getElementById('graphSvg').innerHTML = `
<text x="50%" y="50%" text-anchor="middle" class="error">${message}</text>
`;
document.getElementById('tableContainer').innerHTML = `
<div class="error">${message}</div>
`;
}
// Generate initial graph
generateGraph();
</script>
</body>
</html>