Public
Edited
Oct 3, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart_one_sided = chart_rectangle_data(one_data_initial, 3, null)
Insert cell
Insert cell
code_select = {
if (langage == "dplyr") return "df %>% select(x, z)"
if (langage == "Pandas") return `df.loc[:, ["x", "z"]]`
if (langage == "SQL") return `SELECT x,z FROM df`
}
Insert cell
chart_two_sided_select = chart_rectangle_data(rectangles_select, 3, code_select)
Insert cell
Insert cell
code_rename = {
if (langage == "dplyr") return "df %>% rename(a = y, b = z)"
if (langage == "Pandas") return `df.rename({"a" : "y", "b": "z"})`
if (langage == "SQL") return `SELECT x, y AS a, z AS b FROM df`
}
Insert cell
chart_two_sided_rename = chart_rectangle_data(rectangles_rename, 6, code_rename)
Insert cell
## `mutate`
Insert cell
code_mutate = {
if (langage == "dplyr") return "df %>% mutate(a = x+y)"
if (langage == "Pandas") return `df['a'] = df['x'] + df['y']`
if (langage == "SQL") return `SELECT x, y, z, x+y AS a FROM df`
}
Insert cell
chart_rectangle_data(
one_data_initial.concat(mutate_data),
7,
"df %>% mutate(a = x+y)"
)
Insert cell
one_data_initial
Insert cell
space_between_dataframes = 50
Insert cell
anchor_left_second = d3.max(one_data_initial.map(d => d.x + width_cell)) + space_between_dataframes
Insert cell
mutate_data = create_dataset_after_mutate(
{
anchor_left: [anchor_left_second, 50],
number_columns: 4,
numRows: 3,
width_cell: width_cell, height_cell: height_cell, space_between_cells: space_between_cells,
colors: ["#00a500", "#db951b", "#1b7fdb", "#ee6cc6ff"],
colnames: ["x", "y", "z", "a"],
values: null
})
Insert cell
## Utilitaires
Insert cell
function chart_rectangle_data(rectangles_as_arrays, number_columns = 5, text_to_print = "df %>% select(x,z)") {
// Calculate the width and height based on cell size and spacing
const numColumns = number_columns; // Number of columns
const numRows = 3; // Number of rows
const cellWidth = width_cell ; // Width of each cell
const cellHeight = height_cell ; // Height of each cell
const spaceBetweenCells = space_between_cells; // Space between cells

const tot_width = 50 + numColumns * cellWidth + numColumns*(numColumns - 1) * spaceBetweenCells;
const tot_height = numRows * cellHeight + numRows*(numRows ) * spaceBetweenCells;

const zoom = d3.zoom()
.scaleExtent([1, 30])
.on("zoom", zoomed);

// create our outer SVG element with a size of 500x100 and select it
const svg = d3.create("svg")
.attr("width", tot_width+140)
.attr("height", tot_height+100)
.attr("viewBox", `0 0 ${tot_width+140} ${tot_height+100}`)
// Draw the rectangles
svg.selectAll("rect")
.data(rectangles_as_arrays)
.join("rect")
.attr("x", d => d.x)
.attr("y", d => d.y)
.attr("width", d => d.width)
.attr("height", d => d.height)
.attr("fill", d => d.color)
.attr("opacity", d => d.opacity);

// Add the text if it's not null
svg.selectAll("text")
.data(rectangles_as_arrays)
.join("text")
.attr("x", d => d.x + d.width / 2) // Center text horizontally
.attr("y", d => d.y + d.height / 2) // Center text vertically
.attr("font-size", 12) // Adjust the font size as needed
.attr("fill", "#000000")
.attr("text-anchor", "middle") // Center align text horizontally
.attr("dominant-baseline", "middle") // Center align text vertically
.text(d => (d.text !== undefined && d.text !== null) ? d.text : ""); // Add text only if not null

if (text_to_print == null){
return svg.node();
}

// Add the text
const text = text_to_print ;
const textX = (tot_width / 2) - (text.length * 5); // Calculate X position dynamically
const textY = 30; // Adjust the vertical position as needed
svg.append("text")
.attr("x", 20)
.attr("y", 30)
//.attr("font-family", "Book Antiqua")
.attr("font-size", 20) // Adjust the font size as needed
.attr("fill", "#000000")
.text(text);

return svg.node() ;

// For future me: create an animation

function zoomed({transform}) {
svg.attr("transform", transform);
}

function zooming() {
const [x, y] = [0,100];
svg.transition().duration(2500).call(
zoom.transform,
d3.zoomIdentity.translate(tot_width / 2, tot_height / 2).scale(2)//.translate(-x, -y)
);
}

function reset() {
svg.transition().duration(750).call(
zoom.transform,
d3.zoomIdentity,
d3.zoomTransform(svg.node())
);
}

//return Object.assign(svg.node(), {
// zoomRandom: zooming,
// zoomReset: reset
//});
}
Insert cell
height_cell = 25
Insert cell
width_cell = 55
Insert cell
space_between_cells = 5
Insert cell
one_data_initial = create_data_as_rectangles([20,50], 3, 3, 1)
Insert cell
rectangles_select = create_data_as_rectangles(
{
anchor_left: [20,50],
numColumns: 3, numRows: 3,
number_data: 2,
values: null
})
Insert cell
rectangles_rename = create_data_as_rectangles(
{
anchor_left: [20,50],
numColumns: 3, numRows: 3,
number_data: 2,
operation: "rename",
values: null
})
Insert cell
function create_initial_dataset(
{
anchor_left = [20, 50],
numColumns = 3, numRows = 3,
width_cell, height_cell, space_between_cells,
colors = ["#00a500", "#db951b", "#1b7fdb"]
}
){
return generateRectanglesData(
anchor_left, numColumns, numRows, width_cell, height_cell, space_between_cells, colors
) ;
}
Insert cell
function create_dataset_after_mutate(
{
anchor_left = [20, 50],
number_columns, numRows,
width_cell, height_cell, space_between_cells,
colors = ["#00a500", "#1b7fdb"],
colnames = ["x","z"],
values = null
}){
return generateRectanglesData(
anchor_left,
number_columns, numRows, width_cell,
height_cell, space_between_cells, colors,
colnames,
values) ;
}
Insert cell
function create_data_as_rectangles(
{
anchor_left = [20,50],
numColumns = 3, numRows = 3, number_data = 1,
space_between_dataset = 50, operation = "select",
values = null
}
){
//const anchor_left = [20, 50];
//const numColumns = 3 ;
//const numRows = 3 ;

// Define colors for each column
const initial_colors = ["#00a500", "#db951b", "#1b7fdb"];

const initial_data = create_initial_dataset(
{
anchor_left : anchor_left,
numColumns : numColumns, numRows : numRows,
width_cell : width_cell, height_cell : height_cell, space_between_cells : space_between_cells,
colors : initial_colors, colnames : ['x','y','z']
}
) ;

if (number_data == 1){
return initial_data
}

const tot_width = numColumns * width_cell + numColumns*(numColumns - 1) * space_between_cells ;

const secondRectanglesData = create_dataset_after_mutate(
{
anchor_left: [tot_width + space_between_dataset, 50],
number_columns: operation == "select" ? numColumns-1 : numColumns,
numRows: 3,
width_cell: width_cell, height_cell: height_cell, space_between_cells: space_between_cells,
colors: operation == "select" ? [initial_colors[0], initial_colors[1]] : initial_colors,
colnames: operation == "select" ? ["x", "z"] : ["x", "a", "b"]
});



// Append the second series to the initial series
const combinedRectanglesData = initial_data.concat(secondRectanglesData);

return combinedRectanglesData;
}

