aboutsummaryrefslogtreecommitdiff
path: root/app/static
diff options
context:
space:
mode:
Diffstat (limited to 'app/static')
-rw-r--r--app/static/annotate.css6
-rw-r--r--app/static/css/demo/evaluate.css57
-rw-r--r--app/static/css/demo/learn.css11
-rw-r--r--app/static/css/global.css3
-rw-r--r--app/static/js/buttons.js39
-rw-r--r--app/static/js/makeChart.js146
-rw-r--r--app/static/view_annotation.css3
7 files changed, 238 insertions, 27 deletions
diff --git a/app/static/annotate.css b/app/static/annotate.css
index 7dc222f..8079053 100644
--- a/app/static/annotate.css
+++ b/app/static/annotate.css
@@ -20,5 +20,9 @@ rect {
}
#rubric {
- text-align: center;
+ text-align: left;
+ padding-bottom: 20px;
+ padding-top: 10px;
+ width: 80%;
+ font-size: 16px;
}
diff --git a/app/static/css/demo/evaluate.css b/app/static/css/demo/evaluate.css
new file mode 100644
index 0000000..0c7dbc2
--- /dev/null
+++ b/app/static/css/demo/evaluate.css
@@ -0,0 +1,57 @@
+.graph-wrapper {
+ width: 90%;
+ margin: 0 auto;
+}
+
+#graph_user > svg {
+ width: 100%;
+ height: 100%;
+}
+
+#graph_true > svg {
+ width: 100%;
+ height: 100%;
+}
+
+.line {
+ fill: none;
+ stroke: blue;
+ clip-path: url(#clip);
+}
+
+circle {
+ clip-path: url(#clip);
+ fill: blue;
+}
+
+rect {
+ fill: white;
+ opacity: 0;
+}
+
+.marked {
+ fill: #fc8d62;
+ stroke: #fc8d62;
+}
+
+#next-btn {
+ text-align: right;
+ padding-bottom: 20px;
+}
+
+#lesson {
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+#lesson p {
+ font-size: 16px;
+}
+
+.ann-line {
+ stroke-dasharray: 5;
+ clip-path: url(#clip);
+ fill: #fc8d62;
+ stroke: #fc8d62;
+ stroke-width: 2px;
+}
diff --git a/app/static/css/demo/learn.css b/app/static/css/demo/learn.css
new file mode 100644
index 0000000..13dccd2
--- /dev/null
+++ b/app/static/css/demo/learn.css
@@ -0,0 +1,11 @@
+#next-btn {
+ text-align: right;
+}
+
+#lesson {
+ padding-top: 10px;
+}
+
+#lesson p {
+ font-size: 16px;
+}
diff --git a/app/static/css/global.css b/app/static/css/global.css
new file mode 100644
index 0000000..6258057
--- /dev/null
+++ b/app/static/css/global.css
@@ -0,0 +1,3 @@
+h1, h2, h3 {
+ margin-bottom: 20px;
+}
diff --git a/app/static/js/buttons.js b/app/static/js/buttons.js
index d26a15d..75adad2 100644
--- a/app/static/js/buttons.js
+++ b/app/static/js/buttons.js
@@ -8,7 +8,7 @@ function resetOnClick() {
updateTable();
}
-function noCPOnClick(task_id) {
+function noCPOnClick(identifier) {
var changepoints = document.getElementsByClassName("changepoint");
// validation
if (changepoints.length > 0) {
@@ -16,27 +16,27 @@ function noCPOnClick(task_id) {
return;
}
- var obj = {
- task: task_id,
- changepoints: null
- };
+ var obj = {}
+ obj["identifier"] = identifier;
+ obj["changepoints"] = null;
var xhr = new XMLHttpRequest();
- xhr.open("POST", "");
+ xhr.open("POST", "", false);
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/json");
- xhr.send(JSON.stringify(obj));
+ /* Flask's return to this POST must be a URL, not a template!*/
xhr.onreadystatechange = function() {
- if (xhr.readyState == XMLHttpRequest.DONE) {
- if (xhr.status === 200)
- window.location.href = xhr.responseText;
+ if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
+ window.location.href = xhr.responseText;
+ console.log("XHR Success: " + xhr.responseText);
} else {
- console.log("Error: " + xhr.status);
+ console.log("XHR Error: " + xhr.status);
}
- };
+ }
+ xhr.send(JSON.stringify(obj));
}
-function submitOnClick(task_id) {
+function submitOnClick(identifier) {
var changepoints = document.getElementsByClassName("changepoint");
// validation
if (changepoints.length === 0) {
@@ -45,7 +45,7 @@ function submitOnClick(task_id) {
}
var obj = {};
- obj["task"] = task_id;
+ obj["identifier"] = identifier;
obj["changepoints"] = [];
var i, cp;
for (i=0; i<changepoints.length; i++) {
@@ -62,14 +62,15 @@ function submitOnClick(task_id) {
xhr.open("POST", "");
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/json");
- xhr.send(JSON.stringify(obj));
+ /* Flask's return to this POST must be a URL, not a template!*/
xhr.onreadystatechange = function() {
- if (xhr.readyState == XMLHttpRequest.DONE) {
- if (xhr.status === 200)
- window.location.href = xhr.responseText;
+ if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
+ window.location.href = xhr.responseText;
+ console.log("XHR Success: " + xhr.responseText);
} else {
- console.log("Error: " + xhr.status);
+ console.log("XHR Error: " + xhr.status);
}
};
+ xhr.send(JSON.stringify(obj));
}
diff --git a/app/static/js/makeChart.js b/app/static/js/makeChart.js
index 35069b6..fd4a257 100644
--- a/app/static/js/makeChart.js
+++ b/app/static/js/makeChart.js
@@ -1,4 +1,4 @@
-function makeChart(data) {
+function makeChart(selector, data) {
var n = 0;
data.forEach(function(d) {
d.X = n++;
@@ -8,7 +8,7 @@ function makeChart(data) {
var divWidth = 1000;
var divHeight = 480;
- var svg = d3.select("#graph")
+ var svg = d3.select(selector)
.on("touchstart", nozoom)
.on("touchmove", nozoom)
.append("svg")
@@ -31,6 +31,7 @@ function makeChart(data) {
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
+ yAxis.ticks(0);
var xExtent = d3.extent(data, function(d) { return d.X; });
var xRange = xExtent[1] - xExtent[0];
@@ -49,13 +50,13 @@ function makeChart(data) {
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
- .attr("width", width - 30)
+ .attr("width", width - 18)
.attr("height", height)
- .attr("transform", "translate(" + 30 + ",0)");
+ .attr("transform", "translate(" + 18 + ",0)");
svg.append("g")
.attr("class", "axis axis--y")
- .attr("transform", "translate(" + 30 + ",0)")
+ .attr("transform", "translate(" + 18 + ",0)")
.call(yAxis);
svg.append("g")
@@ -127,3 +128,138 @@ function makeChart(data) {
d3.event.preventDefault();
}
}
+
+function makeChartAnnotated(selector, data, annotations) {
+ var n = 0;
+ data.forEach(function(d) {
+ d.X = n++;
+ d.Y = d.value;
+ });
+
+ var divWidth = 1000;
+ var divHeight = 480;
+
+ var svg = d3.select(selector)
+ .on("touchstart", nozoom)
+ .on("touchmove", nozoom)
+ .append("svg")
+ .attr("width", divWidth)
+ .attr("height", divHeight)
+ .attr("viewBox", "0 0 " + divWidth + " " + divHeight);
+
+ var margin = {top: 20, right: 20, bottom: 50, left: 50};
+ var width = +svg.attr("width") - margin.left - margin.right;
+ var height = +svg.attr("height") - margin.top - margin.bottom;
+
+ var zoom = d3.zoom()
+ .scaleExtent([1, 50])
+ .translateExtent([[0, 0], [width, height]])
+ .extent([[0, 0], [width, height]])
+ .on("zoom", zoomed);
+
+ var x = d3.scaleLinear().range([0, width]);
+ var x2 = d3.scaleLinear().range([0, width]);
+ var y = d3.scaleLinear().range([height, 0]);
+
+ var xAxis = d3.axisBottom(x);
+ var yAxis = d3.axisLeft(y);
+ yAxis.ticks(0);
+
+ var xExtent = d3.extent(data, function(d) { return d.X; });
+ var xRange = xExtent[1] - xExtent[0];
+ var xDomainMin = xExtent[0] - xRange * 0.02;
+ var xDomainMax = xExtent[1] + xRange * 0.02;
+
+ var yExtent = d3.extent(data, function(d) { return d.Y; });
+ var yRange = yExtent[1] - yExtent[0];
+ var yDomainMin = yExtent[0] - yRange * 0.05;
+ var yDomainMax = yExtent[1] + yRange * 0.05;
+
+ x.domain([xDomainMin, xDomainMax]);
+ y.domain([yDomainMin, yDomainMax]);
+ x2.domain(x.domain());
+
+ svg.append("defs").append("clipPath")
+ .attr("id", "clip")
+ .append("rect")
+ .attr("width", width - 18)
+ .attr("height", height)
+ .attr("transform", "translate(" + 18 + ",0)");
+
+ svg.append("g")
+ .attr("class", "axis axis--y")
+ .attr("transform", "translate(" + 18 + ",0)")
+ .call(yAxis);
+
+ svg.append("g")
+ .attr("class", "axis axis--x")
+ .attr("transform", "translate(0," + height + ")")
+ .call(xAxis);
+
+ svg.append("text")
+ .attr("text-anchor", "middle")
+ .attr("class", "axis-label")
+ .attr("transform", "translate(" + (width - 20) + "," + (height + 50) + ")")
+ .text("Time");
+
+ var line = d3.line()
+ .x(function(d) { return x(d.X); })
+ .y(function(d) { return y(d.Y); });
+
+ var g = svg.append("g")
+ .call(zoom);
+
+ g.append("rect")
+ .attr("width", width)
+ .attr("height", height);
+
+ var view = g.append("g")
+ .attr("class", "view");
+
+ view.append("path")
+ .datum(data)
+ .attr("class", "line")
+ .attr("d", line);
+
+ var points = view.selectAll("circle")
+ .data(data)
+ .enter().append("circle")
+ .attr("cx", function(d) { return x(d.X); })
+ .attr("cy", function(d) { return y(d.Y); })
+ .attr("data_X", function(d) { return d.X; })
+ .attr("data_Y", function(d) { return d.Y; })
+ .attr("r", 5);
+
+ function zoomed() {
+ t = d3.event.transform;
+ x.domain(t.rescaleX(x2).domain());
+ svg.select(".line").attr("d", line);
+ points.data(data)
+ .attr("cx", function(d) { return x(d.X); })
+ .attr("cy", function(d) { return y(d.Y); });
+ svg.select(".axis--x").call(xAxis);
+ }
+
+ function nozoom() {
+ d3.event.preventDefault();
+ }
+
+ annotations.forEach(function(a) {
+ for (i=0; i<points._groups[0].length; i++) {
+ p = points._groups[0][i];
+ if (p.getAttribute("data_X") == a.index) {
+ var elem = d3.select(p);
+ elem.classed("marked", "true");
+ view.append("line")
+ .attr("cp_idx", a.index)
+ .attr("y1", y(yDomainMax))
+ .attr("y2", y(yDomainMin))
+ .attr("x1", x(a.index))
+ .attr("x2", x(a.index))
+ .attr("class", "ann-line");
+ break;
+ }
+ }
+ });
+}
+
diff --git a/app/static/view_annotation.css b/app/static/view_annotation.css
index 4b4f338..11bf3c8 100644
--- a/app/static/view_annotation.css
+++ b/app/static/view_annotation.css
@@ -11,7 +11,7 @@
.ann-line {
fill: none;
- stroke-dasharray: 3,3;
+ stroke-dasharray: 5;
clip-path: url(#clip);
}
@@ -64,4 +64,3 @@ rect {
fill: #b3b3b3;
stroke: #b3b3b3;
}
-