Published
Edited
Nov 12, 2021
6 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function visualise(data, matches_dateExtent) {
let container = html`<div id="viz_container" style="width: 700px">`;

var gap_between_lines = 35, // vertical height between line graphs
branch_steepness = 15, // determines the steepness of the branch angle
shunt_to_right = 40, // horizontal position of the branch
bar_colour = `rgba(${bar_colour_val}, 1)`,
bar_strokeWidth = 16,
text_strokeWidth = 3,
demo_margin = { top: 15, bottom: 30, left: 60, right: 0 },
max_width = 625,
viz_width =
width - demo_margin.left - demo_margin.right > max_width
? max_width
: width - demo_margin.left - demo_margin.right,
waterfall_stroke_width = 3;

const burney_link_colour = "rgba(41, 50, 65,0.5)",
bna_link_colour = burney_link_colour;

// determine chart height
let data_length = 0;
data.forEach(function (d, i) {
if (d.connected_titles) {
data_length = data_length + d.connected_titles.length;
} else {
data_length++;
}
});
let demo_height =
data_length * gap_between_lines + demo_margin.top + demo_margin.bottom;

//////////////
/// Scales ///
//////////////

var x = d3
.scaleLinear()
.domain(matches_dateExtent)
.range([0, viz_width - 15]);

// vertical scale for full chart height
var y = d3.scaleLinear().domain([0, 200]).range([demo_height, 0]);

// separate div for fixed xaxis
var x_axis = d3
.select(container)
.append("div")
.attr("class", "x_axis_wrapper")
.append("svg")
.attr("width", viz_width + demo_margin.left + demo_margin.right)
.attr("height", 30)
.append("g")
.attr(
"transform",
"translate(" + demo_margin.left + "," + demo_margin.top * 2 + ")"
);

// Add the X Axis
x_axis
.append("g")
.attr("id", "axis_g")
.call(d3.axisTop(x).tickFormat(d3.format("d")));

// Remove axis line
x_axis.select("#axis_g").select("path").remove();

var svg = d3
.select(container)
.append("svg")
.attr("width", viz_width + 30)
.attr("height", demo_height);

svg.node().appendChild(gradient_defs);

// Define the div for the tooltip
var div = d3
.select(container)
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);

// gridlines in x axis function
function make_x_gridlines() {
return d3.axisBottom(x);
}

// add the X gridlines
svg
.append("g")
.attr("class", "grid")
.attr(
"transform",
"translate(" + demo_margin.left + "," + demo_height + ")"
)
.call(make_x_gridlines().tickSize(-demo_height).tickFormat(""));

// Add the group for line graphs
var svg_graphs = svg
.append("g")
.attr("id", "graph_group")
.attr(
"transform",
"translate(" + demo_margin.left + "," + demo_margin.top + ")"
);

var nested_count = 0;

////////////
/// Draw ///
////////////

