You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
2.8 KiB

// TODO - delete highlighted
// TODO - different colors for each highted dot, matched in table row backgrounds
const WIDTH = 800;
const HEIGHT = 600;
const parseTime = d3.timeParse("%B %e, %Y");
let instances;
let xScale, yScale;
let highlighted = 0;
const renderTable = () => {
const trs = d3.select('tbody')
.selectAll('tr')
.data(instances.filter(d => d.highlighted > 0).sort((a,b) => a.highlighted - b.highlighted), d => d.id)
.enter()
.append('tr')
//.exit()
//.remove()
.selectAll('td')
.data(d => [
d.instance_id,
d.course,
d.graduation_date,
d.total_students,
`${d.dropped} (${Math.floor(d.dropped/d.total_students*100)}%)`,
d.graduates,
`${d.ninety_day_outcomes} (${Math.floor(d.ninety_day_outcomes/d.graduates*100)}%)`
])
.enter()
.append('td')
.text(value => value)
}
const renderPoints = () => {
const circles = d3.select('#points')
.selectAll('circle')
.data(instances, d => d.id)
.enter()
.append('circle');
d3.selectAll('circle')
.attr('cy', (datum, index) => yScale(datum.ninety_day_outcomes/datum.graduates*100) );
d3.selectAll('circle')
.attr('cx', (datum, index) => xScale(parseTime(datum.graduation_date)) );
d3.selectAll('circle')
.classed('highlighted', (datum, index)=> datum.highlighted > 0 )
d3.selectAll('circle').on('click', (event, datum) => {
if(datum.highlighted === 0){
datum.highlighted = ++highlighted;
} else {
datum.highlighted = 0;
}
renderPoints()
renderTable()
});
}
const setupGraph = ()=>{
d3.select('svg');
d3.select('svg')
.style('width', WIDTH)
.style('height', HEIGHT);
xScale = d3.scaleTime();
xScale.range([0,WIDTH]);
const xDomain = d3.extent(instances, (datum, index) => {
return parseTime(datum.graduation_date);
});
xScale.domain(xDomain);
yScale = d3.scaleLinear();
yScale.range([HEIGHT, 0]);
const yDomain = d3.extent(instances, (datum, index) => {
return datum.ninety_day_outcomes/datum.graduates*100;
})
yScale.domain(yDomain);
}
const createAxes = () => {
const bottomAxis = d3.axisBottom(xScale);
d3.select('#container')
.append('g')
.attr('id', 'x-axis')
.call(bottomAxis)
.attr('transform', 'translate(0,'+HEIGHT+')');
const leftAxis = d3.axisLeft(yScale);
d3.select('#container')
.append('g')
.attr('id', 'y-axis')
.call(leftAxis);
}
const createFormSubmissionHandler = () => {
d3.select('form').on('submit', (event)=>{
event.preventDefault();
const instanceID = parseInt(d3.select('input[type="text"]').property('value'))
const found = instances.find(i => i.instance_id === instanceID)
found.highlighted = ++highlighted;
renderTable();
renderPoints();
});
}
window.onload = async ()=>{
instances = await d3.json('/instances');
instances.forEach(instance => instance.highlighted = highlighted)
setupGraph();
createAxes();
renderPoints();
createFormSubmissionHandler();
}