In my table I’ve implemented logic to highlight the Row/Column when the cell is selected but i don’t seem to manage to get the borders on top and bottom of the column correct. The border on the bottom is missing as well as on top and the Header row is excluded as well which it shouldn’t
Screenshot:
Here is the full code of the iframe
// Static test data
const correlationData5y = {
"Stock A": { "Stock A": 1.0, "Stock B": 0.75, "Stock C": -0.3 },
"Stock B": { "Stock A": 0.75, "Stock B": 1.0, "Stock C": 0.2 },
"Stock C": { "Stock A": -0.3, "Stock B": 0.2, "Stock C": 1.0 }
};
// Prepare the table
const tableBody = document.querySelector('#correlationTable tbody');
const tableHeaders = document.querySelector('#tableHeaders');
// Extract tickers from the keys of the correlation data
const tickers = Object.keys(correlationData5y);
// Generate table headers dynamically from the tickers
const headerRow = document.createElement('th');
headerRow.textContent = ''; // Top-left corner (empty)
tableHeaders.appendChild(headerRow); // Add the empty top-left cell
tickers.forEach(ticker => {
const headerCell = document.createElement('th');
headerCell.textContent = ticker; // Add ticker as header
tableHeaders.appendChild(headerCell);
});
// Helper function to determine the cell color class based on correlation value
function getCellClass(value) {
if (value < 0) return 'negative'; // Light blue for negative correlations
if (value < 0.3) return 'low'; // Medium light blue for low correlations
if (value < 0.6) return 'medium'; // Medium dark blue for medium correlations
return 'high'; // Dark blue for high correlations
}
// Create rows for the table dynamically from the data
tickers.forEach(tickerRow => {
const row = document.createElement('tr');
const headerCell = document.createElement('th');
headerCell.textContent = tickerRow; // Row header (ticker)
row.appendChild(headerCell);
tickers.forEach(tickerCol => {
const cell = document.createElement('td');
const value = correlationData5y[tickerRow][tickerCol];
cell.textContent = value.toFixed(2); // Show correlation value with 2 decimals
cell.classList.add('heatmap-cell', getCellClass(value)); // Add the appropriate color class
row.appendChild(cell);
});
tableBody.appendChild(row);
});
// Highlight row and column, changing styles only as needed
const tableCells = document.querySelectorAll('td');
tableCells.forEach(cell => {
cell.addEventListener('mouseenter', () => {
const rowIdx = cell.parentNode.rowIndex;
const colIdx = cell.cellIndex;
// Highlight the row
const row = tableBody.rows[rowIdx - 1]; // Adjust for header row
row.classList.add('highlight-row');
// Highlight the column
tableBody.querySelectorAll('tr').forEach(row => {
const targetCell = row.cells[colIdx];
if (targetCell) targetCell.classList.add('highlight-column');
});
// Highlight the specific cell
cell.classList.add('highlight-cell');
});
cell.addEventListener('mouseleave', () => {
const rowIdx = cell.parentNode.rowIndex;
const colIdx = cell.cellIndex;
// Remove row highlight
const row = tableBody.rows[rowIdx - 1];
row.classList.remove('highlight-row');
// Remove column highlight
tableBody.querySelectorAll('tr').forEach(row => {
const targetCell = row.cells[colIdx];
if (targetCell) targetCell.classList.remove('highlight-column');
});
// Remove cell highlight
cell.classList.remove('highlight-cell');
});
});
/* General Page Styling */
body {
font-family: 'Arial', sans-serif;
margin: 20px;
background-color: #141416; /* Dark background */
color: #fff; /* White text for contrast */
}
h2 {
text-align: center;
font-size: 20px; /* Smaller title font */
margin-bottom: 20px; /* Reduced space */
color: #FD6262; /* Red color for titles */
}
table {
width: 70%; /* Reduced table width */
margin: 0 auto;
border-collapse: collapse;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
background-color: #222; /* Dark table background */
}
th, td {
padding: 8px; /* Reduced padding */
text-align: center;
font-size: 12px; /* Smaller font size */
transition: background-color 0.3s ease;
border: 1px solid #444; /* Dark border for all sides */
}
th {
background-color: #141416;
color: #FD6262; /* Red color for text */
font-weight: bold;
}
td {
font-size: 12px; /* Smaller font size for data */
color: #fff; /* White text color for values */
font-weight: normal;
}
/* Gradient color scale for the heatmap (from light blue to dark blue) */
.negative {
background-color: rgba(52, 152, 219, 0.2); /* Light blue for negative correlations */
}
.low {
background-color: rgba(52, 152, 219, 0.4); /* Medium light blue for low correlations */
}
.medium {
background-color: rgba(52, 152, 219, 0.6); /* Medium dark blue for medium correlations */
}
.high {
background-color: rgba(52, 152, 219, 1); /* Dark blue for high correlations */
}
/* Hover effect */
td:hover {
cursor: pointer;
}
/* Container for scroll */
.table-container {
overflow-x: auto;
margin-top: 30px; /* Adjusted margin */
}
/* Highlighted row style */
.highlight-row {
border: 2px solid #FD6262; /* Red border for the row */
}
/* Highlighted column style */
.highlight-column {
border-left: 2px solid #FD6262; /* Red border on the left */
border-right: 2px solid #FD6262; /* Red border on the right */
}
/* Highlighted cell style */
.highlight-cell {
border: 2px solid #FD6262; /* Dark red border for the selected cell */
background-color: rgba(255, 0, 0, 0.2); /* Light red background for the selected cell */
/* z-index: 1; Bring cell to the top if needed */
}
<div class="table-container">
<table id="correlationTable">
<thead>
<tr id="tableHeaders">
<!-- Table headers will be populated dynamically -->
</tr>
</thead>
<tbody>
<!-- Table rows will be populated by JavaScript -->
</tbody>
</table>
</div>
Tried to have a consistent Highlighting but there is Boarders missing as you can see in the Image and described above
2
Answers
It is not normal table structure. Hence, a bit tricky to achieve your desired output.
If the table was of normal structure then it would have been easier.
Anyway, I have updated the css code to match your requirement.
Removed your few css from trs and tds and have added few css to target last rows of the tables and last cells of table columns.
The hardest part was to achieve to the top border of the table which was added by addition of new css rule (tr#tableHeaders).
Feel free to ask which part you do not get.
Hope, this helps.