Public
Edited
Mar 28, 2023
Insert cell
Insert cell
Insert cell
Insert cell
dogZip = FileAttachment("AK_before_after_merged_filtered.zip").zip()
Insert cell
fileNames = dogZip.filenames
Insert cell
parser = d3.timeParse("%Y%m%d")
Insert cell
readMe = dogZip.file("AK_before_after_merged_filtered.csv").text()
Insert cell
Insert cell
n_articles_data_orig = d3.csvParse(await readMe, function(d) {
return {
MonthYear: parser(d.SQLDATE),
NumArticles: d.NumArticles,
Period: d.Period
};
});
Insert cell
n_articles_data_test = n_articles_data_orig.slice(0,10)
Insert cell
n_articles_data_roll = d3.rollup(n_articles_data_orig, v => d3.sum(v, d => d.NumArticles), d => d.MonthYear)
Insert cell
function unroll(rollup, keys, label = "value", p = {}) {
return Array.from(rollup, ([key, value]) =>
value instanceof Map
? unroll(value, keys.slice(1), label, Object.assign({}, { ...p, [keys[0]]: key } ))
: Object.assign({}, { ...p, [keys[0]]: key, [label] : value })
).flat();
}
Insert cell
n_articles_data = unroll(n_articles_data_roll, "MonthYear", "NumArticles")
Insert cell
viewof NumArticles = vl.markLine()
//.data(marketCap)
.data(n_articles_data)
.encode(
vl.y().fieldQ("NumArticles"),
vl.x().fieldT("M"))
.width(900)
.height(500)
.render()
Insert cell
Insert cell
parser_monthly = d3.timeParse("%Y%m")
Insert cell
avgTone_data_orig = d3.csvParse(await readMe, function(d) {
return {
MonthYear: parser_monthly(d.MonthYear), //parser(d.SQLDATE)
AvgTone: d.AvgTone
};
});
Insert cell
avgTone_data_roll = d3.rollup(avgTone_data_orig, v => d3.extent(v, d => d.AvgTone), d => d.MonthYear)
Insert cell
avgTones_data = unroll(avgTone_data_roll, "MonthYear", "Tone")
Insert cell
viewof avgTone = vl.markLine()
//.data(marketCap)
.data(avgTones_data)
.encode(
vl.y().fieldQ("Tone"),
vl.x().fieldT("M"))
.width(900)
.height(500)
.render()
Insert cell
avgTone_data_roll1 = d3.rollup(avgTone_data_orig, v => d3.mean(v, d => d.AvgTone), d => d.MonthYear)
Insert cell
avgTones_data1 = unroll(avgTone_data_roll1, "MonthYear", "AvgTone")
Insert cell
viewof avgTone1 = vl.markLine()
//.data(marketCap)
.data(avgTones_data1)
.encode(
vl.y().fieldQ("AvgTone"),
vl.x().fieldT("M"))
.width(900)
.height(500)
.render()
Insert cell
Insert cell
avgTone_data_orig
Insert cell
avgTone_data_min_max_roll = d3.rollup(avgTone_data_orig, v => d3.extent(v, d => d.AvgTone), d => d.MonthYear)
Insert cell
Plot.plot({
y: {
grid: false,
label: "Average house prices(£)",
type: logScale1 ? "log" : "linear"
},
x: { label: "Month", grid: true },
marks: [
Plot.areaY(
avgTone_data_orig,
Plot.groupX(
{ y1: "min", y2: "max" },
{ x: "MonthYear", y: "AvgTone", fill: "steelblue", opacity: 0.2 }
)
),
Plot.lineY(
avgTone_data_orig,
Plot.groupX(
{ y: "median" },
{
sort: "MonthYear",
x: "MonthYear",
y: "AvgTone"
}
)
)
],
height: 400,
marginLeft
})
Insert cell
viewof logScale1 = Inputs.toggle({ label: "Use log scale", value: true })
Insert cell
marginLeft = 60
Insert cell
Insert cell
data_orig = d3.csvParse(await readMe, function(d) {
return {
MonthYear: parser(d.SQLDATE),
Actor1Code: d.Actor1Code,
Actor1CountryCode: d.Actor1CountryCode,
AvgTone: d.AvgTone
};
});
Insert cell
data_orig_test = data_orig.slice(0,10)
Insert cell
data_orig_roll = d3.rollup(data_orig, v => v.length, d => d.Actor1Code)
Insert cell
all_data = unroll(data_orig_roll, "Actor1Code")
Insert cell
filter_null = (arry) => {
var results = arry.filter(obj => obj.A != "");
return results
};
Insert cell
all_data_sorted = z.sortByCol('value', 'des', filter_null(all_data))
Insert cell
top_5 = {
let array = []
for (let a in all_data_sorted.slice(0,3))
{
array.push(all_data_sorted.slice(0,3)[a]["A"])
}
return array
}

Insert cell
top5_set = new Set(top_5);