data.forEach(function (d, i) {
/////////////////////
/// Nested Titles ///
/////////////////////
if ("connected_titles" in d) {
// To vertically position all the line graphs correctly, we use the variable nested_count to keep track of the number of branched line graphs drawn
nested_count = nested_count + d["connected_titles"].length - 1;

d["connected_titles"].forEach(function (nested_d, nested_i) {
var horizontal_offset;
// check if branch really long
if (d["connected_titles"].length > 15) {
horizontal_offset = shunt_to_right + nested_i * 5;
} else {
horizontal_offset = shunt_to_right + nested_i * branch_steepness;
}
var vertical_offset =
(i + nested_i + nested_count - d["connected_titles"].length + 1) *
gap_between_lines;

var title_wrapper = svg_graphs
.append("g")
.attr("class", "title_wrapper")
.attr("transform", "translate(0," + vertical_offset + ")");

if (
!(nested_d.first_date_held == "" && nested_d.last_date_held == "")
) {
title_wrapper
.append("line")
.attr("class", "line_run")
.attr("x1", () =>
nested_d.first_date_held == ""
? x(+nested_d.last_date_held.substring(0, 4) - 1)
: nested_d.first_date_held == nested_d.last_date_held
? x(+nested_d.first_date_held.substring(0, 4) - 1)
: x(+nested_d.first_date_held.substring(0, 4))
)
.attr("x2", () =>
nested_d.last_date_held == "" || nested_d.last_date_held == null
? x(+nested_d.date_sort_last + 1)
: nested_d.last_date_held == "Continuing"
? x(new Date().getFullYear())
: x(+nested_d.last_date_held.substring(0, 4))
)
.attr("y1", gap_between_lines + -bar_strokeWidth / 2 + 6)
.attr("y2", gap_between_lines + -bar_strokeWidth / 2 + 6)
.attr("stroke", bar_colour)
.attr("stroke-width", bar_strokeWidth);

// if not final out of group
if (nested_i != d["connected_titles"].length - 1) {
title_wrapper
.append("line")
.attr("class", "line_run_drop")
.attr("x1", () =>
nested_d.last_date_held == ""
? x(+nested_d.date_sort_last) - waterfall_stroke_width / 2
: nested_d.last_date_held == "Continuing"
? x(new Date().getFullYear()) - waterfall_stroke_width / 2
: x(+nested_d.last_date_held) - waterfall_stroke_width / 2
)
.attr("x2", () =>
nested_d.last_date_held == ""
? x(+nested_d.date_sort_last) - waterfall_stroke_width / 2
: nested_d.last_date_held == "Continuing"
? x(new Date().getFullYear()) - waterfall_stroke_width / 2
: x(+nested_d.last_date_held) - waterfall_stroke_width / 2
)
.attr("y1", gap_between_lines + 6)
.attr("y2", gap_between_lines * 2 + 6)
.attr("stroke", "url(#e)")
.attr("stroke-width", waterfall_stroke_width);
}
}

// Draw the angled line - connecting the nested titles together
if (nested_i != 0) {
let x1, x2;
// check if branch really long
if (d["connected_titles"].length > 15) {
x1 = shunt_to_right + 5 * (nested_i - 1);
x2 = shunt_to_right + 5 * nested_i;
} else {
x1 = shunt_to_right + branch_steepness * (nested_i - 1);
x2 = shunt_to_right + branch_steepness * nested_i;
}

title_wrapper
.append("line")
.attr("class", "connected_line")
.attr("x1", x1)
.attr("x2", x2)
.attr("y1", 0 + demo_margin.top - 10)
.attr("y2", gap_between_lines + demo_margin.top - 10);
}

var title_nested_offset_wrapper = title_wrapper
.append("g")
.attr("class", "title_nested_offset_wrapper")
.attr("transform", "translate(" + horizontal_offset + ",0)");

// additional horizontal offset to titles so doesn't overlap with branching
var title_text1 = title_nested_offset_wrapper
.append("text")
.attr("class", "title_name_wrapper")
.attr("transform", "translate(8,52)");
var title_text2 = title_nested_offset_wrapper
.append("text")
.attr("class", "title_name_wrapper")
.attr("transform", "translate(8,52)");

title_text1
.append("tspan")
.attr("class", "title_name")
.text(" " + nested_d["publication_title"])
.attr("stroke", "white")
.attr("opacity", 0.93)
.attr("stroke-width", text_strokeWidth);

let titleName_span = title_text2
.append("a")
.attr("href", nested_d["explore_link"])
.attr("target", "_blank")
.attr("cursor", "pointer")
.append("tspan")
.attr("class", "title_name")
.text(" " + nested_d["publication_title"])
.attr("fill", "black");

// append arrows for preceeding, succeeding titles
if (
nested_d["preceding_titles"] != null &&
nested_d["preceding_titles"] != ""
) {
title_text2
.append("tspan")
.text(" <")
.attr("id", "preceding")
.attr("class", "arrow")
.style("cursor", "default")
.on("mouseover", function () {
div.transition().duration(200).style("opacity", 0.98);
div
.html(nested_d["preceding_titles"])
.style("background", "rgb(219, 232, 237)")
.style("left", d3.event.pageX + 10 + "px")
.style("top", d3.event.pageY - 28 - window.scrollY + "px");
})
.on("mouseout", function () {
div.transition().duration(500).style("opacity", 0);
});
}
if (
nested_d["succeeding_titles"] != null &&
nested_d["succeeding_titles"] != ""
) {
title_text2
.append("tspan")
.text(" >")
.attr("id", "succeeding")
.attr("class", "arrow")
.style("cursor", "default")
.on("mouseover", function () {
div.transition().duration(200).style("opacity", 0.98);
div
.html(nested_d["succeeding_titles"])
.style("background", "rgb(219, 232, 237)")
.style("left", d3.event.pageX + 10 + "px")
.style("top", d3.event.pageY - 28 - window.scrollY + "px");
})
.on("mouseout", function () {
div.transition().duration(500).style("opacity", 0);
});
}

if (nested_d.online_status == "BURNEY") {
let burney_link = title_nested_offset_wrapper
.append("a")
.attr("class", "burney_a")
.attr(
"href",
"https://www.bl.uk/collection-guides/burney-collection"
)
.attr("target", "_blank")
.attr("opacity", 0.5)
.style(
"transform",
"translate(" + (-60 - horizontal_offset) + "px,22px)"
);

burney_link
.append("path")
.attr("d", "M -10 20 H 60 V 22 Q 50 20 45 36 H -10 V 20")
.style("transform", "translateY(-3px)")
.attr("class", "burney_link_rect")
.attr("x", 0)
.attr("y", gap_between_lines - 18)
.attr("width", 60)
.attr("height", 16)
.attr("fill", burney_link_colour)
.style("cursor", "pointer")
.on("mouseover", function (d) {
return d3
.select(this)
.transition()
.duration(80)
.style("opacity", 0.5);
})
.on("mouseout", function (d) {
return d3
.select(this)
.transition()
.duration(80)
.style("opacity", 1);
});

burney_link
.append("text")
.attr("class", "burney_link")
.style("font-weight", 800)
.text("Burney")
.attr("fill", "white")
.attr("x", 1.5)
.attr("y", gap_between_lines - 5.8)
.style("cursor", "pointer")
.on("mouseover", function (d) {
return d3
.select(this.parentNode)
.select(".burney_link_rect")
.transition()
.duration(80)
.style("opacity", 0.5);
})
.on("mouseout", function (d) {
return d3
.select(this.parentNode)
.select(".burney_link_rect")
.transition()
.duration(80)
.style("opacity", 1);
});
}

if (nested_d.link_to_british_newspaper_archive != "") {
let bna_link = title_nested_offset_wrapper
.append("a")
.attr("class", "bna_a")
.attr("href", nested_d.link_to_british_newspaper_archive)
.attr("target", "_blank")
.attr("opacity", 0.5)
.style(
"transform",
"translate(" + (-50 - horizontal_offset) + "px,22px)"
);

bna_link
.append("path")
.attr("class", "bna_link_rect")
.attr("d", "M -10 20 H 60 V 22 Q 50 20 45 36 H -10 V 20")
.style("transform", "translate(-9px, -3px)")
.attr("fill", bna_link_colour)
.style("cursor", "pointer")
.on("mouseover", function (d) {
return d3
.select(this)
.transition()
.duration(80)
.style("opacity", 0.5);
})
.on("mouseout", function (d) {
return d3
.select(this)
.transition()
.duration(80)
.style("opacity", 1);
});

bna_link
.append("text")
.attr("class", "bna_link")
.style("font-weight", 800)
.text("BNA")
.attr("fill", "white")
.attr("x", 0)
.attr("y", gap_between_lines - 5.8)
.style("cursor", "pointer")
.on("mouseover", function (d) {
return d3
.select(this.parentNode)
.select(".bna_link_rect")
.transition()
.duration(80)
.style("opacity", 0.5);
})
.on("mouseout", function (d) {
return d3
.select(this.parentNode)
.select(".bna_link_rect")
.transition()
.duration(80)
.style("opacity", 1);
});
}

// Draw the baselines for each sparkline
if (nested_i != 0) {
let position_dividing_baselines;
if (d["connected_titles"].length > 15) {
position_dividing_baselines =
nested_d.last_date_held == ""
? x(+nested_d.date_sort_last) - shunt_to_right - 5 * nested_i
: nested_d.last_date_held == "Continuing"
? x(new Date().getFullYear()) - shunt_to_right - 5 * nested_i
: x(+nested_d.last_date_held) - shunt_to_right - 5 * nested_i;
} else {
position_dividing_baselines =
nested_d.last_date_held == ""
? x(+nested_d.date_sort_last) -
shunt_to_right -
branch_steepness * nested_i
: nested_d.last_date_held == "Continuing"
? x(new Date().getFullYear()) -
shunt_to_right -
branch_steepness * nested_i
: x(+nested_d.last_date_held.substring(0, 4)) -
shunt_to_right -
branch_steepness * nested_i;
}

title_nested_offset_wrapper
.append("line")
.attr("class", "connected_line")
.attr("x1", 0)
.attr("x2", position_dividing_baselines)
.attr("y1", 0)
.attr("y2", 0)
.attr("transform", "translate(0,40)");

title_nested_offset_wrapper
.append("line")
.attr("class", "connected_line2")
.attr("x1", 0)
.attr("x2", 100)
.attr("y1", 0)
.attr("y2", 0)
.attr(
"transform",
"translate(" + position_dividing_baselines + ",40)"
);
} else {
let position_dividing_baselines =
nested_d.last_date_held == ""
? x(+nested_d.date_sort_last) - shunt_to_right
: nested_d.last_date_held == "Continuing"
? x(new Date().getFullYear()) - shunt_to_right
: x(+nested_d.last_date_held) - shunt_to_right;

title_nested_offset_wrapper
.append("line")
.attr("class", "connected_line")
.attr("x1", -shunt_to_right)
.attr("x2", position_dividing_baselines)
.attr("y1", 0)
.attr("y2", 0)
.attr("transform", "translate(0,40)");

title_nested_offset_wrapper
.append("line")
.attr("class", "connected_line2")
.attr("x1", 0)
.attr("x2", 100)
.attr("y1", 0)
.attr("y2", 0)
.attr(
"transform",
"translate(" + position_dividing_baselines + ",40)"
);
}
});
} else {
/////////////////////
/// Single Titles ///
/////////////////////
var title_wrapper = svg_graphs
.append("g")
.attr("class", "title_wrapper")
.attr(
"transform",
"translate(0," + (i + nested_count) * gap_between_lines + ")"
);

if (!(d.first_date_held == "" && d.last_date_held == "")) {
title_wrapper
.append("line")
.attr("class", "line_run")
.attr("x1", () =>
d.first_date_held == ""
? x(+d.last_date_held - 1)
: d.first_date_held == d.last_date_held
? x(+d.first_date_held - 1)
: x(+d.first_date_held.substring(0, 4))
)
.attr("x2", () =>
+d.last_date_held == 0 || d.last_date_held == "Continuing"
? x(new Date().getFullYear())
: x(+d.last_date_held.substring(0, 4))
)
.attr("y1", gap_between_lines - bar_strokeWidth / 2 + 6)
.attr("y2", gap_between_lines - bar_strokeWidth / 2 + 6)
.attr("stroke", bar_colour)
.attr("stroke-width", bar_strokeWidth);
}

var title_text1 = title_wrapper
.append("text")
.attr("class", "title_name_wrapper")
.attr("transform", "translate(3,52)");
var title_text2 = title_wrapper
.append("a")
.attr("href", d["explore_link"])
.attr("target", "_blank")
.attr("cursor", "pointer")
.append("text")
.attr("class", "title_name_wrapper")
.attr("transform", "translate(3,52)");
title_text1
.append("tspan")
.attr("class", "title_name")
.text(" " + d["publication_title"])
.attr("stroke", "white")
.attr("opacity", 0.93)
.attr("stroke-width", text_strokeWidth);

let titleName_span = title_text2
.append("tspan")
.attr("class", "title_name")
.text(" " + d["publication_title"])
.attr("fill", "black");

title_text1
.append("tspan")
.attr("class", "title_name")
.text(" " + d["publication_title"])
.attr("stroke", "white")
.attr("opacity", 0.93)
.attr("stroke-width", text_strokeWidth);

title_text2
.append("tspan")
.attr("class", "title_name")
.text(" " + d["publication_title"])
.attr("fill", "black");

// append line
let position_dividing_baselines =
+d.last_date_held == 0 || d.last_date_held == "Continuing"
? x(new Date().getFullYear())
: x(+d.last_date_held.substring(0, 4));

title_wrapper
.append("line")
.attr("class", "connected_line")
.attr("x1", 0)
.attr("x2", position_dividing_baselines)
.attr("y1", 0)
.attr("y2", 0)
.attr("transform", "translate(0,40)");
title_wrapper
.append("line")
.attr("class", "connected_line2")
.attr("x1", 0)
.attr("x2", 100)
.attr("y1", 0)
.attr("y2", 0)
.attr("transform", "translate(" + position_dividing_baselines + ",40)");

if (d.online_status == "BURNEY") {
let burney_link = title_wrapper
.append("a")
.attr("class", "burney_a")
.attr("href", "https://www.bl.uk/collection-guides/burney-collection")
.attr("target", "_blank")
.attr("opacity", 0.5)
.style("transform", "translate(" + -60 + "px,22px)");

burney_link
.append("path")
.attr("d", "M -10 20 H 60 V 22 Q 50 20 45 36 H -10 V 20")
.style("transform", "translate(0px, -3px)")
.attr("class", "burney_link_rect")
.attr("fill", burney_link_colour)
.style("cursor", "pointer")
.on("mouseover", function (d) {
return d3
.select(this)
.transition()
.duration(80)
.style("opacity", 0.5);
})
.on("mouseout", function (d) {
return d3
.select(this)
.transition()
.duration(80)
.style("opacity", 1);
});

burney_link
.append("text")
.attr("class", "burney_link")
.style("font-weight", 800)
.text("Burney")
.attr("fill", "white")
.attr("x", 1.5)
.attr("y", gap_between_lines - 5.8)
.style("cursor", "pointer")
.on("mouseover", function (d) {
return d3
.select(this.parentNode)
.select(".burney_link_rect")
.transition()
.duration(80)
.style("opacity", 0.5);
})
.on("mouseout", function (d) {
return d3
.select(this.parentNode)
.select(".burney_link_rect")
.transition()
.duration(80)
.style("opacity", 1);
});
}

if (d.link_to_british_newspaper_archive != "") {
let bna_link = title_wrapper
.append("a")
.attr("class", "bna_a")
.attr("href", d.link_to_british_newspaper_archive)
.attr("target", "_blank")
.attr("opacity", 0.5)
.style("transform", "translate(" + -50 + "px,22px)");

bna_link
.append("path")
.attr("d", "M -10 20 H 60 V 22 Q 50 20 45 36 H -10 V 20")
.style("transform", "translate(-9px, -3px)")
.attr("class", "bna_link_rect")
.attr("fill", bna_link_colour)
.style("cursor", "pointer")
.on("mouseover", function (d) {
return d3
.select(this)
.transition()
.duration(80)
.style("opacity", 0.5);
})
.on("mouseout", function (d) {
return d3
.select(this)
.transition()
.duration(80)
.style("opacity", 1);
});

bna_link
.append("text")
.attr("class", "bna_link")
.style("font-weight", 800)
.text("BNA")
.attr("fill", "white")
.attr("x", 0)
.attr("y", gap_between_lines - 5.8)
.style("cursor", "pointer")
.on("mouseover", function (d) {
return d3
.select(this.parentNode)
.select(".bna_link_rect")
.transition()
.duration(80)
.style("opacity", 0.5);
})
.on("mouseout", function (d) {
return d3
.select(this.parentNode)
.select(".bna_link_rect")
.transition()
.duration(80)
.style("opacity", 1);
});
}
}
});
return container;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
gradient_defs = html`
<svg width=500 height=10><defs>
<linearGradient id="e" x1=0 x2=0 y1=0 y2=80 gradientUnits="userSpaceOnUse">
<stop stop-color="rgba(${bar_colour_val}, 1)" offset="0" />
<stop stop-color="rgba(${bar_colour_val}, 0.8)" offset="0.5" />
<stop stop-color="rgba(${bar_colour_val}, 0)" offset="1" />
</linearGradient>
<linearGradient id="a" x1=0 x2=50 y1=0 y2=0 gradientUnits="userSpaceOnUse">
<stop stop-color="rgba(0, 0, 0, ${baseline_opacity})" offset="0" />
<stop stop-color="rgba(0, 0, 0, 0)" offset="1" />
</linearGradient>
</defs>
`
Insert cell
Insert cell
style = html`<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700;1,900&display=swap" rel="stylesheet">
<style>
#viz_container {
height: 800px;
overflow-x: scroll;
max-width: 100%;
overflow-x: hidden;
}

.x_axis_wrapper {
background: white;
padding-top: 5px;
position: sticky;
top: 0;
}

.mf_line {
fill: none;
stroke: rgb(255, 0, 0);
stroke-width: 1.5;
}

.mf_sum {
fill: rgb(255, 0, 0);
}

.unknown_bar_mf {
fill: rgb(255, 0, 0);
}

.hc_line {
fill: none;
stroke: black;
stroke-width: 1.5;
stroke-dasharray: 2 2;
}

.arrow {
opacity: 0.5;
stroke: gray;
}

.acetate_warning {
fill: rgb(255, 137, 0);
}

text {
font-family: 'Source Sans Pro', sans-serif;
font-size: 10.5pt;
}

.bna_a:hover, .burney_a:hover{
text-decoration: none !important;
}

.title_geographic_coverage {
font-style: italic;
}bu

.title_id {
fill: rgb(124, 124, 124);
text-decoration: underline;
}

.grid {
opacity: 0.35;
}

.grid line {
stroke-dasharray: 7 3;
stroke-width: 1;
opacity: 0.3;
}

.mf_sum_bracket {
stroke-dasharray: 0;
stroke: red;
opacity: 0.5;
stroke-width: 3;
}

.connected_line {
stroke: rgba(41, 50, 65,${baseline_opacity});
/* stroke: url(#a); */
stroke-width: 2;
stroke-dasharray: 0;
}

.connected_line2 {
stroke: url(#a);
stroke-width: 2;
stroke-dasharray: 0;
}

.cover_up_line {
stroke: white;
stroke-width: 5;
stroke-dasharray: 0;
}

div.tooltip {
position: fixed;
text-align: left;
padding: 2px;
font-family: 'Source Sans Pro', sans-serif;
font-size: 10.5pt;
background: #c3dbe9;
border: 0px;
border-radius: 8px;
pointer-events: none;
}

.stop-left {
stop-color: rgb(217, 190, 190);
stop-opacity: 0.35;
/* Indigo */
}

.stop-middle {
stop-color: rgb(217, 190, 190);
stop-opacity: 0.2;
}

.stop-right {
stop-color: rgb(217, 190, 190);
stop-opacity: 0.15;
}

.stop-left_reverse {
stop-color: rgb(217, 190, 190);
stop-opacity: 0;
}

.stop-middle_reverse {
stop-color: rgb(217, 190, 190);
stop-opacity: 0.1;
}

.stop-right_reverse {
stop-color: rgb(217, 190, 190);
stop-opacity: 0.35;
}

.filled {
fill: url(#mainGradient);
}

.filled_reverse {
fill: url(#reverseGradient);
}
</style>`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// title_list_wConnectivity = {
// ///////////////////////////////////////////////////////////////////////////////////////
// /// This is the code used to create FileAttachment("title_list_wConnectivity.json") ///
// ///////////////////////////////////////////////////////////////////////////////////////