Insert cell
generateRectanglesData(
[0,120], 3, 3, 200, 100, 100, ["red","red","red"],
["x","y","z"])
Insert cell
generateRectanglesData(
[0,120], 3, 3, 200, 100, 100, ["red","red","red"],
["x","y","z"],
)
Insert cell
function generateRectanglesData(
anchorLeft, numColumns, numRows, widthCell, heightCell, spaceBetweenCells, colors,
columns = ["x","y","z"],
values = [["a", "b", "c"], ["3", "2", "1"], []]
) {
const rectanglesData = [];

for (let col = 0; col < numColumns; col++) {
const x = anchorLeft[0] + col * (widthCell + spaceBetweenCells);

// Header cell
rectanglesData.push(
createCell(
x, anchorLeft[1], widthCell, heightCell, colors[col], 1,
columns[col]
));

// Data cells with opacity
for (let row = 0; row < numRows; row++) {
const anchorTopCalc = anchorLeft[1] + (row + 1) * (heightCell + spaceBetweenCells);
rectanglesData.push(
createRow(x, anchorTopCalc, widthCell, heightCell, colors[col], 0.5, null)
);
}
}

return rectanglesData;
}
Insert cell
function createCell(x, y, width, height, color, opacity, text) {
return { x, y, width, height, color, opacity, text };
}

Insert cell
function createRow(x, anchor_top, width_cell, height_cell, color, opacity, text){
return createCell(x, anchor_top, width_cell, height_cell, color, opacity, text);
}
Insert cell
// funny animation : https://observablehq.com/@d3/programmatic-zoom
//{
// const form = html`<form>
// <button name="random" type="button">Zoom</button>
// <button name="reset" type="button">Reset</button>
// </form>`;
// form.random.onclick = () => chart_two_sided.zoomRandom();
// form.reset.onclick = () => chart_two_sided.zoomReset();
// return form;
// }
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more