Public
Edited
Nov 5, 2022
Insert cell
Insert cell
Insert cell
Insert cell
viewof csvfile = Inputs.file({label: "Upload the .csv file", accept: ".csv", required: true})
Insert cell
data= csvfile.csv({typed: true})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart4 = BarChart(dataBarChart3, {
x: d => d.date_range_to_trend,
y: d => d.no_of_videos,
xDomain: dataBarChart2.date_range_to_trend, // sort by descending frequency
yLabel: "↑ No of Days to Trend for category: " + desiredCategory,
width: 500,
height: 500,
color: "rgb(108,99,255)"
})
Insert cell
data_title = data.filter(i=>i.view_count != 0).map(i => {const viewdata = {
categories: i.category,
net_popularity_per_view: (i.likes - i.dislikes)/i.view_count,
sentiment_scores:i["Sentiment Scores"]
}
return viewdata})
Insert cell
data_view= data.map(i => {const viewdata = {
video:i.video_id,
category:i.category,
published_week:String(i.publishedAt).split(" ")[0],
published_month:String(i.publishedAt).split(" ")[1]+(String(i.publishedAt).split(" ")[3]).substring(2),
views:i.view_count,
likes:i.likes,
dislikes:i.dislikes
}
return viewdata})
Insert cell
month_year_array = Array.from((d4.rollup(data_view,
v => Object.fromEntries(columnsToSum2.map(col => [col, d3.sum(v, d => d[col])])),
d => d.category,d => d.published_month)), ([categories, counts]) => {
const result={}
result.category = categories;
result.week= Array.from(counts, ([month_year, metrics]) => ({ month_year, likes:metrics.likes, dislikes:metrics.dislikes}));
// result.week = Array.from(counts.values());
// result.week.day= Array.from(counts.keys());
return result;
}).sort((a, b) => d3.ascending(a.category, b.category))
Insert cell
columnsToSum2= Object.keys(data_view[0]).slice(5)
Insert cell
columnsToSum=Object.keys(data_title[0]).slice(1)
Insert cell
week_array = Array.from((d4.rollup(data_view,
v => v.length,
d => d.category,d => d.published_week)), ([categories, counts]) => {
const result={}
result.category = categories;
result.week= Array.from(counts, ([day, no_of_videos]) => ({ day, no_of_videos})).sort((a, b) => d3.ascending(a.day, b.day));
// result.week = Array.from(counts.values());
// result.week.day= Array.from(counts.keys());
return result;
}).sort((a, b) => d4.ascending(a.category, b.category))
Insert cell
days_to_trend = (data.filter(i=>(i.days_to_trend>=0 && i.days_to_trend<=1)).map(i=> ({date_range:"0-1",video_id:i.video_id,category:i.category}))).concat(data.filter(i=>(i.days_to_trend>=2 && i.days_to_trend<=3)).map(i=> ({date_range:"2-3",video_id:i.video_id,category:i.category}))).concat(data.filter(i=>(i.days_to_trend>=4 && i.days_to_trend<=5)).map(i=> ({date_range:"4-5",video_id:i.video_id,category:i.category}))).concat(data.filter(i=>(i.days_to_trend>=6 && i.days_to_trend<=7)).map(i=> ({date_range:"6-7",video_id:i.video_id,category:i.category}))).concat(data.filter(i=>(i.days_to_trend>=8 && i.days_to_trend<=9)).map(i=> ({date_range:"8-9",video_id:i.video_id,category:i.category}))).concat(data.filter(i=>(i.days_to_trend>=10 && i.days_to_trend<=11)).map(i=> ({date_range:"10-11",video_id:i.video_id,category:i.category}))).concat(data.filter(i=>(i.days_to_trend>=12)).map(i=> ({date_range:">=12",video_id:i.video_id,category:i.category})))
Insert cell
days_to_trend_array= Array.from((d4.rollup(days_to_trend,
v => v.length,
d => d.category,d => d.date_range)), ([categories, counts]) => {
const result={}
result.category = categories;
result.week= Array.from(counts, ([date_range_to_trend, no_of_videos]) => ({ date_range_to_trend, no_of_videos}));
// result.week = Array.from(counts.values());
// result.week.day= Array.from(counts.keys());
return result;
}).sort((a, b) => d4.ascending(a.category, b.category))
Insert cell
viewsTotalByCategory = d4.rollup(
data,
v => v.length, //Aggregate by the sum of amount
d => d.category, // group first by name
)
Insert cell
r1=Array.from(viewsTotalByCategory, ([categories, counts]) => {
// result.week = Array.from(counts.values());
// result.week.day= Array.from(counts.keys());
return categories;
})
Insert cell
r2=Array.from(viewsTotalByCategory, ([categories, counts]) => {
// result.week = Array.from(counts.values());
// result.week.day= Array.from(counts.keys());
return counts;
})
Insert cell
viewCountByCategories={const result = {};
for (let index = 0; index < r1.length; ++index) {
result[r1[index]] = r2[index];
}
return result
}

Insert cell
mutable desiredCategory="Music"
Insert cell
arc = d3
.arc()
.innerRadius(0)
.outerRadius(radius)
Insert cell
colorSeq = d3
.scaleSequential()
.domain([0, pieData.length])
.interpolator(d3.interpolateRainbow)
Insert cell
pieData = pie(d3.entries(viewCountByCategories))
Insert cell
pie = d3.pie().value(d => d.value)
Insert cell
labelHeight = 18
Insert cell
radius = Math.min(width, height) / 2
Insert cell
height = 600
Insert cell
width = 1000
Insert cell
d3 = require('d3@5')
Insert cell
d4 = require('d3@6')
Insert cell
// viewCountByCategories = ({
// "People & Blogs": 23564302112,
// "Gaming": 54750035135,
// "Entertainment": 93598356822,
// "Music": 116005517783,
// "Howto & Style": 5972008785,
// "Education": 5830220951,
// "Comedy": 13228148948,
// "Science & Technology": 12467350593,
// "Film & Animation": 13261237595,
// "News & Politics": 13882407684,
// "Sports": 32596429958,
// "Travel & Events": 772899470,
// "Pets & Animals": 808260981,
// "Autos & Vehicles": 2678453316,
// "Nonprofits & Activism": 276680435
// })

Insert cell
function zoom(svg) {
const extent = [[margin.left, margin.top], [width - margin.right, height - margin.top]];

svg.call(d3.zoom()
.scaleExtent([1, 8])
.translateExtent(extent)
.extent(extent)
.on("zoom", zoomed));

function zoomed(event) {
x0.range([margin.left, width - margin.right].map(d => event.transform.applyX(d)));
svg.selectAll("rect").data(data.dat)
.attr("x", d => x0(d[groupKey])).attr("width", x0.bandwidth())
// .attr("transform", d => `translate(${x0(d[groupKey])},0)`)
.data(d => keys.map(key => ({key, value: d[key]}))).selectAll("rect")
.attr("x", d => x1(d.key)).attr("width", x1.bandwidth());
svg.selectAll(".x-axis").call(xAxis);
}
}
Insert cell
wrap = (text) => {
const width=50
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (words.length >0) {
word=words.pop()
line.push(word);
tspan.text(line.join(" "));
// if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y-10).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
// }
}
});
}
Insert cell
legend = svg => {
const g = svg
.attr("transform", `translate(${width-legendDistanceFromRight},${margin.top})`)
.attr("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", legendTextSize)
.selectAll("g")
.data(color.domain().slice().reverse())
.join("g")
.attr("transform", (d, i) => `translate(0,${i * 20})`);

g.append("rect")
.attr("x", -19)
.attr("width", 19)
.attr("height", 19)
.attr("fill", color);

g.append("text")
.attr("x", -24)
.attr("y", 9.5)
.attr("dy", "0.35em")
.text(d => d);
}
Insert cell
x0 = d3.scaleBand()
.domain(dataNew.dat.map(d => d[groupKey]))
.rangeRound([margin.left, width - margin.right])
.paddingInner(0.15)
Insert cell
x1 = d3.scaleBand()
.domain(keys)
.rangeRound([0, x0.bandwidth()])
.padding(0.05)
Insert cell
y = d3.scaleLinear()
.domain([0, d3.max(dataNew.dat, d => d3.max(keys, key => d[key]))]).nice()
.rangeRound([height - margin.bottom, margin.top])
Insert cell
legendDistanceFromRight = 20
Insert cell
color = d3.scaleOrdinal(d3.quantize(colorType, keys.length))
Insert cell
colorType = d3.interpolate("rgb(148, 220, 121)", "red")
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x0).tickSizeOuter(0))
.attr("font-size", xAxisFontSize)
.selectAll("text").call(wrap, x0.bandwidth())
.call(g => g.select(".domain").remove())
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).ticks(null, "s"))
.call(g => g.select(".domain").remove())
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", -10)
.attr("y", -20)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text(dataNew.y))
Insert cell
groupKey = dataNew.columns[0]
Insert cell
margin = ({top: 90, right: 120, bottom: 50, left: 40})
Insert cell
xAxisFontSize = 9
Insert cell
titleSize = 20
Insert cell
legendTextSize = 12
Insert cell
tooltipSize = 12
Insert cell
titleText = "Likes vs Dislikes over time for Category: " + desiredCategory
Insert cell
yAxisText = "Score"
Insert cell
keys = Object.keys(dataModified[0]).slice(1)
Insert cell
dataModified = (month_year_array.filter(i=>i.category == desiredCategory).map(i=>i.week))[0]
Insert cell
dataNew = (
{
"dat": dataModified,
"columns": ["month_year", "likes", "dislikes"],
"y": yAxisText
}
)
Insert cell
// Copyright 2021 Observable, Inc.
// Released under the ISC license.
// https://observablehq.com/@d3/bar-chart
function BarChart(data, {
x = (d, i) => i, // given d in data, returns the (ordinal) x-value
y = d => d, // given d in data, returns the (quantitative) y-value
title, // given d in data, returns the title text
marginTop = 20, // the top margin, in pixels
marginRight = 0, // the right margin, in pixels
marginBottom = 30, // the bottom margin, in pixels
marginLeft = 40, // the left margin, in pixels
width = 640, // the outer width of the chart, in pixels
height = 400, // the outer height of the chart, in pixels
xDomain, // an array of (ordinal) x-values
xRange = [marginLeft, width - marginRight], // [left, right]
yType = d4.scaleLinear, // y-scale type
yDomain, // [ymin, ymax]
yRange = [height - marginBottom, marginTop], // [bottom, top]
xPadding = 0.1, // amount of x-range to reserve to separate bars
yFormat, // a format specifier string for the y-axis
yLabel, // a label for the y-axis
color = "currentColor" // bar fill color
} = {}) {
// Compute values.
const X = d4.map(data, x);
const Y = d4.map(data, y);

// Compute default domains, and unique the x-domain.
if (xDomain === undefined) xDomain = X;
if (yDomain === undefined) yDomain = [0, d3.max(Y)];
xDomain = new d4.InternSet(xDomain);

// Omit any data not present in the x-domain.
const I = d4.range(X.length).filter(i => xDomain.has(X[i]));

// Construct scales, axes, and formats.
const xScale = d4.scaleBand(xDomain, xRange).padding(xPadding);
const yScale = yType(yDomain, yRange);
const xAxis = d4.axisBottom(xScale).tickSizeOuter(0);
const yAxis = d4.axisLeft(yScale).ticks(height / 40, yFormat);

// Compute titles.
if (title === undefined) {
const formatValue = yScale.tickFormat(100, yFormat);
title = i => `${X[i]}\n${formatValue(Y[i])}`;
} else {
const O = d4.map(data, d => d);
const T = title;
title = i => T(O[i], i, data);
}

const svg = d4.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto; height: intrinsic;");

svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(yAxis)
.call(g => g.select(".domain").remove())
.call(g => g.selectAll(".tick line").clone()
.attr("x2", width - marginLeft - marginRight)
.attr("stroke-opacity", 0.1))
.call(g => g.append("text")
.attr("x", -marginLeft)
.attr("y", 10)
.attr("fill", "currentColor")
.attr("text-anchor", "start")
.text(yLabel));

const bar = svg.append("g")
.attr("fill", color)
.selectAll("rect")
.data(I)
.join("rect")
.attr("x", i => xScale(X[i]))
.attr("y", i => yScale(Y[i]))
.attr("height", i => yScale(0) - yScale(Y[i]))
.attr("width", xScale.bandwidth());

if (title) bar.append("title")
.text(title);

svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(xAxis);

return svg.node();
}
Insert cell
map1={const map = {
'Mon': 2,'Tue': 3,'Wed': 4,'Thu': 5,'Fri': 6,'Sat': 7,
'Sun': 1
};
return map}
Insert cell
dataBarChart4 = (week_array.filter(i=>i.category == desiredCategory).map(i=>i.week))[0]
Insert cell
dataBarChart2= dataBarChart4.sort((a, b) => {
return map1[a.day] - map1[b.day];
});
Insert cell
import {howto, altplot} from "@d3/example-components"
Insert cell
import {Legend, Swatches} from "@d3/color-legend"
Insert cell
import {howto, altplot} from "@d3/example-components"
Insert cell
dataBarChart3 = (days_to_trend_array.filter(i=>i.category == desiredCategory).map(i=>i.week))[0]
Insert cell
mutable hoverCategory = "Music"
Insert cell
textPieChart1 = "Category:" + hoverCategory
Insert cell
textPieChart2 = "; No of Videos: " + viewCountByCategories[hoverCategory];
Insert cell
mutable colorTemp = "";
Insert cell
onMouseOut = function(d, i) {
d3.select(this).attr('style', 'fill: colorTemp')
d3.select(this).style("cursor", "default");
}
Insert cell
onMouseOver = function(d, i) {
mutable colorTemp = colorSeq_D2(d.index);
d3.select(this).attr('style', 'fill: pink;');
mutable hoverCategory = d.data.key
d3.select(this).style("cursor", "pointer");
// d3.select("#toptext").text(`Category: ${i.category}`);
// d3.select("#toptext").text(`No Of Videos: ${viewCountByCategories[hoverCategory]}`);
}
Insert cell
// {
// const svg = d3
// .create('svg')
// .attr('width', width)
// .attr('height', height);
// const chart = svg
// .append('g')
// .attr('transform', `translate(${radius},${radius})`);

// const text = svg
// .append('text')
// .attr("id", 'toptext')
// .attr("x", width - 450)
// .attr("y", 550)
// .attr("dx", "-.8em")
// .attr("dy", ".15em")
// .attr("font-family", "sans-serif")
// //.text(textPieChart1 + textPieChart2);

// chart
// .selectAll(null)
// .data(pieData)
// .enter()
// .append('path')
// .attr('d', arc)
// .attr('fill', d => colorSeq(d.index))
// .attr('stroke', 'grey')
// .style('stroke-width', '1px')
// .on('mouseover', onMouseOver)
// .on('mouseout', onMouseOut)
// // .on('mouseover', (event , r) => {
// // mutable hoverCategory = event.data.key;
// // })
// .on('click', (event , r) => {
// mutable desiredCategory = event.data.key;
// //mutable desiredCategory = hoverCategory;
// });

// const legend = svg
// .append('g')
// .attr('transform', `translate(${radius * 2 + 20},0)`);

// legend
// .selectAll(null)
// .data(pieData)
// .enter()
// .append('rect')
// .attr('y', d => labelHeight * d.index * 1.8)
// .attr('width', labelHeight)
// .attr('height', labelHeight)
// .attr('fill', d => colorSeq(d.index))
// .attr('stroke', 'grey')
// .style('stroke-width', '1px');

// legend
// .selectAll(null)
// .data(pieData)
// .enter()
// .append('text')
// .text(d => d.data.key)
// .attr('x', labelHeight * 1.1)
// .attr('y', d => labelHeight * d.index * 1.8 + labelHeight)
// .style('font-family', 'sans-serif')
// .style('font-size', `${labelHeight}px`);

// return svg.node();
// }
Insert cell
// chart1 = {
// const svg = d3.select(DOM.svg(width, height));
// svg.append('text')
// .attr('class', 'title')
// .text(titleText)
// .attr('y', 15)
// .attr('x', width/3)
// .attr('font-size', titleSize);

// var bars = svg.append("g")
// .selectAll("g")
// .data(dataNew.dat);
// bars
// .join("g")
// .attr("transform", d => `translate(${x0(d[groupKey])},0)`)
// .selectAll("rect")
// .data(d => keys.map(key => ({key, value: d[key]})))
// .join("rect")
// .attr("x", d => x1(d.key))
// .attr("y", d => d.value ? y(d.value) : margin.top)
// .attr("width", x1.bandwidth())
// .attr("height", d => d.value ? y(0) - y(d.value) : height - margin.bottom - margin.top)
// .attr("fill", d => d.value ? color(d.key) : 'transparent')
// // .on("mouseenter", function(d) {
// // svg.append("text").attr("class", "tool")
// // .attr("x", x0(d.path[1].__data__[groupKey]) + x1(d.path[0].__data__.key))
// // // .attr("y", y(d.path[0].__data__.value)-25)
// // .attr("y", margin.top - 50)
// // .style("display", null)
// // // .style("fill", color(d.path[0].__data__.key))
// // .style("fill", 'black')
// // .text("Catergory: " + d.path[0].__data__.key.charAt(0).toUpperCase() + d.path[0].__data__.key.slice(1))
// // .attr('font-size', tooltipSize)
// // svg.append("text").attr("class", "tool1")
// // .attr("x", x0(d.path[1].__data__[groupKey]) + x1(d.path[0].__data__.key))
// // // .attr("y", y(d.path[0].__data__.value)-10)
// // .attr("y", margin.top - 35)
// // .style("display", null)
// // // .style("fill", color(d.path[0].__data__.key))
// // .style("fill", 'black')
// // .text("Score: " + Number(d.path[0].__data__.value).toFixed(2))
// // .attr('font-size', tooltipSize)
// // })
// // .on("mouseout", function(d) {
// // svg.selectAll("text.tool").style("display", "none")
// // svg.selectAll("text.tool1").style("display", "none")
// // });

// svg.append("g")
// .attr("class", "x-axis")
// .call(xAxis);

// svg.append("g")
// .call(yAxis);

// svg.append("g")
// .call(legend);
// svg.node().scrollBy(5, 0);

// return svg.node();
// }
Insert cell
// chart3 = BarChart(dataBarChart2, {
// x: d => d.day,
// y: d => d.no_of_videos,
// xDomain: dataBarChart2.day, // sort by descending frequency
// yLabel: "↑ No of Videos vs Publishing Data for category: " + desiredCategory,
// width: 500,
// height: 500,
// color: "#3288bd"
// })
Insert cell
// chart4 = BarChart(dataBarChart3, {
// x: d => d.date_range_to_trend,
// y: d => d.no_of_videos,
// xDomain: dataBarChart2.date_range_to_trend, // sort by descending frequency
// yLabel: "↑ No of Days to Trend for category: " + desiredCategory,
// width: 500,
// height: 500,
// color: "rgb(108,99,255)"
// })
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