// let title_list_wConnectivity = titles_addConnectivityArray;
// let newspaper_titles_data_nestedConnectivity = [];
// let newspaper_titles_data_nestedConnectivity_title_ids = [];
// title_list_wConnectivity.forEach(function (d) {
// // check if d['title_id'] already in newspaper_titles_data_nestedConnectivity_title_ids
// // otherwise - skip
// var already_in_newspaper_titles_data_nestedConnectivity = newspaper_titles_data_nestedConnectivity_title_ids.includes(
// d["title_id"]
// );
// if (!already_in_newspaper_titles_data_nestedConnectivity) {
// if (d.connectivity) {
// // place all connectivity ids in connected_newspaper_titles
// let connected_newspaper_titles = [d["title_id"]].concat(
// d["connectivity"]
// );
// // check the records in the array of connected to IDs for any additional IDs in connectivity
// // return new array of (original connected IDs + additional IDs in records' connectivity)
// function create_new_array_of_connected_ids(old_Array) {
// let connectivity_new_array = old_Array;
// old_Array.forEach(function (element) {
// // for each id in connected_newspaper_titles, find the corresponding record in title_list
// // if does not exist in connected_newspaper_titles, skip step
// var newspaper_record = titles_addConnectivityArray.find(
// (o) => o["title_id"] == element
// );
// // if there is a matching record (some are out of date range) in title_list, concatenate the connectivity array
// if (newspaper_record) {
// if (newspaper_record.connectivity) {
// connectivity_new_array = connectivity_new_array.concat(
// newspaper_record.connectivity
// );
// }
// }
// });
// // ALSO check against other records in title_list, if any others connected to connectivity_new_array (sometimes crawling network will miss records with an assymetric connection)
// titles_addConnectivityArray.forEach(function (newspaper_title) {
// if (newspaper_title["connectivity"]) {
// const found = newspaper_title["connectivity"].some(
// (r) => connectivity_new_array.indexOf(r) >= 0
// );
// if (found) {
// connectivity_new_array.push(newspaper_title["title_id"]);
// }
// }
// });
// // filter out duplicates
// let set = new Set(connectivity_new_array);
// connectivity_new_array = Array.from(set);
// return connectivity_new_array;
// }
// function all_connected_ids_in_Array(Array) {
// var connectivity_ids_array = create_new_array_of_connected_ids(Array);
// if (connectivity_ids_array.length > Array.length) {
// return false;
// } else {
// return true;
// }
// }
// function add_ids_to_Array(Array) {
// connected_newspaper_titles = create_new_array_of_connected_ids(
// connected_newspaper_titles
// );
// }
// // check all connectivity data in connected_newspaper_titles
// // if not, add to connected_newspaper_titles.
// // Repeat until all connectivity data in connected_newspaper_titles
// do {
// add_ids_to_Array(connected_newspaper_titles);
// } while (!all_connected_ids_in_Array(connected_newspaper_titles));
// // add nested data to newspaper_titles_data_nestedConnectivity
// let new_nested_newspaper_titles = titles_addConnectivityArray.filter(
// function (d) {
// return connected_newspaper_titles.includes(d["title_id"]);
// }
// );
// // check length nested data > 1
// if (new_nested_newspaper_titles.length > 1) {
// newspaper_titles_data_nestedConnectivity.push({
// connected_titles: new_nested_newspaper_titles,
// ids: connected_newspaper_titles
// });
// newspaper_titles_data_nestedConnectivity_title_ids = newspaper_titles_data_nestedConnectivity_title_ids.concat(
// connected_newspaper_titles
// );
// } else {
// newspaper_titles_data_nestedConnectivity_title_ids.push(
// d["title_id"]
// );
// newspaper_titles_data_nestedConnectivity.push(d);
// }
// } else {
// newspaper_titles_data_nestedConnectivity_title_ids.push(d["title_id"]);
// newspaper_titles_data_nestedConnectivity.push(d);
// }
// }
// });
// return newspaper_titles_data_nestedConnectivity;
// }

Insert cell
// titles_addConnectivityArray = {
// // turn connectivity facet into array of ids
// let titles_addConnectivityArray = title_list.map(function (obj) {
// let connected_ids = connectivity.filter(
// (d) => d["title_id"] == obj.title_id
// )[0].connectivity;
// connected_ids = connected_ids == "" ? null : connected_ids.split(",");
// return { ...obj, connectivity: connected_ids };
// });
// //sort so titles with connectivity all first
// return titles_addConnectivityArray.sort((a, b) => (b.connectivity ? 1 : -1));
// }

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more