Built with blockbuilder.org
forked from SpaceActuary's block: Mini Chart
forked from SpaceActuary's block: Mini Charts
forked from anonymous's block: Mini Tables
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'>
<style>
body {
margin: 0;position:fixed;top:0;right:0;bottom:0;left:0;
font-family: 'Montserrat', sans-serif;
font-size: 14px;
display: flex;
flex-wrap: wrap
}
body > div {
flex: 0 0 30%;
margin: 20px 0px 0px 20px;
}
table {
font-family: 'Montserrat', sans-serif;
font-size: 14px;
}
table thead tr th{
border-bottom: 1px solid black;
}
.label,
.change,
.axis,
.main {
text-anchor: middle;
alignment-baseline: middle;
fill: #aaa;
}
th.textual,
td.textual {
text-align: left;
}
th.centered,
td.centered {
text-align: center;
}
th.numeric,
td.numeric {
text-align: right;
}
.change,
.main {
text-anchor: middle;
alignment-baseline: middle;
fill: #333;
}
line.axis {
stroke: #aaa;
stroke-width: 1.5px;
}
</style>
</head>
<body>
<script>
console.clear();
var changeFormat = d3.format(".2f"),
numberFormat = d3.format(",.0f"),
percentFormat = d3.format(".1%");
d3.csv("data.csv", function(data){
data.forEach(function(d, i, data){
var d0 = i ? data[i-1] : {};
d.year = +d.year;
d.amount1 = +d.amount1;
d.yoy1 = i ? d.amount1 / d0.amount1 - 1 : 0;
d.amount2 = +d.amount2;
d.yoy2 = i ? d.amount2 / d0.amount2 - 1 : 0;
d.amount3 = +d.amount3;
d.yoy3 = i ? d.amount3 / d0.amount3 - 1 : 0;
})
var data_ABC = data.filter(function(d){ return d.group == "ABC"}),
data_XYZ = data.filter(function(d){ return d.group == "XYZ"}),
data_Total = data.filter(function(d){ return d.group == "Total"});
var miniTable0 = miniTable()
.columns([
{ head: 'Year', cl: 'textual', thead_row: 1, rowspan: 2, colspan: 1,
html: function(d){ return d.year; } },
{ head: 'Variable 1', cl: 'centered', thead_row: 1, rowspan: 1, colspan: 2 },
{ head: 'Variable 2', cl: 'centered', thead_row: 1, rowspan: 1, colspan: 2 },
{ head: 'Variable 3', cl: 'centered', thead_row: 1, rowspan: 1, colspan: 2 },
{ head: 'Amount', cl: 'numeric', thead_row: 2,
html: function(d){ return numberFormat(+d.amount1); } },
{ head: 'YoY%', cl: 'numeric', thead_row: 2,
html: function(d){ return percentFormat(+d.yoy1); } },
{ head: 'Amount', cl: 'numeric', thead_row: 2,
html: function(d){ return changeFormat(+d.amount2); } },
{ head: 'YoY%', cl: 'numeric', thead_row: 2,
html: function(d){ return percentFormat(+d.yoy2); } },
{ head: 'Amount', cl: 'numeric', thead_row: 2,
html: function(d){ return percentFormat(+d.amount3); } },
{ head: 'YoY%', cl: 'numeric', thead_row: 2,
html: function(d){ return percentFormat(+d.yoy3); } }
]);
var miniTable1 = miniTable()
.columns([
{ head: 'Year', cl: 'textual',
html: function(d){ return d.year; } },
{ head: 'Amount', cl: 'numeric',
html: function(d){ return numberFormat(+d.amount1); } },
{ head: 'YoY%', cl: 'numeric',
html: function(d){ return percentFormat(+d.yoy1); } }
]);
var miniTable2 = miniTable()
.columns([
{ head: 'Year', cl: 'textual',
html: function(d){ return d.year; } },
{ head: 'Amount', cl: 'numeric',
html: function(d){ return changeFormat(+d.amount2); } },
{ head: 'YoY%', cl: 'numeric',
html: function(d){ return percentFormat(+d.yoy2); } }
]);
var miniTable3 = miniTable()
.columns([
{ head: 'Year', cl: 'textual',
html: function(d){ return d.year; } },
{ head: 'Amount', cl: 'numeric',
html: function(d){ return percentFormat(+d.amount3); } },
{ head: 'YoY%', cl: 'numeric',
html: function(d){ return percentFormat(+d.yoy3); } }
]);
d3.select("body").append("div")
.datum(data_ABC)
.call(miniTable0);
/*
d3.select("body").append("div")
.datum(data_ABC)
.call(miniTable1);
d3.select("body").append("div")
.datum(data_ABC)
.call(miniTable2);
d3.select("body").append("div")
.datum(data_ABC)
.call(miniTable3);
d3.select("body").append("div")
.datum(data_XYZ)
.call(miniTable1);
d3.select("body").append("div")
.datum(data_XYZ)
.call(miniTable2);
d3.select("body").append("div")
.datum(data_XYZ)
.call(miniTable3);
d3.select("body").append("div")
.datum(data_Total)
.call(miniTable1);
d3.select("body").append("div")
.datum(data_Total)
.call(miniTable2);
d3.select("body").append("div")
.datum(data_Total)
.call(miniTable3);
*/
});
function miniTable() {
var margin = {top: 20, bottom: 80, left: 80, right: 20},
height = 170 - margin.top - margin.bottom, // default height
width = 280 - margin.left - margin.right, // default width
changeFormat = d3.format(".1f"),
numberFormat = d3.format(",.0f"),
columns = [],
xScale = d3.scalePoint(),
yScale = d3.scaleLinear(),
line = d3.line()
.x(function(d, i, data){ return xScale(d.x); })
.y(function(d, i, data){ return yScale(d.y); });
function table(selection) {
selection.each(function(data){
var tableData = data; // dataPrep(raw, xValue, yValue);
console.table(tableData);
var yExt = d3.extent(tableData, d => d.y);
// Select the svg element, if it exists.
var tableElement = d3.select(this).selectAll("table").data([1]);
// Otherwise, create the skeletal chart.
var tableElementEnter = tableElement.enter().append("table")
tableElementEnter.append("thead")
tableElementEnter.append("tbody")
tableElementEnter.append("tfoot")
tableElement = tableElement.merge(tableElementEnter)
var thead = tableElement.selectAll("thead")
var tbody = tableElement.selectAll("tbody")
var tfoot = tableElement.selectAll("tfoot")
var thead_data = d3.nest()
.key(function (d) { return d.thead_row; })
.entries(columns);
console.log("thead_data",thead_data)
var thead_tr = thead.selectAll('th').data(thead_data)
thead_tr.enter().append("tr")
.merge(thead_tr)
.selectAll('th')
.data(function(d){ return d.values}).enter()
.append('th')
.attr('class', d => d.cl)
.attr('rowspan', d => d.rowspan)
.attr('colspan', d => d.colspan)
.text(d => d.head)
var rows = tbody.selectAll("tr")
.data(tableData)
.enter()
.append("tr");
// create a cell in each row for each column
var cells = rows.selectAll("td")
.data(function(row, i) {
// evaluate column objects against the current row
return columns.filter(function(c){ return ('html' in c) })
.map(function(c) {
var cell = {};
d3.keys(c).forEach(function(k) {
cell[k] = typeof c[k] == 'function' ? c[k](row,i) : c[k];
});
return cell;
});
});
cells.enter().append("td")
.merge(cells)
.html(d => d.html)
.attr('class', d => d.cl)
})
}
table.width = function(_) {
if (!arguments.length) return width;
width = _;
return table;
};
table.height = function(_) {
if (!arguments.length) return height;
height = _;
return table;
};
table.columns = function(_) {
if (!arguments.length) return columns;
columns = _;
return table;
};
table.numberFormat = function(_) {
if (!arguments.length) return numberFormat;
numberFormat = _;
return table;
};
table.changeFormat = function(_) {
if (!arguments.length) return changeFormat;
changeFormat = _;
return table;
};
return table;
}
</script>
</body>
https://d3js.org/d3.v4.min.js