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(); });