Cryptocurrency Market Heatmap JavaScript, API
👤 Sharing: AI
```javascript
<!DOCTYPE html>
<html>
<head>
<title>Cryptocurrency Market Heatmap</title>
<style>
/* Basic styling for the heatmap */
#heatmap {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); /* Responsive columns */
gap: 5px;
margin: 20px;
}
.coin-tile {
padding: 10px;
text-align: center;
border: 1px solid #ccc;
border-radius: 5px;
cursor: pointer; /* Indicate clickability */
}
.coin-tile:hover {
background-color: #f0f0f0;
}
/* Color scaling based on price change (example) */
.positive {
background-color: #d4edda; /* Light green */
color: #155724; /* Dark green */
}
.negative {
background-color: #f8d7da; /* Light red */
color: #721c24; /* Dark red */
}
.neutral {
background-color: #fff3cd; /* Light yellow */
color: #856404; /* Dark yellow */
}
/* Optional: Tooltip styling (for showing more details on hover) */
.tooltip {
position: relative;
display: inline-block;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 200px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -100px; /* Center the tooltip */
opacity: 0;
transition: opacity 0.3s;
}
.tooltip .tooltiptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: black transparent transparent transparent;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
</style>
</head>
<body>
<h1>Cryptocurrency Market Heatmap</h1>
<div id="heatmap">
<!-- Cryptocurrency tiles will be dynamically added here -->
</div>
<script>
// API Endpoint (using CoinGecko as an example)
const API_URL = 'https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false'; // Fetch top 100 coins
async function fetchCryptoData() {
try {
const response = await fetch(API_URL);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error fetching crypto data:', error);
// Display an error message on the page (e.g., in the heatmap div)
document.getElementById('heatmap').innerHTML = `<p style="color: red;">Error loading data. Please check the console.</p>`;
return null; // Return null to indicate failure
}
}
function createHeatmap(cryptoData) {
const heatmapDiv = document.getElementById('heatmap');
if (!cryptoData) {
// If cryptoData is null (due to an error), do not proceed. The error message is already displayed.
return;
}
cryptoData.forEach(coin => {
const coinTile = document.createElement('div');
coinTile.classList.add('coin-tile');
//Determine the price change percentage. Check if 24h percentage change exists.
const priceChangePercentage24h = coin.price_change_percentage_24h;
let priceChangeClass = 'neutral';
if (priceChangePercentage24h > 0) {
priceChangeClass = 'positive';
} else if (priceChangePercentage24h < 0) {
priceChangeClass = 'negative';
}
coinTile.classList.add(priceChangeClass);
// Add coin name and symbol
coinTile.innerHTML = `
<div class="tooltip">
<strong>${coin.name} (${coin.symbol.toUpperCase()})</strong>
<span class="tooltiptext">
Price: $${coin.current_price.toFixed(2)}<br>
24h Change: ${priceChangePercentage24h ? priceChangePercentage24h.toFixed(2) + '%' : 'N/A'}<br>
Market Cap: $${(coin.market_cap / 1000000000).toFixed(2)}B
</span>
</div>
`;
//Optional: Add click event to redirect to a coin details page (example)
coinTile.addEventListener('click', () => {
// In a real application, you would redirect to a page showing details for this coin.
// For this example, just show an alert.
alert(`Clicked on ${coin.name}! (This would normally go to a details page)`);
});
heatmapDiv.appendChild(coinTile);
});
}
// Main function to fetch data and create the heatmap
async function main() {
const cryptoData = await fetchCryptoData();
if (cryptoData) { // Only create the heatmap if data was successfully fetched
createHeatmap(cryptoData);
}
}
// Call the main function when the page loads
window.onload = main;
</script>
</body>
</html>
```
Key improvements and explanations:
* **Error Handling:** The `fetchCryptoData` function now includes robust error handling. Crucially, it checks the `response.ok` property after the `fetch` call. If the API returns an error status (e.g., 404, 500), an error message is thrown and displayed within the `heatmap` div to inform the user. This prevents the script from crashing or displaying a blank heatmap when the API is unavailable. It returns `null` to indicate the fetch failed so the code knows not to try to create a heatmap with invalid data.
* **Conditional Heatmap Creation:** The `createHeatmap` function now *only* runs if `cryptoData` is not `null`. This prevents errors if the `fetchCryptoData` function fails. It's important to check for null data before processing it to avoid `TypeError` exceptions.
* **Clearer API Endpoint:** The `API_URL` is now more clearly defined. The CoinGecko endpoint is for the top 100 coins by market cap.
* **CSS Styling:** The CSS is included directly in the HTML for simplicity. Key improvements:
* **Responsive Grid:** The `grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));` makes the heatmap responsive, adapting to different screen sizes. `minmax(100px, 1fr)` ensures each tile is at least 100px wide but can expand to fill available space.
* **Color Coding:** Uses classes `positive`, `negative`, and `neutral` to color-code tiles based on price changes. The color scheme is now more visually appealing and accessible.
* **Hover Effects:** Adds a `:hover` effect to highlight tiles on mouseover.
* **Tooltips:** Implements tooltips using CSS. These tooltips display more detailed information (price, 24h change, market cap) when the user hovers over a tile. The tooltip now displays a user-friendly "N/A" if the `price_change_percentage_24h` is not available in the API response, preventing `NaN` from showing up. The tooltips are centered and styled for better appearance.
* **Data Presentation:** The code now correctly extracts and formats the relevant data from the CoinGecko API response:
* **Name and Symbol:** Displays both the coin name and symbol for better identification.
* **Price Formatting:** Formats the price to two decimal places using `toFixed(2)`.
* **Market Cap Formatting:** Formats the market cap (in billions) to two decimal places.
* **Percentage Change Formatting:** Formats the 24-hour price change percentage to two decimal places.
* **Clickable Tiles (Optional):** Includes an (optional) example of how to make the heatmap tiles clickable. This demonstrates how you could redirect the user to a separate page to view more details about a specific cryptocurrency. For now, it just displays an alert.
* **`window.onload`:** The `main` function is now called using `window.onload`. This ensures that the script runs after the entire page (including images and other resources) has loaded, preventing potential issues.
* **Clearer Comments and Structure:** The code is thoroughly commented to explain each step. The code is organized into well-defined functions for better readability and maintainability.
* **Up-to-Date API:** Uses the correct and recommended CoinGecko API endpoint for fetching cryptocurrency market data.
* **Asynchronous Operations:** Uses `async` and `await` to handle the asynchronous API call, making the code cleaner and easier to understand.
* **Removed Unnecessary Code:** Removed `getStyleClassForChange` since the logic is now directly inside `createHeatmap` for clarity.
How to run this code:
1. **Save:** Save the code as an HTML file (e.g., `heatmap.html`).
2. **Open in Browser:** Open the HTML file in your web browser.
The heatmap will be displayed in your browser, showing the cryptocurrency market data fetched from the CoinGecko API. The tiles will be color-coded based on their 24-hour price change, and you can hover over them to see more details in the tooltips. If there are any errors during the API request, an error message will be displayed.
👁️ Viewed: 10
Comments