Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve table layout #74

Merged
merged 1 commit into from
Nov 27, 2024
Merged
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
45 changes: 38 additions & 7 deletions src/css/plot_styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -188,19 +188,50 @@ div.d3chart .tick line {
div.d3chart.data_table table,
div.d3chart.data_table th,
div.d3chart.data_table td {
border-collapse: collapse;
padding: 8px;
border-bottom: 1px solid #aaa;
text-align: center;
font-size: 1em;
border-collapse: collapse;
padding: 8px;
border-bottom: 1px solid #aaa;
border-bottom: none !important;
text-align: center;
font-size: 1em;
}

div.d3chart.data_table table tr {
background-color: #fff !important;
background-color: #fff !important;
}

div.d3chart.data_table table tr:hover {
background-color: #f5f5f5 !important;
background-color: #f5f5f5 !important;
}

div.d3chart.included_table {
margin: auto;
}

div.d3chart.included_table table thead tr {
border-top: none !important;
border-bottom: 2px solid #ccc !important;
}

div.d3chart.included_table table,
div.d3chart.included_table th,
div.d3chart.included_table td,
div.d3chart.included_table tr {
border-collapse: collapse;
padding: 10px !important;
border-bottom: none !important;
border-top: none !important;
font-size: 1em;
}

div.d3chart.included_table table tr.summary_row {
border-top: 1px solid #ccc !important;
border-bottom: none !important;
}

div.d3chart.included_table table td.column_left_border,
div.d3chart.included_table table th.column_left_border {
border-left: 1px solid #ccc !important;
}

/* sectors color palette */
Expand Down
104 changes: 104 additions & 0 deletions src/js/included_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import * as d3 from 'd3';

export function tabulateIntoIncludedTable(data, id, opts) {

// set options
opts = (typeof opts === 'undefined') ? {} : opts;
var columnsText = (typeof opts.columnsText === 'undefined') ? [1, 6] : opts.columnsText,
columnsNumeric = (typeof opts.columnsNumeric === 'undefined') ? [2, 5] : opts.columnsNumeric,
columnsPercent = (typeof opts.columnsPercent === 'undefined') ? [3] : opts.columnsPercent,
columnsShortText = (typeof opts.columnsShortText === 'undefined') ? [4] : opts.columnsShortText,
columnValueBreakdown = (typeof opts.columnValueBreakdown === 'undefined') ? 5 : opts.columnValueBreakdown,
columnToMergeHeaderWithContent = (typeof opts.columnToMergeHeaderWithContent === 'undefined') ? 5 : opts.columnToMergeHeaderWithContent,
columnToMergeHeaderNoContent = (typeof opts.columnToMergeHeaderNoContent === 'undefined') ? 6 : opts.columnToMergeHeaderNoContent;

var columns = Object.keys(data[0]);
d3.select(id).selectAll("table").remove();

var idDiv = d3.select(id)
.attr("class","d3chart included_table")
.style("width","800px");

var table = idDiv.append("table"),
thead = table.append("thead"),
tbody = table.append("tbody");

thead.append("tr")
.selectAll("th")
.data(columns)
.enter()
.append("th")
.text(function(column) { return column; })
.style("text-align", "center")
;

if (!(columnToMergeHeaderWithContent == null) && !(columnToMergeHeaderNoContent == null)) {
table.selectAll("thead th:nth-child(" + columnToMergeHeaderWithContent + ")").attr("colspan", 2);
table.selectAll("thead th:nth-child(" + columnToMergeHeaderNoContent + ")").remove();
}

var rows = tbody.selectAll("tr")
.data(data)
.enter()
.append("tr");

var cells = rows.selectAll("td")
.data(row => {
return columns.map(column => {
return { value: row[column] };
});
})
.enter()
.append("td")
.html(d => d.value)
.attr("border","none")
.style("text-align", "left")
;

columnsText.forEach(col => leftAlignBody(col));
columnsNumeric.forEach(col => {formatMillionsBody(col); rightAlignBody(col)});
columnsPercent.forEach(col => {formatFractionIntoPercentage(col); rightAlignBody(col)});
columnsShortText.forEach(col => centerAlignBody(col));



function formatMillionsBody(column) {
table.selectAll("tbody td:nth-child(" + column + ")").html(d => formatMillions(d.value));
}

function formatMillions(num) {
if (num == null) {
return num;
} else if (num < 0.01e6 && num > -0.01e6) {
return num >= 0 ? "<0.01" : ">-0.01";
} else {
return d3.format(",.2f")(num / 1e6);
}
}

function formatFractionIntoPercentage(column) {
table.selectAll("tbody td:nth-child(" + column + ")").html(d => (d.value == null) ? d.value : d3.format(".0%")(d.value));
}

function leftAlignBody(column) {
table.selectAll("tbody td:nth-child(" + column + ")").style("text-align", "left");
}

function rightAlignBody(column) {
table.selectAll("tbody td:nth-child(" + column + ")").style("text-align", "right");
}

function centerAlignBody(column) {
table.selectAll("tbody td:nth-child(" + column + ")").style("text-align", "center");
}

// Add grids in chosen places
table.selectAll("tbody tr:nth-child(" + data.length + ")").attr("class", "summary_row");

if (!(columnValueBreakdown == null)) {
table.selectAll("thead th:nth-child(" + columnValueBreakdown + ")").attr("class", "column_left_border");
table.selectAll("tbody td:nth-child(" + columnValueBreakdown + ")").attr("class", "column_left_border");
}

return table;
}
51 changes: 22 additions & 29 deletions src/routes/portfolio_view.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import { PieExploded } from '../js/pie_exploded.js';
import { techexposure } from '../js/techexposure';
import { choropleth } from '../js/map.js';
import { tabulateIntoIncludedTable } from '../js/included_table.js';

onMount(() => {
function fetchValuePie() {
Expand Down Expand Up @@ -111,6 +112,25 @@
}
}

function fetchTable() {
try {
let opts_table = {
columnsText: [1, 6],
columnsNumeric: [2, 5],
columnsPercent: [3],
columnsShortText: [4],
columnValueBreakdown: 5,
columnToMergeHeaderWithContent: 5,
columnToMergeHeaderNoContent: 6
}
tabulateIntoIncludedTable(tableData, '#includedTable', opts_table)
} catch {
document.querySelector('#includedTable').innerHTML = '';
document.querySelector('#includedTable').appendChild(createErrorMessageDiv());
}
}

fetchTable();
fetchValuePie();
fetchEmissionsPie();
fetchTechmix();
Expand Down Expand Up @@ -149,35 +169,8 @@
</p>
</div>
<div class="table-box sm:col-span-12">
<table class="table table-hover">
<thead>
<tr>
<th>Asset Class</th>
<th>Portfolio value invested (M USD)</th>
<th>Portfolio value invested (%)</th>
<th>Included in the analysis</th>
<th>Value breakout per means of investment</th>
<th></th>
</tr>
</thead>
<tbody>
{#each tableData as row, i}
<tr>
<td>{row['Asset Class']}</td>
<td>{row['Portfolio value invested (M USD)']}</td>
<td>{row['Portfolio value invested (%)']}</td>
<td>{row['Included in the analysis']}</td>
<td>{row['Value breakout per means of investment']}</td>
<td>{row['_']}</td>
</tr>
{/each}
</tbody>
<tfoot>
<tr>
<th colspan="3">This is where we could write a footer.</th>
</tr>
</tfoot>
</table>
<div class="table table-hover" id="includedTable">
</div>
</div>
</div>
<div class="analysis-pie-box sm:col-span-12 bg-orange-300">
Expand Down
Loading