Insert cell
data_orig_filtered = data_orig.filter(d => top5_set.has(d.Actor1Code))
Insert cell
data_orig_filtered_roll = d3.rollup(data_orig_filtered, v => d3.median(v, d => d.AvgTone), d => d.Actor1Code, d => d.MonthYear)
Insert cell
chart_data = unroll(data_orig_filtered_roll, ["Actor1Code","MonthYear","AvgTone"])
Insert cell
chart = {
// The selection
const hover = vl.selectSingle("hover")
.on("mouseover")
.encodings("x")
.nearest(true)
.clear("moouseout")
.init({ x: { year: 2014, month: 3, date: 25 } });
// The line and point marks. Notice how we filter the points on hover
const lineAndPoint = vl.layer(
vl.markLine(),
vl.markPoint()
.transform(vl.filter(hover))
).encode(
vl.y().fieldQ("value"),
vl.color().fieldN("Actor1Code")
);
// The rule helps as a proxy for the hover. We draw rules all over the chart
// so we can easily find the nearest one. We then hide them using opacity 0
const rule = vl.markRule({ strokeWidth: 0.5, tooltip: true })
// We pivot the data so we can show all the stock prices at once
.transform(vl.pivot("Actor1Code").value("value").groupby(["MonthYear"]))
.encode(
vl.opacity().value(0).if(hover, vl.value(0.7)),
vl.tooltip([vl.fieldT("MonthYear")])
)
.select(hover);

return vl
.layer(lineAndPoint, rule )
.encode(vl.x().fieldT("MonthYear"))
.data(chart_data)
.width(width - 150)
.height(300)
.render();
}
Insert cell
Insert cell
data_orig_roll1 = d3.rollup(data_orig, v => v.length, d => d.Actor1CountryCode)
Insert cell
all_data1 = unroll(data_orig_roll1, "Actor1Code")
Insert cell
all_data_sorted1 = z.sortByCol('value', 'des', filter_null(all_data1))
Insert cell
top_5_country = {
let array = []
for (let a in all_data_sorted1.slice(0,5))
{
array.push(all_data_sorted1.slice(0,5)[a]["A"])
}
return array
}

Insert cell
top_5_country_set = new Set(top_5_country);

Insert cell
data_orig_filtered1 = data_orig.filter(d => top_5_country_set.has(d.Actor1CountryCode))
Insert cell
data_orig_filtered1_roll = d3.rollup(data_orig_filtered1, v => d3.median(v, d => d.AvgTone), d => d.Actor1CountryCode, d => d.MonthYear)
Insert cell
chart_data1 = unroll(data_orig_filtered1_roll, ["Actor1CountryCode","MonthYear","AvgTone"])
Insert cell
chart2 = {
// The selection
const hover = vl.selectSingle("hover")
.on("mouseover")
.encodings("x")
.nearest(true)
.clear("moouseout")
.init({ x: { year: 2014, month: 3, date: 25 } });
// The line and point marks. Notice how we filter the points on hover
const lineAndPoint = vl.layer(
vl.markLine(),
vl.markPoint()
.transform(vl.filter(hover))
).encode(
vl.y().fieldQ("value"),
vl.color().fieldN("Actor1CountryCode")
);
// The rule helps as a proxy for the hover. We draw rules all over the chart
// so we can easily find the nearest one. We then hide them using opacity 0
const rule =vl.markRule({ strokeWidth: 0.5, tooltip: true })
// We pivot the data so we can show all the stock prices at once
.transform(vl.pivot("Actor1CountryCode").value("value").groupby(["MonthYear"]))
.encode(
vl.opacity().value(0).if(hover, vl.value(0.7)),
vl.tooltip([vl.fieldT("MonthYear")])
)
.select(hover);

return vl
.layer(lineAndPoint, rule )
.encode(vl.x().fieldT("MonthYear"))
.data(chart_data1)
.width(width - 150)
.height(300)
.render();
}
Insert cell
Insert cell
{
const selection = vl.selectPoint("Select") // name the selection 'Cars' (what will happen if we delete 'Cars'?)
.fields('Actor1Code') // limit selection to the Origin field
.init(top_5[0]) // use first genre entry as initial value
.bind(vl.menu(top_5)); // bind to a menu of unique genre values


// Nothing changed below
return vl.markLine()
.data(chart_data)
.params(selection)
.encode(
vl.color().if(selection, vl.value('teal')).value("blue"),
vl.x().fieldT('MonthYear'),
vl.y().fieldQ('value'),
// vl.opacity().if(selection).value(0.1)
)
.width(width - 150)
.height(300)
.render()
}
Insert cell
width = 960
Insert cell
height = 500
Insert cell
margin = ({top: 20, right: 20, bottom: 30, left: 40})
Insert cell
xScale = d3.scaleTime()
.domain(d3.extent(n_articles_data, d => d.M))
.range([margin.left, width - margin.right])
Insert cell
yScale = d3.scaleLinear()
.domain([0, d3.max(n_articles_data, (d) => d.NumArticles)]).nice()
.range([height - margin.bottom, margin.top])
Insert cell
xAxis = (g) => g
.attr('transform', `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xScale))
Insert cell
yAxis = (g) => g
.attr('transform', `translate(${margin.left},0)`)
.call(d3.axisLeft(yScale))
Insert cell
line = d3.line()
.defined(d => !isNaN(d.NumArticles))
.x(d => xScale(d.M))
.y(d => yScale(d.NumArticles))
Insert cell
d3 = require("d3@6")
Insert cell
import {toc} from "@harrystevens/toc"
Insert cell
z = require('https://bundle.run/zebras@0.0.11')
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