(function() {
var TBODY_DATA = {
"Harumi": [30, 32],
"Amy": [10, 5],
"Hans": [25, 20],
"Sally": [70, 57],
"Jamal": [20, 35],
"Heather": [35, 45],
"John": [15, 12],
"Keiko": [42, 52],
"Lech": [50, 50],
"Musaf": [55, 60]
};
var THEAD_DATA = [ "Students", "Variable 1", "Variable 2" ];
var GRAPH_OPTIONS = {
WIDTH: 331,
HEIGHT: 331,
TITLES: {
Y: "Variable 2",
X: "Variable 1"
},
BOARD: {
boundingbox: [-10, 75, 75, -10]
},
LINE: {
stroke: "#000",
"stroke-width": 2,
"stroke-dasharray": "5, 5"
},
AXIS: {
stroke: "#000",
"stroke-width": 2,
ticks: {
tickSize: 2,
ticksCount: 7,
drawZero: true,
text: {
"font-size": "16px",
fill: "#000",
offset: {
x: -5,
y: -2
}
}
}
},
TICKS: {
stroke: "#000",
"stroke-width": 2
},
POINT: {
r: 6,
fill: "red"
},
TEXT: {
"font-size": "16px",
fill: "#000"
},
AXIS_TICKS: {
tickSize: 2,
ticksCount: 7,
drawZero: true
},
X_AXIS: {
stroke: "#000",
"stroke-width": 2,
ticks: {
tickSize: 2,
ticksCount: 7,
drawZero: true,
text: {
"font-size": "16px",
fill: "#000",
offset: {
x: -6,
y: -1
}
}
}
},
Y_AXIS: {
stroke: "#000",
"stroke-width": 2,
ticks: {
tickSize: 2,
ticksCount: 7,
drawZero: true,
text: {
"font-size": "16px",
fill: "#000",
offset: {
x: -2,
y: -5
}
}
}
}
};
function LineDrawing(section) {
this.section = section;
this.section.points_possible = 1;
this.section.points_earned = 0;
this.section.section_completed = false;
section.jq.addClass('line_drawing');
this.activityContainer = document.querySelector(".activity");
if ( !this.activityContainer ) {
this.activityContainer = document.createElement("div");
this.activityContainer.className = "activity";
this.section.jq[0].appendChild(this.activityContainer);
}
//дополнительное описание всей активности
this.aria_instruction = this.section.jq.find('.aria-instruction');
$(this.activityContainer).attr({
'aria-label': this.aria_instruction.text(),
'tabindex': 0,
'role': 'application'
});
this.graph = new Graph();
this.table = this._generateTable();
this.activityContainer.appendChild(this.table.node);
this.activityContainer.appendChild(this.graph.node);
_initEvents.call(this);
}
LineDrawing.prototype.finishSlide = function() {
this.section.points_earned = this.section.points_possible;
this.section.section_completed = true;
player.activity.grade_activity();
player.update_section_status();
document.querySelector('.navigation_button.next_button').focus();
};
LineDrawing.prototype._generateTable = function() {
var container, table, thead, tbody, tr, td, i;
var studentsNames = Object.keys(TBODY_DATA);
var trows = [];
container = document.createElement("div");
table = document.createElement("table");
thead = document.createElement("thead");
tbody = document.createElement("tbody");
tr = document.createElement("tr");
container.className = "table";
// Create table head
for (i = 0; i < THEAD_DATA.length; i++) {
td = document.createElement("td");
td.innerHTML = THEAD_DATA[i];
tr.appendChild(td);
}
thead.appendChild(tr);
// Create table body
var student, data, j, aria;
for (i = 0; i < studentsNames.length; i++) {
tr = document.createElement("tr");
td = document.createElement("td");
student = studentsNames[i];
data = TBODY_DATA[student];
aria = student + ". Variable 1: " + data[0] + ". Variable 2: " + data[1] + ".";
td.innerHTML = student;
tr.appendChild(td);
tr.setAttribute("tabindex", "0");
tr.setAttribute("aria-label", aria);
for (j = 0; j < data.length; j++) {
td = document.createElement("td");
td.innerHTML = data[j];
tr.appendChild(td);
}
tbody.appendChild(tr);
trows.push(tr);
}
table.appendChild(thead);
table.appendChild(tbody);
container.appendChild(table);
return {
node: container,
trows: trows,
studentsNames: studentsNames
};
};
function Graph() {
this.svgns = 'http://www.w3.org/2000/svg';
this.height = GRAPH_OPTIONS.HEIGHT;
this.width = GRAPH_OPTIONS.WIDTH;
this.limits = {
minX: GRAPH_OPTIONS.BOARD.boundingbox[0] + 10,
minY: GRAPH_OPTIONS.BOARD.boundingbox[3] + 10,
maxX: GRAPH_OPTIONS.BOARD.boundingbox[1] - 5,
maxY: GRAPH_OPTIONS.BOARD.boundingbox[2] - 5
};
this.ratio = this._initRatio();
this.node = this._generateBoard();
this.xAxis = this.drawAxis([0, 0], [0, this.limits.maxY], GRAPH_OPTIONS.X_AXIS);
this.yAxis = this.drawAxis([0, 0], [this.limits.maxX, 0], GRAPH_OPTIONS.Y_AXIS);
}
Graph.prototype._initRatio = function() {
var bB = GRAPH_OPTIONS.BOARD.boundingbox;
this.xLength = bB[2] - bB[0];
this.yLength = bB[1] - bB[3];
var x = this.width / this.xLength;
var y = this.height / this.yLength;
this.centerX = Math.abs(bB[0] * x);
this.centerY = Math.abs(bB[3] * y);
return {
x: x,
y: y
}
};
Graph.prototype._generateBoard = function() {
var container, title;
this.svgNode = document.createElementNS(this.svgns, "svg");
this.svgNode.setAttributeNS(null, "width", this.width);
this.svgNode.setAttributeNS(null, "height", this.height);
container = document.createElement("div");
container.className = "graph";
container.appendChild(this.svgNode);
if ( GRAPH_OPTIONS.TITLES ) {
for (var i in GRAPH_OPTIONS.TITLES) {
title = document.createElement("div");
title.innerHTML = GRAPH_OPTIONS.TITLES[i];
title.className = i.toLowerCase() + "_title";
container.appendChild(title);
}
}
return container;
};
Graph.prototype.drawAxis = function(p1, p2, options) {
options = options || GRAPH_OPTIONS.AXIS;
options.ticks = options.ticks || GRAPH_OPTIONS.AXIS_TICKS;
var axis = this.drawLine(p1, p2, options);
var ticks = this.setTicks(axis, options.ticks);
return {
axis: axis,
ticks: ticks
};
};
Graph.prototype.drawLine = function(p1, p2, options) {
options = options || GRAPH_OPTIONS.LINE;
p1 = isObject(p1) ? [p1.x, p1.y] : p1;
p2 = isObject(p2) ? [p2.x, p2.y] : p2;
var line = document.createElementNS(this.svgns, "line");
var lineData = {
node: line,
x1: p1[0],
y1: p1[1],
x2: p2[0],
y2: p2[1],
A: ( p1[1] - p2[1] ),
B: ( p1[0] - p2[0] ),
attributes: options
};
var x1 = this.invertX(p1[0]);
var y1 = this.invertY(p1[1]);
var x2 = this.invertX(p2[0]);
var y2 = this.invertY(p2[1]);
line.setAttributeNS(null, "x1", x1);
line.setAttributeNS(null, "x2", x2);
line.setAttributeNS(null, "y1", y1);
line.setAttributeNS(null, "y2", y2);
for (var i in options) {
if ( typeof i === "string" ) {
line.setAttributeNS(null, i, options[i]);
}
}
if ( this.svgNode.childNodes[0] ) {
this.svgNode.insertBefore(line, this.svgNode.childNodes[0]);
}
else {
this.svgNode.appendChild(line);
}
return lineData;
};
Graph.prototype.setText = function(x, y, text, options) {
options = options || GRAPH_OPTIONS.TEXT;
var textNode = document.createElementNS(this.svgns, "text");
textNode.textContent = text;
x = this.invertX(x + ( options.offset.x || 0 ));
y = this.invertY(y + ( options.offset.y || 0 ));
textNode.setAttributeNS(null, "x", x);
textNode.setAttributeNS(null, "y", y);
for (var i in options) {
if ( typeof options[i] === "string" ) {
textNode.setAttributeNS(null, i, options[i]);
}
}
this.svgNode.appendChild(textNode);
};
Graph.prototype.invertX = function(x) {
return x * this.ratio.x + this.centerX;
};
Graph.prototype.invertY = function(y) {
return this.height - ( y * this.ratio.y + this.centerY );
};
Graph.prototype.setTicks = function(line, options) {
var stepX = ( line.x2 - line.x1 ) / options.ticksCount;
var stepY = ( line.y2 - line.y1 ) / options.ticksCount;
var startX = line.x1 + stepX;
var startY = line.y1 + stepY;
if ( options.drawZero ) {
this.drawPoint(line.x1, line.y1, { r: 2, stroke: "#000", fill: "#fff" });
this.setText(line.x1, line.y1, 0, options.text);
}
for (var i = 0; i < options.ticksCount; i++) {
this.drawPoint(startX, startY, { r: 2, stroke: "#000", fill: "#fff" });
this.setText(startX, startY, ( startX || startY ), options.text);
startX += stepX;
startY += stepY;
}
};
Graph.prototype.drawPoint = function(x, y, options) {
options = options || GRAPH_OPTIONS.POINT;
var pointData = {};
var point = document.createElementNS(this.svgns, "circle");
pointData.node = point;
pointData.x = x;
pointData.y = y;
x = this.invertX(x);
y = this.invertY(y);
point.setAttributeNS(null, "cx", x);
point.setAttributeNS(null, "cy", y);
for (var i in options) {
if ( typeof i === "string" ) {
point.setAttributeNS(null, i, options[i]);
}
}
this.svgNode.appendChild(point);
this.points = this.points || [];
this.points.push(pointData);
return pointData;
};
Graph.prototype.updateLine = function(line, p1, p2) {
p1 = isObject(p1) ? [p1.x, p1.y] : p1;
p2 = isObject(p2) ? [p2.x, p2.y] : p2;
var x1 = this.invertX(p1[0]);
var y1 = this.invertY(p1[1]);
var x2 = this.invertX(p2[0]);
var y2 = this.invertY(p2[1]);
line.setAttributeNS(null, "x1", x1);
line.setAttributeNS(null, "x2", x2);
line.setAttributeNS(null, "y1", y1);
line.setAttributeNS(null, "y2", y2);
};
function isObject(el) {
var str = Object.prototype.toString.call(el);
str = str.substring(8, str.length - 1);
str = str.toLowerCase();
return ( str === "object" );
}
function _initEvents() {
var trows = this.table.trows;
var studentsNames = this.table.studentsNames;
var graph = this.graph;
var callback, callbackBlur, lineX, lineY;
var points = [];
var counter = 0;
var isPassed = false;
var self = this;
for (var i = 0; i < trows.length; i++) {
callback = (function(i, graph) {
return function() {
var x = TBODY_DATA[studentsNames[i]][0];
var y = TBODY_DATA[studentsNames[i]][1];
var x1 = graph.limits.minX;
var y1 = graph.limits.minY;
if ( !points[i] ) {
points[i] = graph.drawPoint(x, y);
counter++;
}
lineX = lineX ? lineX : graph.drawLine([x1, y], [x, y]);
lineY = lineY ? lineY : graph.drawLine([x, y], [x, y1]);
graph.updateLine(lineX.node, [x1, y], [x, y]);
graph.updateLine(lineY.node, [x, y], [x, y1]);
if ( trows.length === counter && !isPassed ) {
//последняя строка не читается из-за смены фокуса
setTimeout(function() {
self.finishSlide();
isPassed = true;
}, 1000);
}
}
})(i, this.graph);
callbackBlur = function() {
graph.updateLine(lineX.node, [0, 0], [0, 0]);
graph.updateLine(lineY.node, [0, 0], [0, 0]);
};
trows[i].addEventListener("click", callback);
trows[i].addEventListener("focus", callback);
trows[i].addEventListener("blur", callbackBlur);
}
}
window.mheContpract = window.mheContpract || {};
window.mheContpract['line_drawing'] = {
initialize: function(section) {
section.slide = new LineDrawing(section);
},
show: function(section) {
//section.slide.showSlide();
}
};
})
();
(function() {
var GRAPH_OPTIONS = {
WIDTH: 360,
HEIGHT: 331,
TITLES: {
Y: "Variable 2",
X: "Variable 1"
},
BOARD: {
boundingbox: [-10, 75, 75, -10]
},
LINE: {
stroke: "#000",
"stroke-width": 2,
"stroke-dasharray": "5, 5"
},
AXIS: {
stroke: "#000",
"stroke-width": 2,
ticks: {
tickSize: 2,
ticksCount: 7,
drawZero: true,
text: {
"font-size": "16px",
fill: "#000",
offset: {
x: -5,
y: -2
}
}
}
},
TICKS: {
stroke: "#000",
"stroke-width": 2
},
POINT: {
r: 6,
fill: "red"
},
TEXT: {
"font-size": "16px",
fill: "#000"
},
AXIS_TICKS: {
tickSize: 2,
ticksCount: 7,
drawZero: true
},
X_AXIS: {
stroke: "#000",
"stroke-width": 2,
ticks: {
tickSize: 2,
ticksCount: 7,
drawZero: true,
text: {
"font-size": "16px",
fill: "#000",
offset: {
x: -6,
y: -1
}
}
}
},
Y_AXIS: {
stroke: "#000",
"stroke-width": 2,
ticks: {
tickSize: 2,
ticksCount: 7,
drawZero: true,
text: {
"font-size": "16px",
fill: "#000",
offset: {
x: -2,
y: -5
}
}
}
}
};
var TEXTS = [
[
"Correlation: Positive",
"This scatterplot shows a strong positive correlation.",
"People who scored high on Variable 1 tended to also have high scores on Variable 2, and vice versa.",
"r = +0.91."
],
[
"Correlation: Negative",
"This scatterplot shows a strong negative correlation.",
"People who scored high on Variable 1 tended to have low scores on Variable 2.",
"r = –0.96."
],
[
"Correlation: None",
"This scatterplot shows no correlation between the two variables.",
"r = +0.03 (near zero)"
]
];
var POINTS = [
[
[5, 5],
[10, 12],
[20, 21],
[25, 33],
[13, 38],
[28, 48],
[35, 55],
[44, 52],
[50, 63],
[65, 60]
],
[
[60, 5],
[50, 10],
[55, 17],
[42, 28],
[35, 30],
[29, 37],
[22, 52],
[17, 59],
[15, 47],
[10, 62]
],
[
[5, 33],
[10, 55],
[17, 19],
[21, 43],
[25, 51],
[31, 14],
[38, 52],
[45, 58],
[51, 24],
[68, 40]
]
];
function Practice(section) {
this.section = section;
this.section.points_possible = 1;
this.section.points_earned = 0;
this.section.section_completed = false;
section.jq.addClass('practice');
this.graph = new Graph();
this.graphContainer = section.jq[0].querySelector(".graph-container");
this.graphContainer.appendChild(this.graph.node);
this.fbContainer = section.jq[0].querySelector(".feedback-container");
this.buttons = section.jq[0].querySelectorAll(".btn-container button");
//дополнительное описание всей активности
this.aria_instruction = this.section.jq.find('.aria-instruction');
$(section.jq[0].querySelector(".scatterplot-activity")).attr({
'aria-label': this.aria_instruction.text(),
'tabindex': 0,
'role': 'application'
});
this.feedbacks = [];
this.points = [];
_initEvents.call(this);
initLiveRegion.call(this);
}
var initLiveRegion = function() {
this.liveRegion = $('');
this.section.jq.append(this.liveRegion);
};
Practice.prototype.finishSlide = function() {
this.section.points_earned = this.section.points_possible;
this.section.section_completed = true;
player.activity.grade_activity();
player.update_section_status();
document.querySelector('.navigation_button.next_button').focus();
};
Practice.prototype.setText = function(ind) {
this.fbContainer.innerHTML = "";
if ( this.feedbacks[ind] ) {
this.fbContainer.appendChild(this.feedbacks[ind]);
}
else {
var textContainer;
var ariaLabel = "";
var regexp = /<[A-Za-z]*[^>*]*>/g;
textContainer = document.createElement("div");
textContainer.className = "feedback-text";
var node, i;
for (i = 0; i < TEXTS[ind].length; i++) {
node = document.createElement("p");
node.innerHTML = TEXTS[ind][i];
ariaLabel += TEXTS[ind][i].replace(regexp, "");
textContainer.appendChild(node);
}
textContainer.setAttribute("aria-label", ariaLabel);
textContainer.setAttribute("tabindex", "0");
this.feedbacks[ind] = textContainer;
this.fbContainer.appendChild(textContainer);
}
};
Practice.prototype.drawScatterplot = function(ind) {
var points = POINTS[ind];
var i = 0;
var x, y;
for (i; i < points.length; i++) {
x = points[i][0];
y = points[i][1];
if ( this.points[i] ) {
this.graph.updatePoint(this.points[i], x, y);
}
else {
this.points.push(this.graph.drawPoint(x, y));
}
}
};
Practice.prototype.checkConsist = function(counter) {
for (var i = 0; i < counter.length; i++) {
if ( !counter[i] ) {
return;
}
}
this.finishSlide();
};
function Graph() {
this.svgns = 'http://www.w3.org/2000/svg';
this.height = GRAPH_OPTIONS.HEIGHT;
this.width = GRAPH_OPTIONS.WIDTH;
this.limits = {
minX: GRAPH_OPTIONS.BOARD.boundingbox[0] + 10,
minY: GRAPH_OPTIONS.BOARD.boundingbox[3] + 10,
maxX: GRAPH_OPTIONS.BOARD.boundingbox[1] - 5,
maxY: GRAPH_OPTIONS.BOARD.boundingbox[2] - 5
};
this.ratio = this._initRatio();
this.node = this._generateBoard();
this.xAxis = this.drawAxis([0, 0], [0, this.limits.maxY], GRAPH_OPTIONS.X_AXIS);
this.yAxis = this.drawAxis([0, 0], [this.limits.maxX, 0], GRAPH_OPTIONS.Y_AXIS);
}
Graph.prototype._initRatio = function() {
var bB = GRAPH_OPTIONS.BOARD.boundingbox;
this.xLength = bB[2] - bB[0];
this.yLength = bB[1] - bB[3];
var x = this.width / this.xLength;
var y = this.height / this.yLength;
this.centerX = Math.abs(bB[0] * x);
this.centerY = Math.abs(bB[3] * y);
return {
x: x,
y: y
}
};
Graph.prototype._generateBoard = function() {
var container, title;
this.svgNode = document.createElementNS(this.svgns, "svg");
this.svgNode.setAttributeNS(null, "width", this.width);
this.svgNode.setAttributeNS(null, "height", this.height);
container = document.createElement("div");
container.className = "graph";
container.appendChild(this.svgNode);
if ( GRAPH_OPTIONS.TITLES ) {
for (var i in GRAPH_OPTIONS.TITLES) {
title = document.createElement("div");
title.innerHTML = GRAPH_OPTIONS.TITLES[i];
title.className = i.toLowerCase() + "_title";
container.appendChild(title);
}
}
return container;
};
Graph.prototype.drawAxis = function(p1, p2, options) {
options = options || GRAPH_OPTIONS.AXIS;
options.ticks = options.ticks || GRAPH_OPTIONS.AXIS_TICKS;
var axis = this.drawLine(p1, p2, options);
var ticks = this.setTicks(axis, options.ticks);
return {
axis: axis,
ticks: ticks
};
};
Graph.prototype.drawLine = function(p1, p2, options) {
options = options || GRAPH_OPTIONS.LINE;
p1 = isObject(p1) ? [p1.x, p1.y] : p1;
p2 = isObject(p2) ? [p2.x, p2.y] : p2;
var line = document.createElementNS(this.svgns, "line");
var lineData = {
node: line,
x1: p1[0],
y1: p1[1],
x2: p2[0],
y2: p2[1],
A: ( p1[1] - p2[1] ),
B: ( p1[0] - p2[0] ),
attributes: options
};
var x1 = this.invertX(p1[0]);
var y1 = this.invertY(p1[1]);
var x2 = this.invertX(p2[0]);
var y2 = this.invertY(p2[1]);
line.setAttributeNS(null, "x1", x1);
line.setAttributeNS(null, "x2", x2);
line.setAttributeNS(null, "y1", y1);
line.setAttributeNS(null, "y2", y2);
for (var i in options) {
if ( typeof i === "string" ) {
line.setAttributeNS(null, i, options[i]);
}
}
if ( this.svgNode.childNodes[0] ) {
this.svgNode.insertBefore(line, this.svgNode.childNodes[0]);
}
else {
this.svgNode.appendChild(line);
}
return lineData;
};
Graph.prototype.setText = function(x, y, text, options) {
options = options || GRAPH_OPTIONS.TEXT;
var textNode = document.createElementNS(this.svgns, "text");
textNode.textContent = text;
x = this.invertX(x + ( options.offset.x || 0 ));
y = this.invertY(y + ( options.offset.y || 0 ));
textNode.setAttributeNS(null, "x", x);
textNode.setAttributeNS(null, "y", y);
for (var i in options) {
if ( typeof options[i] === "string" ) {
textNode.setAttributeNS(null, i, options[i]);
}
}
this.svgNode.appendChild(textNode);
};
Graph.prototype.invertX = function(x) {
return x * this.ratio.x + this.centerX;
};
Graph.prototype.invertY = function(y) {
return this.height - ( y * this.ratio.y + this.centerY );
};
Graph.prototype.setTicks = function(line, options) {
var stepX = ( line.x2 - line.x1 ) / options.ticksCount;
var stepY = ( line.y2 - line.y1 ) / options.ticksCount;
var startX = line.x1 + stepX;
var startY = line.y1 + stepY;
if ( options.drawZero ) {
this.drawPoint(line.x1, line.y1, { r: 2, stroke: "#000", fill: "#fff" });
this.setText(line.x1, line.y1, 0, options.text);
}
for (var i = 0; i < options.ticksCount; i++) {
this.drawPoint(startX, startY, { r: 2, stroke: "#000", fill: "#fff" });
this.setText(startX, startY, ( startX || startY ), options.text);
startX += stepX;
startY += stepY;
}
};
Graph.prototype.drawPoint = function(x, y, options) {
options = options || GRAPH_OPTIONS.POINT;
var pointData = {};
var point = document.createElementNS(this.svgns, "circle");
pointData.node = point;
pointData.x = x;
pointData.y = y;
x = this.invertX(x);
y = this.invertY(y);
point.setAttributeNS(null, "cx", x);
point.setAttributeNS(null, "cy", y);
for (var i in options) {
if ( typeof i === "string" ) {
point.setAttributeNS(null, i, options[i]);
}
}
this.svgNode.appendChild(point);
this.points = this.points || [];
this.points.push(pointData);
return pointData;
};
Graph.prototype.updatePoint = function(point, x, y) {
point.x = x;
point.y = y;
x = this.invertX(x);
y = this.invertY(y);
point.node.setAttributeNS(null, "cx", x);
point.node.setAttributeNS(null, "cy", y);
};
function isObject(el) {
var str = Object.prototype.toString.call(el);
str = str.substring(8, str.length - 1);
str = str.toLowerCase();
return ( str === "object" );
}
function _initEvents() {
var i = 0;
var self = this;
var counter = new Array(3);
for (i; i < this.buttons.length; i++) {
this.buttons[i].addEventListener("click", (function(i) {
return function() {
self.setText(i);
self.drawScatterplot(i);
if ( self.section.section_completed ) {
return;
}
counter[i] = true;
self.checkConsist(counter);
}
})(i));
}
}
window.mheContpract = window.mheContpract || {};
window.mheContpract['practice_2'] = {
initialize: function(section) {
section.slide = new Practice(section);
},
show: function(section) {
//section.slide.showSlide();
}
};
})();