What:
Why:
How:
To proper reading of the information in the first instance, the four number firsts in student's code are removed, because have pattern 2800 and it is ordered the code the min to max on x axis, making more easy the lookup.
Moreover, it was decided to use color hue to create better identification in the range of the student's note. I use hue that humans associated with alerts: green-good, yellow-regular and red-bad; thus help to identified the range.
Finally it was decided to separate each student in order to facilitate identification of the student's note relative to the student's code and I use animation to generate expectative.
Marks:
Channels:
xxxxxxxxxx
<meta charset="utf-8">
<title>Transform Transitions</title>
<style>
body {
margin: 0;
}
.axis path,
.axis line{
fill: none;
stroke: black;
}
.line{
fill: none;
stroke: blue;
stroke-width: 2px;
}
path.area {
fill: #E2B2B2;
}
path.line {
fill: none;
stroke: purple;
stroke-width: 1.5;
}
.tick text{
font-size: 12px;
}
.tick line{
opacity: 0.2;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.legend .legend-bg {
fill: rgba(241, 209, 209, 0.5);
stroke: rgba(195, 33, 33, 0.5);
}
.notas, .marker-bg {
fill: rgba(0, 153, 51, 0.8);
stroke: rgba(0, 153, 51, 0.8);
stroke-width: 3;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 100, right: 100, bottom: 50, left: 100},
w = 900 - margin.left - margin.right,
h = 500 - margin.top - margin.bottom,
z = 20,
x = w / z,
y = h / z,
radius = 4,
pos = 100,
posX = 0,
posY = 0;
var xScale, yScale;
var legend ="";
var estudiantes;
var i=0;
d3.json('alumnos.json', function (error, estudiantesData) {
if (error) {
console.error(error);
return;
}
estudiantes = estudiantesData.map(function (d) {
return {
grade: d.grade,
code: d.code,
}
});
var svg = d3.select("body").append("svg")
.attr("height", h + margin.top + margin.bottom)
.attr("width", w + margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
xScale = d3.scale.ordinal().rangeRoundBands([0, w]);
xScale.domain(estudiantes.map(function(d) { return d.code; }));
yScale = d3.scale.linear()
.domain([0, d3.max(estudiantes, function(d){ return d.grade; })])
.range([h, 0]);
var rectClip = svg.append('clipPath')
.attr('id', 'rect-clip')
.append('rect')
.attr('width', 0)
.attr('height', h);
//--------------- ANIMACIONES ---------------//
rectClip.transition()
.duration(250*estudiantes.length)
.attr('width', w);
estudiantes.forEach(function (nota, i) {
setTimeout(function () {
puntos(nota, svg, h, xScale, yScale);
}, 1000 + 500*i);
});
//------------------------------------------//
var legendWidth = 210, legendHeight = 95;
legend = svg.append('g')
.attr('class', 'legend')
.attr('transform', 'translate(' + (w/2 - legendHeight) + ','+ (-legendHeight) +')');
legend.append('rect')
.attr('class', 'legend-bg')
.attr('width', legendWidth)
.attr('height', legendHeight);
legend.append('text')
.attr('x', 5)
.attr('y', 25)
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("font-weight", "bold")
.text('Presione el nodo para mayor información');
// clipping to make sure nothing appears behind legend
svg.append('clipPath')
.attr('id', 'axes-clip')
.append('polygon')
.attr('points', (-margin.left) + ',' + (-margin.top) + ' ' +
(w - legendWidth - 1) + ',' + (-margin.top) + ' ' +
(w - legendWidth - 1) + ',' + legendHeight + ' ' +
(w + margin.right) + ',' + legendHeight + ' ' +
(w + margin.right) + ',' + (h + margin.bottom) + ' ' +
(-margin.left) + ',' + (h + margin.bottom));
//---- PINTA LA LINEA CONTINUAS ----//
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.innerTickSize(-h)
.outerTickSize(0);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.innerTickSize(-w)
.outerTickSize(0)
.tickPadding(10);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis)
.append('text')
.attr('dx', w)
.attr('x', 5)
.attr('y', 5)
.style('font-weight','bold')
.style('','')
.text('Código');
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append('text')
.attr('x',40)
.attr('y', -15)
.attr('dy', '.71em')
.style('text-anchor', 'end')
.style('font-weight','bold')
.text('Calificación');
});
function puntos(nota, svg, h, xScale, yScale) {
var colorF = "rgb(202, 110, 35)",
colorS = "rgb(202, 50, 125)",
xPos = xScale(nota.code)-10,
yPosStart = h,
yPosEnd = yScale(nota.grade);
if(nota.grade >= 5 ){
colorF = "rgb(54, 226, 30)";
colorS = "rgb(29, 150, 44)";
}else if(nota.grade < 5 && nota.grade >= 4){
colorF = "rgb(221, 239, 52";
colorS = "rgb(132, 189, 20)";
}else if(nota.grade < 4 && nota.grade >= 3){
colorF = "rgb(249, 249, 144)";
colorS = "rgb(222, 194, 57)";
}else if(nota.grade < 3 && nota.grade >= 2){
colorS = "rgb(255, 126, 35)";
colorF = "rgb(255, 171, 90)";
}else{
colorS = "rgb(245, 103, 103)";
colorF = "rgb(245, 0, 0)";
}
var circles = svg.append('g')
.attr('class', 'notas')
.style("fill", colorF)
.style("stroke", colorS)
.attr('transform', 'translate(' + xPos + ', ' + yPosStart + ')')
.attr('opacity', 0);
circles.transition()
.duration(200)
.attr('transform', 'translate(' + xPos + ', ' + yPosEnd + ')')
.attr('opacity', 1);
circles.append('path')
.attr('d', 'M' + 24 + ',' + (h-yPosStart) + 'L' + 24 + ',' + (h-yPosStart))
.transition()
.duration(200)
.attr('d', 'M' + 24 + ',' + (h-yPosEnd) + 'L' + 24 + ',' + (radius));
circles.append('circle')
.attr('class', 'marker-bg-'+i++)
.attr('data-grade', nota.grade)
.attr('data-code', nota.code)
.attr('cx', 24)
.attr('cy', 0)
.attr('r', radius)
.attr('transform', 'translate(' + 0 + ', ' + 0 + ')')
.style("cursor", "pointer")
.style("fill", colorF)
.style("stroke", colorS)
.on("click", imprimir);
}
function translate(d) {
return "translate("+posX+","+ posY+")";
}
function imprimir(d) {
var a = this.parentNode.appendChild(this);
posX = d3.transform(d3.select(this).attr("transform")).translate[0];
posY = d3.transform(d3.select(this).attr("transform")).translate[1];
code_aux = d3.select(this).attr("data-code");
grade_aux = d3.select(this).attr("data-grade");
d3.select(this)
.transition()
.duration(750)
.attr("r", radius*2);
d3.select(this)
.transition()
.delay(1000)
.attr("r", radius);
d3.select("#update").remove();
d3.select("#update").remove();
legend.append('text')
.attr('id', 'update')
.attr('x', 50)
.attr('y', 55)
.text("Código: 2800"+code_aux);
legend.append('text')
.attr('id', 'update')
.attr('x', 50)
.attr('y', 75)
.text("Calificación: "+grade_aux);
}
</script>
</body>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js