createSummaryVisualization = function (
data,
referenceData,
showAdded = true,
showRemoved = true,
addColor = "#66C2A5",
removeColor = "#F05268",
showContent = true
) {
var columns = Object.keys(data[0]);
var referenceColumns =
referenceData.length > 0 ? Object.keys(referenceData[0]) : [];
var addedColumns = referenceColumns.filter(
(column) => !columns.includes(column)
);
var removedColumns = columns.filter(
(column) => !referenceColumns.includes(column)
);
var addedRows = showAdded ? referenceData.slice(data.length) : [];
var removedRows = showRemoved ? data.slice(referenceData.length) : [];
var allColumns = Array.from(new Set([...columns, ...referenceColumns]));
console.log("allcols", allColumns);
console.log("columns", columns);
if (!showAdded) {
allColumns = allColumns.filter((column) => !addedColumns.includes(column));
}
if (!showRemoved) {
allColumns = allColumns.filter(
(column) => !removedColumns.includes(column)
);
}
console.log("allcols", allColumns);
// Set the dimensions and gaps
var gapX = spacing;
var gapY = spacing;
var marginTop = 0;
var marginLeft = 0;
// Create an div element
var div = d3.create("div");
div
.style("display", "grid")
.style(
"grid-template-columns",
`repeat(${allColumns.length}, ${showContent ? "min-content" : "1fr"})`
)
.style(
"grid-template-rows",
`repeat(${data.concat(addedRows).length}, auto)`
)
.style("gap", "1px")
.style("width", "auto");
const scrollWrapper = d3.create("div");
scrollWrapper.style("overflow-x", "scroll");
scrollWrapper.node().appendChild(div.node()); // Append the div's DOM node to the scrollWrapper's DOM node
// Create groups for each row
var rows = div
.selectAll("div.row")
.data(data.concat(addedRows)) // Include added rows
.enter()
.append("div")
.classed("row", true)
.style("display", "grid")
.style("grid-column", "1 / -1")
.style("grid-template-columns", "subgrid")
.style("grid-template-rows", "subgrid");
// .attr("transform", function (d, i) {
// var rowY = i * (cellHeight + gapY);
// return "translate(0," + (rowY + (i > 0 ? marginTop : 0)) + ")";
// });
// Create rectangles for each cell within the rows
var rectangles = rows
.selectAll("div.cell")
.data(function (d, i) {
return allColumns.map(function (column) {
if (i < data.length) {
// original rows
return { column: column, value: d[column], rowIndex: i };
} else {
// new rows
return {
column: column,
value: referenceData[i][column],
rowIndex: i
};
}
});
})
.enter()
.append("div")
.classed("cell", true)
.style("aspect-ratio", showContent ? "" : "1 / 1")
.style("min-width", "1px")
.style("min-height", "1px")
.style("text-overflow", "clip")
.style("overflow", "hidden")
.style("white-space", "nowrap")
.style("font-size", "0.66em")
.style("display", "flex")
.style("flex-direction", "column")
.style("align-items", "start")
.style("justify-content", "center")
.attr("title", (d) => d.value)
.html((d) => {
if (!showContent) return;
if (removedColumns.includes(d.column)) {
// return `
// <s>${referenceData[d.rowIndex]?.[d.column]}</s>
// `
} else if (addedColumns.includes(d.column)) {
} else if (d.rowIndex >= data.length) {
} else if (d.rowIndex >= referenceData.length) {
// return `
// <s>${referenceData[d.rowIndex]?.[d.column]}</s>
// `
} else if (d.value !== referenceData[d.rowIndex]?.[d.column]) {
return `
<s>${referenceData[d.rowIndex]?.[d.column]}</s>
<span>${d.value}</span>
`;
}
return d.value;
})
// .style("height", cellHeight+"px")
// .attr("x", function (d, i) {
// var colIndex = allColumns.indexOf(d.column);
// return colIndex * (cellWidth + gapX) + (i > 0 ? marginLeft : 0);
// })
.style("background", function (d) {
//TODO cells of added columns for removed rows white
// TODO cells of removed columns for added rows white
if (removedColumns.includes(d.column)) {
return removeColor; // Removed column
} else if (addedColumns.includes(d.column)) {
return addColor; // Added column
} else if (d.rowIndex >= data.length) {
return addColor; // Added row
} else if (d.rowIndex >= referenceData.length) {
return removeColor; // removed row
} else if (d.value !== referenceData[d.rowIndex]?.[d.column]) {
return "#FBE156"; // changed cell
}
return "#F5F5F5"; // Unchanged cells
});
// Add tooltips to show content
rectangles.append("title").text(function (d) {
return d.value;
});
return scrollWrapper.node();
}