Loading main.py +3 −3 Changes for main.py: 3 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -16,9 +16,9 @@ def webui_index(): # return adc2019system.role.role return render_template('index.html') @webui.route('/view/solution') def webui_view_solution(): return render_template('view-solution.html') @webui.route('/viewer') def webui_viewer(): return render_template('viewer.html') @webui.route('/part/problems') def webui_part_problems(): Loading roles/host.py +6 −5 Changes for roles/host.py: 6 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -106,15 +106,16 @@ class Host(object): else: return {'status': 'unknown request'} def get_solution_for_viewer(self, problem_key, solution_id): def get_viewer_data(self, problem_key, solution_id): problem = self.get_problem(problem_key) if problem is None: return None problem_data = problem.get_d3json() if solution_id is None: solution_data = None else: solution = problem.get_solution(solution_id) if solution is None: return None solution_data = solution.get_d3json() return { Loading Loading @@ -146,10 +147,10 @@ class Host(object): elif cmd == 'stop': self.worker_manager.request_stop() return {} elif cmd == 'view/solution': elif cmd == 'view': problem_key = params['problem'] solution_id = params['solution'] return self.get_solution_for_viewer(problem_key, solution_id) return self.get_viewer_data(problem_key, solution_id) elif cmd == 'adccli/login': with open('path-to-adccli-login', 'r') as fp: d = json.load(fp) Loading static/js/adc2019-viewer.js +77 −92 Changes for static/js/adc2019-viewer.js: 77 added lines, 92 removed lines. Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ class ADC2019BoardViewer { let cubeResolution = this.cubeResolution; // Draw outer box if(('solution' in data) && (data['solution'] != null)){ let _width = data['solution']['w'] * this.cubeResolution; let _height = data['solution']['h'] * this.cubeResolution; this.view.append("g") Loading @@ -128,6 +129,7 @@ class ADC2019BoardViewer { .attr("y2", function (d) { return d; }) .attr("stroke", "#d00") .attr("stroke-width", 2); } let colors = d3.schemeCategory10 Loading @@ -138,11 +140,18 @@ class ADC2019BoardViewer { // Create data var blocks = data['problem']['block']; var block_nums = Object.keys(blocks).length; var block_row = Math.ceil(Math.sqrt(block_nums)); var block_idx = 0; for(var bi in blocks){ let bw = blocks[bi]['w']; let bh = blocks[bi]['h']; let bx = data['solution']['block'][bi]['x']; let by = data['solution']['block'][bi]['y']; var bx = (block_idx % block_row) * 3; var by = (Math.floor(block_idx / block_row)) * 3; if(('solution' in data) && (data['solution'] != null)){ bx = data['solution']['block'][bi]['x']; by = data['solution']['block'][bi]['y']; } blocks[bi]['cellpos'] = Array(); for(var _h=0; _h<bh; _h++){ Loading @@ -161,6 +170,34 @@ class ADC2019BoardViewer { blocks[bi]['x'] = bx; blocks[bi]['y'] = by; block_idx++; } function snapToGrid(p, r) { return Math.round(p / r) * r; } var __view = this.view; 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); } var itemContainer = this.view.selectAll("g.itemContainer") Loading @@ -168,15 +205,19 @@ class ADC2019BoardViewer { .enter() .append('g') .attr('class', 'itemContainer') .attr("transform", (d) => 'translate(' + d.x + ',' + d.y + ')') .attr("transform", (d) => 'translate(' + 0 + ',' + 0 + ')') .attr('data-x', (d) => d.x) .attr('data-y', (d) => d.y); .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 % colors.length]) .attr('x', 0) .attr('y', 0) .attr('y', 0); cellContainer.selectAll('g') .data((d) => d.cellpos) Loading @@ -191,6 +232,7 @@ class ADC2019BoardViewer { return d3.select(nodes[i].parentNode).attr('data-color'); }); if(('solution' in data) && (data['solution'] != null)){ cellContainer.selectAll('g') .data((d) => d.cellpos) .enter() Loading @@ -203,8 +245,24 @@ class ADC2019BoardViewer { .attr('fill', 'white') .attr('font-size', '20px') .attr('cursor', 'move'); // .text((d) => d[2]); }else{ cellContainer.selectAll('g') .data((d) => d.cellpos) .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]); } if(('solution' in data) && (data['solution'] != null)){ // Draw lines let sw = data['solution']['w']; let sh = data['solution']['h']; var lines = Object(); Loading Loading @@ -265,91 +323,9 @@ class ADC2019BoardViewer { .attr('fill', 'black') .attr('font-size', '16px') .text((d) => d[2]); } } // _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(){ Loading @@ -359,17 +335,26 @@ $(function(){ hash = location.hash.replace("#", ""); params = hash.split('/'); problem_name = params[0]; if(params.length > 1){ solution_id = params[1]; }else{ solution_id = null; } $.ajax({ type: "POST", dataType: "json", url: "/api/view/solution", url: "/api/view", data: JSON.stringify({ "problem": params[0], "solution": params[1] "problem": problem_name, "solution": solution_id }), contentType: 'application/json' }).done((d) => { board.draw(d); }).fail((d) => { console.log(d); }); }); Loading static/js/adc2019.js +1 −1 Changes for static/js/adc2019.js: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ class StatusView { _this.container.find('.solution-detail-row.valid-solution td').click((e) => { var solution_id = $(e.target).parent("tr").data("solution-id"); var problem_name = $(e.target).parent("tr").data("problem"); var viewer_url = "/view/solution#" + problem_name + "/" + solution_id; var viewer_url = "/viewer#" + problem_name + "/" + solution_id; window.open(viewer_url, "_blank"); }); Loading templates/part_problem_status.html +1 −0 Changes for templates/part_problem_status.html: 1 added line, 0 removed lines. Original line number Diff line number Diff line <div> <h4 class='inline-heading' id='problem-status-title'>{{problem.name}}</h4> <a href="/viewer#{{problem.name}}" target="_blank">Viewer</a> {#% # if localmode %#} <button class="btn btn-primary btn-lg start-button" type="button" data-qname="{{problem.name}}">Start</button> <!-- <button class="btn btn-danger btn-lg stop-button" type="button" data-qname="all">Stop</button> --> Loading Loading
main.py +3 −3 Changes for main.py: 3 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -16,9 +16,9 @@ def webui_index(): # return adc2019system.role.role return render_template('index.html') @webui.route('/view/solution') def webui_view_solution(): return render_template('view-solution.html') @webui.route('/viewer') def webui_viewer(): return render_template('viewer.html') @webui.route('/part/problems') def webui_part_problems(): Loading
roles/host.py +6 −5 Changes for roles/host.py: 6 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -106,15 +106,16 @@ class Host(object): else: return {'status': 'unknown request'} def get_solution_for_viewer(self, problem_key, solution_id): def get_viewer_data(self, problem_key, solution_id): problem = self.get_problem(problem_key) if problem is None: return None problem_data = problem.get_d3json() if solution_id is None: solution_data = None else: solution = problem.get_solution(solution_id) if solution is None: return None solution_data = solution.get_d3json() return { Loading Loading @@ -146,10 +147,10 @@ class Host(object): elif cmd == 'stop': self.worker_manager.request_stop() return {} elif cmd == 'view/solution': elif cmd == 'view': problem_key = params['problem'] solution_id = params['solution'] return self.get_solution_for_viewer(problem_key, solution_id) return self.get_viewer_data(problem_key, solution_id) elif cmd == 'adccli/login': with open('path-to-adccli-login', 'r') as fp: d = json.load(fp) Loading
static/js/adc2019-viewer.js +77 −92 Changes for static/js/adc2019-viewer.js: 77 added lines, 92 removed lines. Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ class ADC2019BoardViewer { let cubeResolution = this.cubeResolution; // Draw outer box if(('solution' in data) && (data['solution'] != null)){ let _width = data['solution']['w'] * this.cubeResolution; let _height = data['solution']['h'] * this.cubeResolution; this.view.append("g") Loading @@ -128,6 +129,7 @@ class ADC2019BoardViewer { .attr("y2", function (d) { return d; }) .attr("stroke", "#d00") .attr("stroke-width", 2); } let colors = d3.schemeCategory10 Loading @@ -138,11 +140,18 @@ class ADC2019BoardViewer { // Create data var blocks = data['problem']['block']; var block_nums = Object.keys(blocks).length; var block_row = Math.ceil(Math.sqrt(block_nums)); var block_idx = 0; for(var bi in blocks){ let bw = blocks[bi]['w']; let bh = blocks[bi]['h']; let bx = data['solution']['block'][bi]['x']; let by = data['solution']['block'][bi]['y']; var bx = (block_idx % block_row) * 3; var by = (Math.floor(block_idx / block_row)) * 3; if(('solution' in data) && (data['solution'] != null)){ bx = data['solution']['block'][bi]['x']; by = data['solution']['block'][bi]['y']; } blocks[bi]['cellpos'] = Array(); for(var _h=0; _h<bh; _h++){ Loading @@ -161,6 +170,34 @@ class ADC2019BoardViewer { blocks[bi]['x'] = bx; blocks[bi]['y'] = by; block_idx++; } function snapToGrid(p, r) { return Math.round(p / r) * r; } var __view = this.view; 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); } var itemContainer = this.view.selectAll("g.itemContainer") Loading @@ -168,15 +205,19 @@ class ADC2019BoardViewer { .enter() .append('g') .attr('class', 'itemContainer') .attr("transform", (d) => 'translate(' + d.x + ',' + d.y + ')') .attr("transform", (d) => 'translate(' + 0 + ',' + 0 + ')') .attr('data-x', (d) => d.x) .attr('data-y', (d) => d.y); .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 % colors.length]) .attr('x', 0) .attr('y', 0) .attr('y', 0); cellContainer.selectAll('g') .data((d) => d.cellpos) Loading @@ -191,6 +232,7 @@ class ADC2019BoardViewer { return d3.select(nodes[i].parentNode).attr('data-color'); }); if(('solution' in data) && (data['solution'] != null)){ cellContainer.selectAll('g') .data((d) => d.cellpos) .enter() Loading @@ -203,8 +245,24 @@ class ADC2019BoardViewer { .attr('fill', 'white') .attr('font-size', '20px') .attr('cursor', 'move'); // .text((d) => d[2]); }else{ cellContainer.selectAll('g') .data((d) => d.cellpos) .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]); } if(('solution' in data) && (data['solution'] != null)){ // Draw lines let sw = data['solution']['w']; let sh = data['solution']['h']; var lines = Object(); Loading Loading @@ -265,91 +323,9 @@ class ADC2019BoardViewer { .attr('fill', 'black') .attr('font-size', '16px') .text((d) => d[2]); } } // _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(){ Loading @@ -359,17 +335,26 @@ $(function(){ hash = location.hash.replace("#", ""); params = hash.split('/'); problem_name = params[0]; if(params.length > 1){ solution_id = params[1]; }else{ solution_id = null; } $.ajax({ type: "POST", dataType: "json", url: "/api/view/solution", url: "/api/view", data: JSON.stringify({ "problem": params[0], "solution": params[1] "problem": problem_name, "solution": solution_id }), contentType: 'application/json' }).done((d) => { board.draw(d); }).fail((d) => { console.log(d); }); }); Loading
static/js/adc2019.js +1 −1 Changes for static/js/adc2019.js: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ class StatusView { _this.container.find('.solution-detail-row.valid-solution td').click((e) => { var solution_id = $(e.target).parent("tr").data("solution-id"); var problem_name = $(e.target).parent("tr").data("problem"); var viewer_url = "/view/solution#" + problem_name + "/" + solution_id; var viewer_url = "/viewer#" + problem_name + "/" + solution_id; window.open(viewer_url, "_blank"); }); Loading
templates/part_problem_status.html +1 −0 Changes for templates/part_problem_status.html: 1 added line, 0 removed lines. Original line number Diff line number Diff line <div> <h4 class='inline-heading' id='problem-status-title'>{{problem.name}}</h4> <a href="/viewer#{{problem.name}}" target="_blank">Viewer</a> {#% # if localmode %#} <button class="btn btn-primary btn-lg start-button" type="button" data-qname="{{problem.name}}">Start</button> <!-- <button class="btn btn-danger btn-lg stop-button" type="button" data-qname="all">Stop</button> --> Loading