Last active
July 31, 2025 10:00
-
-
Save FrankSpierings/1c0e46ad37dc9f81897c0e2df054880e to your computer and use it in GitHub Desktop.
Some JS line chart example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>The Love Graph</title> | |
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
<style> | |
/* Optional: Basic styling for the canvas container */ | |
body { | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
min-height: 100vh; | |
margin: 0; | |
background-color: #f0f0f0; | |
} | |
div { | |
width: 600px; /* Adjust canvas width */ | |
height: 600px; /* Adjust canvas height */ | |
background-color: white; | |
padding: 20px; | |
border-radius: 8px; | |
box-shadow: 0 4px 8px rgba(0,0,0,0.1); | |
} | |
</style> | |
</head> | |
<body> | |
<div> | |
<canvas id="myChart"></canvas> | |
</div> | |
<script> | |
const ctx = document.getElementById('myChart'); | |
const range = [-2.5, 2.5]; // Defines the x-axis range for plotting | |
const size = 4000; // Number of data points for smoother curves | |
// Generate x-values evenly distributed within the defined range | |
const x = Array.from({ length: size }, (_, i) => range[0] + i * ((range[1] - range[0]) / (size - 1))); | |
// Calculate y-values for the upper half of the heart using the formula: y = sqrt(abs(x)) + sqrt(1 - x^2) | |
const y_upper = x.map(val => { | |
// Ensure 1 - val*val is not negative to avoid NaN from Math.sqrt() | |
if (1 - val * val >= 0) { | |
return Math.sqrt(Math.abs(val)) + Math.sqrt(1 - val * val); | |
} | |
return NaN; // Return NaN for values outside the valid domain (e.g., |x| > 1 for sqrt(1-x^2)) | |
}); | |
// Calculate y-values for the lower half of the heart using the formula: y = sqrt(abs(x)) - sqrt(1 - x^2) | |
const y_lower = x.map(val => { | |
// Ensure 1 - val*val is not negative | |
if (1 - val * val >= 0) { | |
return Math.sqrt(Math.abs(val)) - Math.sqrt(1 - val * val); | |
} | |
return NaN; // Return NaN for values outside the valid domain | |
}); | |
const data = { | |
labels: x, // x-values will be used for labels (though hidden) | |
datasets: [{ | |
label: 'Upper Half of Heart', // Label for dataset, hidden by legend: false | |
data: y_upper, | |
borderColor: 'red', | |
backgroundColor: 'rgba(255, 99, 132, 0.2)', // Light red fill (though fill: false) | |
fill: false, // Do not fill the area under the line | |
tension: 0 // Set tension to 0 for straight lines between points, ensuring sharp corners and connections | |
}, | |
{ | |
label: 'Lower Half of Heart', // Label for dataset, hidden by legend: false | |
data: y_lower, | |
borderColor: 'red', | |
backgroundColor: 'rgba(255, 99, 132, 0.2)', | |
fill: false, | |
tension: 0 // Set tension to 0 | |
}] | |
}; | |
const config = { | |
type: 'line', | |
data: data, | |
options: { | |
responsive: true, // Chart will resize with its container | |
maintainAspectRatio: false, // Allow independent height/width control | |
scales: { | |
x: { | |
title: { | |
display: true, | |
text: 'x values' | |
}, | |
min: range[0], | |
max: range[1], | |
ticks: { | |
display: false // Hide x-axis labels (numbers) | |
}, | |
grid: { | |
drawOnChartArea: false // Hide vertical grid lines (those parallel to y-axis) | |
} | |
}, | |
y: { | |
title: { | |
display: true, | |
text: 'y values (Heart Shape)' | |
}, | |
min: range[0], // Keep min same as x-axis min for symmetric view | |
max: range[1] + 1, // Set y-axis max to ensure top of heart is visible | |
} | |
}, | |
plugins: { | |
title: { | |
display: true, | |
text: 'The Love Graph (Heart Shape)', | |
font: { | |
size: 18 // Adjust title font size | |
} | |
}, | |
legend: { | |
display: false // Hide the legend entirely | |
}, | |
tooltip: { // Enable and configure tooltips | |
enabled: true, | |
callbacks: { | |
label: function(context) { | |
let label = context.dataset.label || ''; | |
if (label) { | |
label += ': '; | |
} | |
// Format x and y values to 3 decimal places | |
if (context.parsed.x !== null && context.parsed.y !== null) { | |
label += `(${context.parsed.x.toFixed(3)}, ${context.parsed.y.toFixed(3)})`; | |
} | |
return label; | |
} | |
} | |
} | |
} | |
} | |
}; | |
new Chart(ctx, config); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment