Published
Edited
Dec 14, 2020
Importers
Insert cell
md`# Final Deliverable - Draft`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof select_axis = html`<select>
<option>Points per game
<option>Height
</select>`
Insert cell
viewof choose_team = select({
options: _.uniqBy(formatted_data.map(d => d.team).sort(d3.ascending))
})
Insert cell
scatter_avg = {
const svg = d3
.create("svg")
.attr("viewBox", [0, 0, measurements1.width, measurements1.height + 50]);

const tip = svg.append("g").style("pointer-events", "none");
const tipRect = tip.append("rect");
const tipText = tip.append("text").style("text-anchor", "middle");

svg.append("g").call(xAxis3);

if (select_axis == "Points per game") {
svg.append("g").call(yAxis3);
} else {
svg.append("g").call(yAxis4);
}

svg
.append("text")
.attr("class", "x label")
.attr("text-anchor", "middle")
.attr("x", width / 2)
.attr("y", measurements1.height + 30)
.text("Year");

svg
.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.attr("x", -measurements1.height / 2.75)
.attr("y", 15)
.attr("transform", "rotate(-90)")
.text(select_axis);

if (select_axis == "Points per game") {
svg
.selectAll("circle")
.data(chosen_data2)
.join(enter => enter.append("circle"))
.attr("r", 5)
.attr("cx", d => xScale(d.Year))
.attr("cy", d => yScale1(d.PER))
.attr("fill", '#32a852')
.attr("id", "select")
.attr("opacity", d => 0.5);
} else {
svg
.selectAll("circle")
.data(chosen_data2)
.join(enter => enter.append("circle"))
.attr("r", 5)
.attr("cx", d => xScale(d.Year))
.attr("cy", d => yScale2(d.height))
.attr("fill", 'blue')
.attr("id", "select")
.attr("opacity", d => 0.1);
}

return svg.node();
}
Insert cell
md` By utilizing the select feature users can choose whether to see the height or points per game from the years 2010-2015. By incorporating this, the user can see the relation between the height or points per game over the years. We realized that height and points per game is incrasing over the years.`
Insert cell
Insert cell
// Select metric to visualize in the treemap
viewof metric = select({
title: "Metric for visualization",

options: [
{ label: "height", value: "height" },
{ label: "average points per game", value: "per" }
]
})
Insert cell
biglinechart = {
const svg = d3.create("svg").attr("viewBox", [-80, -40, width + 80, 600]);
svg
.append("text")
.attr(
"transform",
`translate(${measurements.marginLeft +
(line_x.range()[1] - line_x.range()[0]) / 2},${550})`
)
.style("text-anchor", "middle")
.text("Averages throughout 2010-2015");
svg.node().update = game => {
svg.selectAll("*").remove();

const gx = svg
.append("g")
.call(linexAxis)
.attr("transform", `translate(0, ${500 - measurements.marginBottom})`);

const dataWithTime = [...summedLineData];
for (let i = 0; i < dataWithTime.length; i++) {
dataWithTime[i].time = formatutc(dataWithTime[i].yrs);
}

const line_x = d3
.scaleTime()
.domain([
d3.min(dataWithTime, d => d.time),
d3.max(dataWithTime, d => d.time)
])
.range([measurements.marginLeft, width - measurements.marginRight]);

// console.log(line_x(dataWithTime[0].time));

const line_y = d3
.scaleBand()
.domain(dataWithTime.map(d => d[game]))
.range([500 - measurements.marginBottom, measurements.marginTop])
.padding(0.1)
.round(true);

console.log(line_y(dataWithTime[0][game]));

const lineyAxis = (g, scale = line_y) =>
g
.attr("transform", `translate(${measurements.marginLeft},0)`)
.call(d3.axisLeft(scale).ticks(500));

const gy = svg.append("g").call(lineyAxis);

const line = d3
.line()
// .defined(d => !isNaN(d[game]))
.x(d => line_x(d.time))
.y(d => line_y(d[game]));

svg
.append("path")
.datum(dataWithTime)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 0.5)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("d", line)
.call(transition);
};
return svg.node();
}
Insert cell
md`By utilizing the select feature users can choose whether to see the average height or points per game from the years 2010-2015. However, one could see that there is not a relation between the average heigh and points per game. The average points per game jumps up and down throughout the years while the average height shows an upward trend throughout the years. Therefore, from the data we collected and analyzed above, once again the relationship of points per game and height isn't clear enough to make a conclusion, for that we can say that there isn't a relationship between height and points per game`
Insert cell
biglinechart.update(metric)
Insert cell
Insert cell
Insert cell
Insert cell
chosen_data2 = {
const temp_data2 = filtered_data.filter(d => d.Tm == choose_team);
const result_data = temp_data2.map(d => {
return {
age: d["Age"],
player: d["Player"],
team: d["Tm"],
Year: +d["Year"],
PER: +d["PER"],
height: +d["Height"]
};
});
return result_data;
}
Insert cell
Insert cell
y = d3
.scaleLinear()
.domain([0, d3.max(chosen_data, d => d.height)])
.range([measurements.height, measurements.marginBottom])
Insert cell
d3.max(chosen_data, d => d.height)
Insert cell
xAxis = (g, x) =>
g
.attr(
"transform",
`translate(${measurements.marginLeft},${measurements.height -
measurements.marginBottom})`
)
.call(d3.axisBottom(x).ticks(12))
.call(g => g.select(".domain").attr("display", "none"))
Insert cell
yAxis = (g, y) =>
g
.attr(
"transform",
`translate(${2 * measurements.marginLeft}, ${-measurements.marginBottom})`
)
.call(
d3.axisLeft(
d3
.scaleLinear()
.domain([0, d3.max(chosen_data, d => d.height)])
.range([measurements.height, measurements.marginBottom])
)
)
.call(g => g.select(".domain").attr("display", "none"))
Insert cell
Insert cell
Insert cell
minX = d3.min(chosen_data2, d => d.Year)
Insert cell
maxX = d3.max(chosen_data2, d => d.Year)
Insert cell
minY1 = d3.min(chosen_data2, d => d.PER)
Insert cell
maxY1 = d3.max(chosen_data2, d => d.PER)
Insert cell
minY2 = d3.min(chosen_data2, d => d.height)
Insert cell
maxY2 = d3.max(chosen_data2, d => d.height)
Insert cell
xScale = d3
.scaleLinear()
.domain([minX - 1, maxX + 1])
.range([measurements1.marginLeft, width + measurements1.marginRight])
Insert cell
xAxis3 = g =>
g
.attr(
"transform",
`translate(0,${measurements1.height - measurements1.marginBottom})`
)
.call(d3.axisBottom(xScale).ticks(maxX - minX))
Insert cell
yScale1 = d3
.scaleLinear()
.domain([minY1, maxY1 + 1])
.range([measurements1.height, measurements1.marginBottom])
Insert cell
yAxis3 = g =>
g
.attr("transform", `translate(${measurements1.marginLeft},0)`)
.call(d3.axisLeft(yScale1))
Insert cell
yScale2 = d3
.scaleLinear()
.domain([minY2, maxY2 + 1])
.range([measurements1.height, measurements1.marginBottom])
Insert cell
yAxis4 = g =>
g
.attr("transform", `translate(${measurements1.marginLeft},0)`)
.call(d3.axisLeft(yScale2))
Insert cell
formatutc = d3.timeParse("%Y")
Insert cell
line_chart_data = data.map(d => {
return {
year: d["Year"],
x: +d["PER"],
y: +d["Weight"],
age: +d["Age"],
height: +d["Height"]
};
})
Insert cell
line_chart_data1 = line_chart_data
.filter(d => d.year > 2010)
.filter(d => d.year < 2016)
.sort((a, b) => b.year - a.year)
Insert cell
d3_ = require("d3-array@2")
Insert cell
line_yrs = d3_.rollups(
line_chart_data1,
v => d3_.mean(v, d => d.height),
d => d.year
)
Insert cell
lines_yrs2 = d3_.rollups(
line_chart_data1,
v => d3_.mean(v, d => d.x),
d => d.year
)
Insert cell
line_y2 = d3
.scaleBand()
.domain(lines_yrs2.map(d => d[1]))
.range([measurements.marginTop, 500 - measurements.marginBottom])
.padding(0.1)
.round(true)
Insert cell
line_x = d3
.scaleTime()
.domain([
d3.min(line_yrs.map(d => formatutc(d[0]))),
d3.max(line_yrs.map(d => formatutc(d[0])))
])
.range([measurements.marginLeft, width - measurements.marginRight])
Insert cell
linexAxis = d3
.axisBottom()
.scale(line_x)
.ticks(5)
Insert cell
summedLineData = {
let arr = [];
for (let i = 0; i < line_yrs.length; i++) {
const summedData = {};
summedData.yrs = line_yrs[i][0];
summedData.height = line_yrs[i][1];
summedData.per = lines_yrs2[i][1];
arr.push(summedData);
}
return arr;
}
Insert cell
function transition(path) {
path
.transition()
.duration(7500)
.attrTween("stroke-dasharray", tweenDash)
.on("start", () => {
d3.select(this).call(transition);
});
}
Insert cell
function tweenDash() {
const l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
return function(t) {
return i(t);
};
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
measurements1 = {
return {
width: width,
height: 700,
marginLeft: 60,
marginRight: 50,
marginTop: 100,
marginBottom: 0
};
}
Insert cell
Insert cell
Insert cell
Insert cell
lodash = require('lodash')
Insert cell
Insert cell
filters
Insert cell
import { chart_grouping, filters } with {
group
} from "@travisle/final-project-charts-le"
Insert cell
import { callout } from "@d3/line-chart-with-tooltip"
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