class ADC2019Board {
constructor(selector) {
this.container = $(selector);
this.width = this.container.width();
this.height = $(window).height();
this.svg = d3.select(selector).append('svg');
this.view = this.svg.append('g').attr('class', 'view');
this.currentTransform = null;
this.cubeResolution = 50;
this._init();
this._draw_slider();
}
get_board_list(selector){
var _self = this;
var container = $(selector);
container.html("");
$.ajax({
url: '/api/boards',
type: 'GET',
}).done((data) => {
var $board_list = container.append("
");
for(var i=0; i" + data[i] + "");
}
if(data.indexOf(_self._get_hash()) >= 0){
_self.draw(_self._get_hash());
}
}).fail((data) => {
console.log("Error");
});
}
draw(name){
this._draw_init();
this._get_board(name);
}
_get_hash(){
return location.hash.replace("#", "");
}
_init(){
var _self = this;
if (this.currentTransform){
this.view.attr('transform', this.currentTransform);
}
$(window).on('hashchange', () => {
_self.draw(_self._get_hash());
});
}
_get_board(name){
$.ajax({
url: '/api/board/' + name,
type: 'GET',
}).done((data) => {
this._draw_grid(data.size[0], data.size[1]);
this._draw_blocks(data.blocks);
}).fail((data) => {
console.log("Error");
});
}
_draw_init(){
this.view.selectAll("g").remove();
}
_draw_grid(x_cnt, y_cnt){
let _width = x_cnt * this.cubeResolution;
let _height = y_cnt * this.cubeResolution;
this.view.append("g")
.attr("class", "x axis")
.selectAll("line")
.data(d3.range(0, _width+1, this.cubeResolution))
.enter().append("line")
.attr("x1", function (d) { return d; })
.attr("y1", 0)
.attr("x2", function (d) { return d; })
.attr("y2", _height)
.attr("stroke", "#888");
this.view.append("g")
.attr("class", "y axis")
.selectAll("line")
.data(d3.range(0, _height+1, this.cubeResolution))
.enter().append("line")
.attr("x1", 0)
.attr("y1", function (d) { return d; })
.attr("x2", _width)
.attr("y2", function (d) { return d; })
.attr("stroke", "#888");
}
_draw_slider(){
let _self = this;
var zoom = d3.zoom()
.scaleExtent([0.5, 5])
.translateExtent([
[-this.width * 2, -this.height * 2],
[this.width * 2, this.height * 2]
])
.on("zoom", zoomed);
function zoomed() {
this.currentTransform = d3.event.transform;
_self.view.attr("transform", this.currentTransform);
// this.slider.property("value", d3.event.scale);
}
function slided(d) {
zoom.scaleTo(this.svg, d3.select(this).property("value"));
}
// var slider = d3.select("body").append("input")
// .datum({})
// .attr("type", "range")
// .attr("value", 1)
// .attr("min", zoom.scaleExtent()[0])
// .attr("max", zoom.scaleExtent()[1])
// .attr("step", (zoom.scaleExtent()[1] - zoom.scaleExtent()[0]) / 100)
// .on("input", slided);
this.svg.call(zoom).on('dblclick.zoom', null);
}
_draw_blocks(blocks){
let cubeResolution = this.cubeResolution;
function snapToGrid(p, r) {
return Math.round(p / r) * r;
}
function dragged(d) {
var el = d3.select(this);
var _x = parseInt(el.attr('data-x'), 10) + d3.event.x;
var _y = parseInt(el.attr('data-y'), 10) + d3.event.y;
el.attr("transform", (d) => {
return 'translate(' + snapToGrid(_x, cubeResolution) + ',' + snapToGrid(_y, cubeResolution) + ')'
})
}
function dragended(d) {
var el = d3.select(this).classed("dragging", false);
var _x = parseInt(el.attr('data-x'), 10) + d3.event.x;
var _y = parseInt(el.attr('data-y'), 10) + d3.event.y;
d3.select(this)
.attr('data-x', snapToGrid(_x, cubeResolution))
.attr('data-y', snapToGrid(_y, cubeResolution));
}
function dragstarted(d) {
var el = d3.select(this);
el.raise().classed("dragging", true);
}
let colors = d3.schemeCategory10
// Reference
// Grid: https://bl.ocks.org/ngminhtrung/7c5721a1504f3e29a36da9ddd9e5039b
// Snap: https://bl.ocks.org/evanjmg/ea3e59e67b4256c8831d3fc80f71294b
// Nested data structure: https://codeday.me/jp/qa/20190428/720184.html
var itemContainer = this.view.selectAll("g.itemContainer")
.data(blocks)
.enter()
.append('g')
.attr('class', 'itemContainer')
.attr("transform", (d) => 'translate(' + d.x + ',' + d.y + ')')
.attr('data-x', (d) => d.x)
.attr('data-y', (d) => d.y)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
var cellContainer = itemContainer.append('g')
.attr('class', 'cellContainer')
.attr('data-color', (d, i) => colors[i])
.attr('x', 0)
.attr('y', 0)
cellContainer.selectAll('g')
.data((d) => d.cells)
.enter()
.append('rect')
.attr('x', (d) => d[0] * this.cubeResolution)
.attr('y', (d) => d[1] * this.cubeResolution)
.attr('width', this.cubeResolution)
.attr('height', this.cubeResolution)
.attr('cursor', 'move')
.attr('fill', (d, i, nodes) => {
return d3.select(nodes[i].parentNode).attr('data-color');
});
cellContainer.selectAll('g')
.data((d) => d.cells)
.enter()
.append('text')
.attr('x', (d) => d[0] * this.cubeResolution + 0.5 * this.cubeResolution)
.attr('y', (d) => d[1] * this.cubeResolution + 0.5 * this.cubeResolution)
.attr('width', this.cubeResolution)
.attr('height', this.cubeResolution)
.attr('text-anchor', 'middle')
.attr('fill', 'white')
.attr('font-size', '20px')
.attr('cursor', 'move')
.text((d) => d[2]);
}
}
$(function(){
// const board = new ADC2019Board("#board-container");
// board.get_board_list("#board-list-container");
// // board.draw("Q001_10X10_b8_n11.txt");
var show_question_status = function(qname){
$.ajax({
type: "GET",
dataType: "html",
url: "/template/question/" + qname,
}).done((d) => {
$("#status-container").empty();
$("#status-container").html(d);
// $("#status-container").find(".start-button").eq(0).click(function(){
// var qname = $(this).data("qname");
// pm.sendQuestion(qname);
// });
// $("#status-container").find(".stop-button").eq(0).click(function(){
// pm.sendStop();
// });
// $("#status-container").find(".save-button").eq(0).click(function(){
// var qname = $(this).data("qname");
// $.ajax({
// type: "POST",
// dataType: "json",
// url: "/save",
// data: {qname: qname}
// }).done((data) => {
// alert(data['status']);
// });
// });
// $("#status-container").find(".submit-button").eq(0).click(function(){
// var qname = $(this).data("qname");
// $.ajax({
// type: "POST",
// dataType: "json",
// url: "/adccli-put-a",
// data: {qname: qname}
// }).done((data) => {
// alert(data['message']);
// });
// });
// $(".answer-detail-row td").click(function(){
// var json_name = $(this).parent("tr").data("json");
// var qname = $(this).parent("tr").data("qname");
// var viewer_url = "/board-viewer#" + qname + "," + json_name
// window.open(viewer_url, "_blank");
// })
});
}
var refresh_questions = function(){
$.ajax({
type: "GET",
dataType: "html",
url: "/template/questions"
}).done((d) => {
$("#question-list-container").empty();
$("#question-list-container").html(d);
$(".question-row td").click(function(){
var $tr = $(this).parent("tr.question-row");
$(".question-row").removeClass("q-selected");
$tr.addClass("q-selected");
var qname = $tr.data("qname");
// show_question_status(qname);
location.hash = "#" + qname;
return false;
});
var hash = location.hash.replace("#", "");
if(hash != ""){
$(".question-row[data-qname='" + hash + "']").addClass("q-selected");
}
});
}
$(window).on('hashchange', function(){
var hash = location.hash.replace("#", "");
if(hash == ""){
// show_client_table();
}else{
show_question_status(hash);
}
}).trigger('hashchange');
refresh_questions();
});