diff --git a/server/static/css/simulation.css b/server/static/css/simulation.css index ed16287..45babb5 100644 --- a/server/static/css/simulation.css +++ b/server/static/css/simulation.css @@ -67,7 +67,7 @@ body { } #Static { - width: 90%; + width: 1100px; top: 12%; left: 1%; z-index: 2; @@ -257,7 +257,7 @@ body { .static_box { float: left; width: 450px; - margin: 0 3% 0 3%; + margin: 0 20px 0 20px; } .search.icon { @@ -345,10 +345,10 @@ body { #static_adjust_box h3, #dynamic_adjust_box h3 { margin: 10px; - text-align: center; } .input_range { + margin-top:100px; height: 20px; position: relative; } @@ -367,13 +367,11 @@ output { background-image: -o-linear-gradient(top, #444444, #999999); background-image: -webkit-gradient(linear, left top, left bottom, from(#444444), to(#999999)); background-image: -webkit-linear-gradient(top, #444444, #999999); - width: 40px; height: 30px; text-align: center; color: white; border-radius: 10px; display: none; - font: bold 15px/30px Georgia; bottom: 180%; left: 0; margin-left: -1%; diff --git a/server/static/images/circuit/Terminator0.png b/server/static/images/circuit/terminator0.png similarity index 100% rename from server/static/images/circuit/Terminator0.png rename to server/static/images/circuit/terminator0.png diff --git a/server/static/images/circuit/Terminator1.png b/server/static/images/circuit/terminator1.png similarity index 100% rename from server/static/images/circuit/Terminator1.png rename to server/static/images/circuit/terminator1.png diff --git a/server/static/js/circuit.js b/server/static/js/circuit.js index c2f3db1..df8ca1d 100644 --- a/server/static/js/circuit.js +++ b/server/static/js/circuit.js @@ -1063,13 +1063,13 @@ Recommend.prototype.nextstep = function() { this.currentstep.addClass("active"); if (this.index < this.data.length) { for (var i = 0; i < this.data[this.index].length; ++i) { - var newlogic = new Logicitem(this.data[this.index][i], this); + var newlogic = new Logicitem(this.data[this.index][i], i, this); this.logiclist.append(newlogic.view); } } else { for (var i = 0; i < this.result.length; ++i) { - var newlogic = new Logicitem(this.result[i], this); - newlogic.view.unbind("click"); + var newlogic = new Logicitem(this.result[i], i, this); + newlogic.view.unbind("click"); this.logiclist.append(newlogic.view); } this.confirmbut.show(); @@ -1086,13 +1086,14 @@ Recommend.prototype.nextstep = function() { * * @description item object list in recommend */ -function Logicitem(data, parent) { +function Logicitem(data, index, parent) { var that = this; this.view = logic.clone(true); + this.index = index; this.data = data; this.view.find("img")[0].src = "../static/images/frame/" + data.name + ".png"; this.view.find(".label[name='name']").append(data.name); - this.view.find(".right").append("hello"); + this.view.find(".right").append("hello"); var radardata = { labels: ["Efficiency", "Realiability", "Accessiblity", "Demand", "Specificity"], datasets: [ @@ -1109,7 +1110,7 @@ function Logicitem(data, parent) { ] }; this.view.mouseenter(function() { - window.myRadar = new Chart(document.getElementById("recommendradar" + data.id).getContext("2d")).Radar(radardata, { + window.myRadar = new Chart(document.getElementById("recommendradar" + data.id + that.index).getContext("2d")).Radar(radardata, { responsive: true, angleLineColor : "rgba(255,255,255,.5)", scaleLineColor: "rgba(255,255,255,.5)" diff --git a/server/static/js/dna.js b/server/static/js/dna.js index 179dcad..f11a7ec 100644 --- a/server/static/js/dna.js +++ b/server/static/js/dna.js @@ -1,48 +1,32 @@ -/* 有命名片段的颜色列表 */ +/** + * @file dna.js + * @Control the components in dna page. + * @author Jiewei Wei + * @mail weijieweijerry@163.com + * @github https://github.com/JieweiWei + * @data Oct 19 2014 + * @copyright 2014 SYSU-Software. All rights reserved. + * + */ + +/* Color list. */ window.colors = { 'promoter' : 'rgb(255, 128, 0)', 'RBS': 'rgb(0, 127, 255)', 'terminator': 'rgb(210, 0, 0)', 'output': 'rgb(160, 32, 240)', - /* 默认颜色 */ 'biobrick_scar': 'rgb(128,128,128)', 'poly_A': 'rgb(128,128,128)', - /* 酶切位点颜色 */ - 'restriction': 'rgb(0,250,145)', }; -/* 每次DNA新增的行数 */ -LINE_OF_SHOW = 4; - -/* 定义一行所显示的DNA单元数目 */ +/* Number of rows in each new DNA. */ +window.LINE_OF_SHOW = 4; +/* The number of DNA cell line displayed. */ window.LEN_OF_LINE = 42; -/* 定义第二条链比第一条链浅色比例 */ +/* Color coefficient. */ window.COLOR_PERCENTAGE = 1.4; -/* 酶切片段 */ -window.restrictionPart = { - 'EcoRI': { - 'fir' : [[1,1,0,1], [1,0,1,1], [1,0,1,0], [1,0,1,0], [1,0,1,0], [1,1,0,0]], - 'sec' : [[0,0,1,1], [1,0,1,0], [1,0,1,0], [1,0,1,0], [1,1,1,0], [0,1,1,1]], - 'firStr' : 'GAATTC', - }, - 'XbaI': { - 'fir' : [[1,1,0,1], [1,0,1,1], [1,0,1,0], [1,0,1,0], [1,0,1,0], [1,1,0,0]], - 'sec' : [[0,0,1,1], [1,0,1,0], [1,0,1,0], [1,0,1,0], [1,1,1,0], [0,1,1,1]], - 'firStr' : 'TCTAGA', - }, - 'SpeI': { - 'fir' : [[1,1,0,1], [1,0,1,1], [1,0,1,0], [1,0,1,0], [1,0,1,0], [1,1,0,0]], - 'sec' : [[0,0,1,1], [1,0,1,0], [1,0,1,0], [1,0,1,0], [1,1,1,0], [0,1,1,1]], - 'firStr' : 'ACTAGT', - }, - 'PstI': { - 'fir' : [[0,1,0,0], [1,0,1,1], [1,0,1,0], [1,0,1,0], [1,1,1,0], [0,0,0,1]], - 'sec' : [[0,1,0,0], [1,0,1,1], [1,0,1,0], [1,0,1,0], [1,1,1,0], [0,0,0,1]], - 'firStr' : 'CTGCAG', - }, -}; -/* 获取输入和输出名字 */ +/* Get input and output data. */ $(function() { $("#progress").modal('setting', 'closable', false).modal("show"); var preprocess = JSON.parse(sessionStorage.getItem('preprocess')); @@ -88,7 +72,7 @@ $(function() { } }); -/* 获取DNA链的数据 */ +/* Get dna data. */ $(function() { var circuits = JSON.parse(sessionStorage.getItem('circuits')); if (circuits == null) { @@ -102,9 +86,8 @@ $(function() { } }); -/* 初始化DNA双链 */ +/* Init dna. */ $(function () { - /* 已经显示的行 */ strHaveShow = 0; allFrtStr = ''; for (var i = 0; i < dnaData.length; ++i) { @@ -113,7 +96,14 @@ $(function () { reArrange(); }); -/* DNA双链匹配工具函数 */ + +/** + * @dna match. + * + * @param {astrand} one of astrand of dna. + * + * @return another astrand of dna. + */ function MatchDNA(astrand) { var dnaMatch = { 'A' : 'T', 'T' : 'A', 'C' : 'G', 'G' : 'C', @@ -125,37 +115,27 @@ function MatchDNA(astrand) { return otherStrand; } -/* 根据第一条链重整DNA双链 */ +/* Arrange the secone astrand according to the first astrand. */ function reArrange() { frtStr = allFrtStr.substr(strHaveShow, LEN_OF_LINE * LINE_OF_SHOW); strHaveShow += frtStr.length; - // $('.dna_line').remove(); for (var i = 0; i < frtStr.length; i += LEN_OF_LINE) { var line1Str = frtStr.substr(i, LEN_OF_LINE); var line2Str = MatchDNA(line1Str); var tagTR = $('
'); var frtTR = $('
'); var sndTR = $('
'); - //var frtTR = $('
'); - //var sndTR = $('
'); - //var unitTR = $('
'); for (var j = 0; j < line1Str.length; ++j) { tagTR.append($(' ')); - // frtTR.find('input').val(frtTR.find('input').val()+line1Str[j]).prop('disabled', 'disabled'); frtTR.append($('' + line1Str[j] + '')); - // sndTR.find('input').val(sndTR.find('input').val()+line2Str[j]).prop('disabled', 'disabled'); sndTR.append($(''+ line2Str[j] + '')); - //unitTR.append($(' ')); } $('
') .append(tagTR).append(frtTR) .append(sndTR) - //.append(unitTR) .appendTo($('#dna_content')); } initColor(); - //changeDNA(); - //selectBoth(); setName(); } @@ -171,14 +151,13 @@ $('#dna_content').scroll(function(){ $(function() { $('#showNewDna').click(function() { reArrange(); - // alert(parseInt(allFrtStr.length / LEN_OF_LINE)); if (strHaveShow == allFrtStr.length) { $(this).hide(); } }); }); -/* 在标签栏添加片段名称 */ +/* Add tag name. */ $(setName = function() { var lens = 0; for (var i = 0; i < dnaData.length; ++i) { @@ -187,7 +166,7 @@ $(setName = function() { } }); -/* 初始化所有链的颜色 */ +/* Init color. */ $(initColor = function () { var left = 0, right = dnaData[0][2].length; for (var i = 0; i < dnaData.length-1; ++i) { @@ -200,156 +179,10 @@ $(initColor = function () { } }); -/* 获取第二条链的颜色 */ +/* Get color of second astrand. */ function getSecondColor(color) { var rgb = color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i); return 'rgb(' + parseInt(parseInt(rgb[1])*COLOR_PERCENTAGE) + ',' + parseInt(parseInt(rgb[2])*COLOR_PERCENTAGE) + ',' + parseInt(parseInt(rgb[3])*COLOR_PERCENTAGE) + ')'; } - -// function chanegColor(frtStrand, lens, colors) { -// frtStrand.children('span').each(function() { -// var curSpanIndex = $(this).prevAll('span').length; -// var curIndex = frtStrand.parent('.dna_line').prevAll().length * LEN_OF_LINE + curSpanIndex; -// var i = 0; -// for (; i < lens.length; ++i) { -// if (curIndex <= lens[i]) { -// break; -// } -// } -// $(this).css('background-color', colors[i]); -// var color = $(this).css('background-color'); -// var rgb = color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i); -// color = 'rgb(' + parseInt(parseInt(rgb[1])*COLOR_PERCENTAGE) + ',' -// + parseInt(parseInt(rgb[2])*COLOR_PERCENTAGE) + ',' -// + parseInt(parseInt(rgb[3])*COLOR_PERCENTAGE) + ')'; -// frtStrand.next().children('span').eq(curSpanIndex) -// .css('background-color', color); -// }); -// } - - /* 判断输入是否为AGCT或者agct */ -//function isUnit(event) { -// return event.which == 65 || event.which == 71 || -// event.which == 67 || event.which == 84 || -// event.which == 97 || event.which == 103 || -// event.which == 99 || event.which == 116; -//} - -/* 第二条链根据第一条链改变 */ -//$(changeDNA = function () { -// $('.first_strand').keypress(function(event) { -// /* 只能输入AGCT和agct */ -// if (isUnit(event)) { -// return true; -// } else { -// return false; -// } -// }).keyup(function(event) { -// /* 当输入AGCT,agct或者回退键结束后重整DNA链 */ -// if (isUnit(event) || event.keyCode == 8) { -// var curIndex = $(this).parents('.dna_line').prevAll().length; -// var cursorPos = $(this).getCursorPosition(); -// var fstAll = ''; -// $('.first_strand').each(function() { -// fstAll += $(this).val(); -// }); -// reArrange(fstAll.toUpperCase()); -// $('.first_strand').eq(curIndex).selectRange(cursorPos, cursorPos); -// } -// }); -//}); - -/* 是否进行多行选择 */ -//window.isMultiLine = false; - -/* 两条链同步选中 */ -//$(selectBoth = function() { -// $('.first_strand').select(function(event) { -// var cursorR = $(this).getCursorRange(); -// for (var i = cursorR.start+1; i <= cursorR.end; ++i) { -// $(this).parent().find('span:nth-of-type('+i+')') -// .css('background-color', 'rgb(255, 255, 0)'); -// $(this).parent().next().find('span:nth-of-type('+i+')') -// .css('background-color', 'rgba(255, 255, 0, 0.6)'); -// } -// var offset = $(this).parent() -// .find('span:nth-of-type('+cursorR.start+')').offset(); -// var top = offset.top; -// var left = offset.left; -// /* 点击按钮出现评论框 */ -// $('#dna_aside button:eq(1)').show().click(function(event) { -// $('#dna_modal_box').css({'top': top+'px', 'left': left+'px',}) -// .show().find('input').focus(); -// }); -// }).keydown(function(event) { -// /* 输入AGCT,agct,CTRL或者方向键入 */ -// if (isUnit(event) || event.keyCode == 8 || -// event.which >= 37 && event.which <= 40) { -// initColor(); -// } -// }).click(function(event) { -// if (!isMultiLine) { -// initColor(); -// } -// }).keydown(function(event) { -// isMultiLine = event.which == 17; -// }).keyup(function() { -// isMultiLine = false; -// }); -//}); - -/* 左键点击后评论框和评论按钮消失 */ -/* 左键点击后,颜色初始化 */ -//$(function() { -// $('body').click(function() { -// $('#dna_aside button:eq(1)').hide(); -// }).not('#comment_button').click(function() { -// if ($('#dna_modal_box').css('display') == 'none') { -// initColor(); -// } -// }); -//}); - -/* 输入评论 */ -//$(function() { -// $('#dna_modal_box').find('input').change(function() { -// $('#dna_modal_box').hide(); -// }).keydown(function(event) { -// /* 输入回车隐藏评论框 */ -// if (event.which == 13) { -// $('#dna_modal_box').hide(); -// } -// }); -// $('#dna_modal_box .remove').click(function() { -// $('#dna_modal_box').hide(); -// }); -//}); -// -// -///* 找出未标记DNA的酶切位点 */ -//$(function() { -// var circuits = JSON.parse(sessionStorage.getItem('circuits')); -// for (var k = 0; k < circuits.length; ++k) { -// var dna = circuits[k]['dna']; -// var start = 0; -// for (var i = 0; i < dna.length; ++i) { -// if (dna[i][1] == 'biobrick_scar' || dna[i][1] == 'poly_A') { -// var indexs = new Array(); -// for (var name in restrictionPart) { -// var index = dna[i][2].indexOf(restrictionPart[name]['firStr']) -// if (index >= 0) { -// $('.first_line span:eq('+start+'):gt('+start+'):lt('+(start+index)+')').css('background-color', colors['restriction']); -// $('.second_line span:eq('+start+'):gt('+start+'):lt('+(start+index)+')').css('background-color', getSecondColor(colors['restriction'])); -// } -// } -// } -// start += dna[i][2].length; -// } -// } -// }); -// -// $(document).ready(function() { -// $("#progress").modal("show"); -// }); diff --git a/server/static/js/graphiti/Connection.js b/server/static/js/graphiti/Connection.js index ce8ee80..d80dcb4 100644 --- a/server/static/js/graphiti/Connection.js +++ b/server/static/js/graphiti/Connection.js @@ -54,6 +54,7 @@ init: function() { this.regulated = false; this.draggable = false; + this.selectable = false; //this.Activator = new g.Buttons.Activate(); //this.Repressor = new g.Buttons.Inhibit(); //this.remove = new g.Buttons.Remove(); diff --git a/server/static/js/input-range.js b/server/static/js/input-range.js index c44d8d1..ec356fd 100644 --- a/server/static/js/input-range.js +++ b/server/static/js/input-range.js @@ -1,13 +1,13 @@ -$(function() { +$(ShowOutput = function() { var el, newPoint, newPlace, offset; - $(".adjust_input").change(function() { + $(".adjust_input").unbind('mouseup').bind('mouseup', function() { el = $(this); width = el.width(); newPoint = (el.val() - el.attr("min")) / (el.attr("max") - el.attr("min")); if ($(this).parent().prop('id') == 'static_adjust_input') { offset = 15.5; } else { - offset = 8.6; + offset = 8; } if (newPoint < 0) { newPlace = 0; } else if (newPoint > 1) { newPlace = width; } diff --git a/server/static/js/main.js b/server/static/js/main.js index 43cf0ca..5da4bac 100644 --- a/server/static/js/main.js +++ b/server/static/js/main.js @@ -51,7 +51,7 @@ $(document).ready(function() { $("#showIndex").mouseleave(function() { $(this).find("span").hide(); $(this).find("span").empty(); - $(this).find("span").append("Flame"); + $(this).find("span").append("FLAME"); $(this).find("span").show("slow"); }); diff --git a/server/static/js/shape-view.js b/server/static/js/shape-view.js index d63ca4f..9aa6068 100644 --- a/server/static/js/shape-view.js +++ b/server/static/js/shape-view.js @@ -198,7 +198,7 @@ g.Application = Class.extend({ shape.selectable = false; shape.draggable = false; this.views[0].addFigure(shape, this.baseX, this.baseY); - this.label = new graphiti.shape.basic.Label("2070bp"); + this.label = new graphiti.shape.basic.Label("pSB1C3(2070bp)"); this.label.setColor("#0d0d0d"); this.label.setFontColor("#0d0d0d"); this.label.setFontSize(radius / 10); @@ -479,7 +479,7 @@ g.Shapes.Circuit = graphiti.shape.basic.Rectangle.extend({ if (figure.hitTest(x, y) == true) { if (result === null) { result = figure; - } else if (result.getZOrder() < figure.getZOrder()) { + } else if (result.getZOrder() < figure.getZOrder() && figure.NAME != "graphiti.Gate" && figure.NAME != "graphiti.Connection") { result = figure; } } @@ -569,7 +569,7 @@ g.Shapes.Part = graphiti.shape.basic.Rectangle.extend({ if (child.hitTest(x, y) == true) { if (result === null) { result = child; - } else if (result.getZOrder() < figure.getZOrder()) { + } else if (result.getZOrder() < figure.getZOrder() && figure.NAME != "graphiti.Connection") { result = child; } } @@ -655,15 +655,15 @@ g.Shapes.Logic = graphiti.shape.basic.Rectangle.extend({ var inputpart = new g.Shapes.Part(logic.inputparts[0], "input"); this.addItem(inputpart); } else { + var gate = new g.Gate(logic.logic_type, this.gateWidth, this.gateHeight); + this.addItem(gate); var lastpartlength = logic.outputparts[partslength - 1].length; logic.outputparts[partslength - 1][lastpartlength - 2].type = "outputfinal"; var outputpart = new g.Shapes.Part(logic.outputparts[0], "output"); this.addItem(outputpart); if (logic.logic_type === "inverter") { this.gateWidth += 100; - } - var gate = new g.Gate(logic.logic_type, this.gateWidth, this.gateHeight); - this.addItem(gate); + } } }, @@ -730,7 +730,7 @@ g.Shapes.Logic = graphiti.shape.basic.Rectangle.extend({ if (figure.hitTest(x, y) == true) { if (result === null) { result = figure; - } else if (result.getZOrder() < figure.getZOrder()) { + } else if (result.getZOrder() < figure.getZOrder() && figure.NAME != "graphiti.Gate" && figure.NAME != "graphiti.Connection") { result = figure; } } @@ -814,15 +814,14 @@ g.Shapes.VectorBiobrick = graphiti.shape.icon.Icon.extend({ this.label.setColor("#0d0d0d"); this.label.setFontColor("#0d0d0d"); this.label.setFontSize(8); - var locator; if (angle < 5.0 * 3.1415926 / 6.0) { - locator = new graphiti.layout.locator.RightLocator(this); + this.locator = new graphiti.layout.locator.RightLocator(this); } else if (angle > 7.0 * 3.1415926 / 6.0) { - locator = new graphiti.layout.locator.LeftLocator(this); + this.locator = new graphiti.layout.locator.LeftLocator(this); } else { - locator = new graphiti.layout.locator.BottomLocator(this); + this.locator = new graphiti.layout.locator.BottomLocator(this); } - this.addFigure(this.label, locator); + this.addFigure(this.label, this.locator); }, onClick: function() { @@ -844,8 +843,8 @@ g.Shapes.VectorBiobrick = graphiti.shape.icon.Icon.extend({ e.figure.setCanvas(null); that.children.remove(e.figure); } - }); - this.addFigure(this.label, new graphiti.layout.locator.RightLocator(this)); + }); + this.addFigure(this.label, this.locator); this.repaint(); } }); @@ -853,7 +852,7 @@ g.Shapes.VectorBiobrick = graphiti.shape.icon.Icon.extend({ g.Gate = graphiti.shape.icon.Icon.extend({ - NAME : "graphiti.Buttons.Back", + NAME : "graphiti.Gate", /** * diff --git a/server/static/js/simulation-ctrl.js b/server/static/js/simulation-ctrl.js index 28bad1f..b0ebc7a 100644 --- a/server/static/js/simulation-ctrl.js +++ b/server/static/js/simulation-ctrl.js @@ -9,6 +9,12 @@ * */ +/* The horizontal accuracy in static graph. */ +window.STATIC_PRECISION_X = 4; + +/* The horizontal accuracy in dynamic graph. */ +window.DYNAMIC_PRECISION_X= 2; + /* Switching tabs of #simulation_main_draw. */ $(function() { $('#simulation_main_draw>div').click(function() { @@ -131,22 +137,6 @@ function PrecisionControl(dataArray, p) { return dataArray_; } -/** - * @Retain p decimal places by Scientific notation. - * - * @param {dataArray} array of float. - * - * @param {p} accuracy. - * - *@return array with p decimal places by Scientific notation. - */ -function ArrayToExponential(dataArray, p) { - var dataArray_ = []; - for (var i = 0; i < dataArray.length; ++i) { - dataArray_.push(dataArray[i].toExponential(p)); - } - return dataArray_; -} /* Chart all graphs. */ function ChartAllGraphs() { @@ -157,7 +147,7 @@ function ChartAllGraphs() { staticDrawData[curCircuit]['y'] ); } else { - alert('Simulate Error'); + //alert('Simulate Error'); } DrawDynamicPerformance( PrecisionControl(dynamicDrawData[curCircuit]['x'], DYNAMIC_PRECISION_X), @@ -180,9 +170,11 @@ $(function() { data: JSON.stringify(reactionInfos[curCircuit]), async: false, success: function(dynamicData) { + /* Record the time interval in the current circuit. */ + recordAdjustValues[curCircuit]['t'] = reactionInfos[curCircuit]['t']; + dynamicDrawData[curCircuit]['x'] = dynamicData['t']; dynamicDrawData[curCircuit]['y'] = dynamicData['c']; - ChartAllGraphs(); $('#show_dynamic_box').click(); }, @@ -195,7 +187,8 @@ $(function() { /* Adjust the concentration of anther input. */ $(AdjustStatic = function() { - $('#static_adjust_box input[type=range]').change(function() { + //ShowOutput(); + $('#static_adjust_box input[type=range]').unbind('change').bind('change', function() { var adjustVar = $(this).prop('id'); reactionInfos[curCircuit]['c_static'] = parseFloat($(this).val()); @@ -210,6 +203,9 @@ $(AdjustStatic = function() { for (var i = 0; i < staticData['c_output'].length; ++i) { var variable = staticData['c_output'][i]['variable']; if (adjustVar.indexOf(variable) < 0) { + /* Record the c_static of current circuit. */ + recordAdjustValues[curCircuit]['c_static'][adjustVar.substring(0, adjustVar.length-3)] = reactionInfos[curCircuit]['c_static']; + staticDrawData[curCircuit]['y'][i] = staticData['c_output'][i]; ChartAllGraphs(); $('.show_static_box').eq(i).click(); @@ -239,14 +235,15 @@ function SetCircuits () { 'RBS' : 'RBS2.png', 'terminator': 'terminator2.png', }; - + var logic = logics[curCircuit][curLogic]; var allParts = logic['inputparts'].concat(logic['outputparts']); for (var m = 0; m < allParts.length; ++m) { var newLine = $( '' + '
' + - '' + + '' + '' ); for (var n = 0; n < allParts[m].length; ++n) { @@ -272,12 +269,70 @@ function SetCircuits () { } newLine.appendTo($('#simulation_adjust_main tbody')); } - + AdjustRBS(); }; -/* 调节RIPS */ -$(function() { - $('.adjust_line input[type=range]').change(function() { +/* Adjust RIPS. */ +$(AdjustRBS = function() { + $('.adjust_line input[type=range]').unbind('change').bind('change', function() { + var index = $(this).parent().parent('.adjust_line').prev().length; + /* Modify RBS. */ + var RBS = RBSList[$(this).val()]; + /* Record the RBS type. */ + recordAdjustValues[curCircuit]['circuitRBS'][curLogic][index] = parseInt($(this).val()); + + var curPart = $(this).parent().prev('td').children('.part'); + curPart.eq(1).find('.ui.label.labelbg').text(RBS); + + /* Modify the curve. */ + var outputName = curPart.eq(2).find('.ui.label.labelbg').text(); + reactionInfos[curCircuit]['output_RBS'][outputName] = RBS; + /* Get static data. */ + $.ajax({ + type: 'POST', + url: '/simulation/simulate/static', + contentType: 'application/json', + dataType: 'json', + data: JSON.stringify(reactionInfos[curCircuit]), + async: false, + complete: function(data) { + if (data.responseText.indexOf('NaN') >= 0) { + staticDrawData[curCircuit] = { + 'x': undefined, + 'y': undefined, + }; + } else { + var staticData = JSON.parse(data.responseText); + staticDrawData[curCircuit] = { + 'x': staticData['c_input'], + 'y': staticData['c_output'], + }; + } + }, + fail: function() { + $("#nodata").modal("show"); + }, + }); + + /* Get dynamic data. */ + $.ajax({ + type: 'POST', + url: '/simulation/simulate/dynamic', + contentType: 'application/json', + dataType: 'json', + data: JSON.stringify(reactionInfos[curCircuit]), + async: false, + success: function(dynamicData) { + dynamicDrawData[curCircuit] = { + 'x': dynamicData['t'], + 'y': dynamicData['c'], + }; + }, + fail: function() { + $("#nodata").modal("show"); + }, + }); + ChartAllGraphs(); }); }); diff --git a/server/static/js/simulation-data.js b/server/static/js/simulation-data.js index 38b92b6..1e20e9a 100644 --- a/server/static/js/simulation-data.js +++ b/server/static/js/simulation-data.js @@ -15,24 +15,16 @@ window.TIME = 60; /* Default concentration of reactants. */ window.CONCENTRATION = 1e-9; +/* Default ajust concentration of reactants. */ +window.ADJUST_CONCENTRATION = 0.0001; + /* Fixed concentration of defaults. */ window.FIXED_C = CONCENTRATION; -/* The horizontal accuracy in static graph. */ -window.STATIC_PRECISION_X = 4; - -/* The horizontal accuracy in dynamic graph. */ -window.DYNAMIC_PRECISION_X= 2; - -/* The Vertical accuracy in static graph. */ -window.STATIC_PRECISION_Y = 3; - -/* The Vertical accuracy in dynamic graph. */ -window.DYNAMIC_PRECISION_Y = 3; /* Access to relevant data of all circuits. */ $(function() { - var reactionData = JSON.parse(sessionStorage.getItem('preprocess')); + window.reactionData = JSON.parse(sessionStorage.getItem('preprocess')); if (reactionData == null || reactionData.length == 0) { $("#nodata").modal("show"); } else { @@ -124,30 +116,62 @@ $(function() { } }); -/** - * @Get RIPS of current logic of current circuit. - * - * @return a directory of RIPS of current logic of current circuit. - * - */ -function GetCurRIPS() { - var RIPS = {}; - var logic = logics[curCircuit][curLogic]; - if (logic['logic_type'] == 'toggle_switch_1') { - } else if (logic['logic_type'] == 'toggle_switch_2') { - } else if (logic['logic_type'] == 'simple_logic') { - } else if (logic['logic_type'] == 'or_gate') { - } else { - var allParts = logic['inputparts'].concat(logic['outputparts']); - for (var i = 0; i < allParts.length; ++i) { - var url = '/biobrick/' + (i < logic['inputparts'].length ? 'input' : 'output') + '?id=' + allParts[i][1]['id']; - alert(url); - $.get(url, function(data) { - console.log(data); - }) +/* Get RIPS of current logic of current circuit. */ +$(function() { + window.RBSList = []; + $.ajax({ + url: '/biobrick/RBS', + contentType: 'application/json', + dataType: 'json', + async: false, + success: function(data) { + for (var i = 0; i < data['result'].length; ++i) { + RBSList.push(data['result'][i]['name']); + } + }, + fail: function() { + $("#nodata").modal("show"); + }, + }); +}); + +$(function() { + /* Record the adjusted values. */ + window.recordAdjustValues = []; + /* For each circuit. */ + for (var i = 0; i < logics.length; ++i) { + recordAdjustValues.push({ + 't': TIME, + 'c_static': {}, + 'circuitRBS': [], + }); + for (var j = 0; j < reactionData.length; ++j) { + var input = reactionData[i]['inputs']; + for (var k = 0; k < input.length; ++k) { + $.ajax({ + url: '/biobrick/input?id=' + input[k]['id'], + type: 'GET', + contentType: 'application/json', + dataType: 'json', + async: false, + success: function(data) { + recordAdjustValues[i]['c_static'][data['result']['name']] = ADJUST_CONCENTRATION; + } + }); + } + } + /* For each logic. */ + for (var j = 0; j < logics[i].length; ++j) { + var allParts = logics[i][j]['inputparts'].concat(logics[i][j]['outputparts']); + var logicRBS = []; + /* For each part. */ + for (var k = 0; k < allParts.length; ++k) { + logicRBS.push($.inArray(allParts[k][1]['name'] ,RBSList)); + } + recordAdjustValues[i]['circuitRBS'].push(logicRBS); } } -}; +}); /* Show data in console for test. */ function ShowData() { @@ -166,8 +190,16 @@ function ShowData() { console.log('logics: '); console.log(logics); + console.log('RBSList: '); + console.log(RBSList); + + console.log('recordAdjustValues: '); + console.log(recordAdjustValues); + return reactionInfos.length == circuits.length && - staticDrawData.length == circuits.length && - dynamicDrawData.length == circuits.length && - logics.length == circuits.length; + staticDrawData.length == circuits.length && + dynamicDrawData.length == circuits.length && + logics.length == circuits.length && + RBSList.length == 54 && + recordAdjustValues.length == circuits.length; } diff --git a/server/static/js/simulation-draw.js b/server/static/js/simulation-draw.js index 190ce80..fa5498e 100644 --- a/server/static/js/simulation-draw.js +++ b/server/static/js/simulation-draw.js @@ -9,64 +9,95 @@ * */ +/* Color output curve. */ +window.OUTPUT_COLORS = ['#FF0000', '#00FF00', '#0000FF']; + +/* The number of horizontal displayed points in dynamic graph. */ +window.NUM_OF_SCALE = 10; + +/* The Vertical accuracy in graph. */ +window.PRECISION_Y = 3; + /* Common property of line graph. */ window.SAME_PROPERTIES = { - align: 'center', - tip: { - enable: true, - shadow: true, - move_duration: 400, - border: { - enable: true, - radius: 5, - width: 0, - }, - }, - legend: { - enable: true, - row: 1, - column: 'max', - valign: 'top', - sign: 'bar', - background_color: null, - offsetx: -80, - border: true, - color: 'gray', - }, - sub_option: { - smooth : true, - label: false, - point_size: 0, - }, - subtitle: { - text: 'concentration of output(s)/mM', - fontsize:12, - color:'gray', - textAlign:'left', - padding:'0 0 0 0', - height:30 - }, - background_color: null, + align: 'center', + tip: { + enable: true, + shadow: true, + move_duration: 400, border: { - enable: false, - width:0, + enable: true, + radius: 5, + width: 0, }, listeners: { parseText:function(tip,name,value,text,i){ - return name + " : " + value; - } + return name + " : " + (parseFloat(value).toFixed(PRECISION_Y)); }, - crosshair: { - enable:true, - line_color:'#62bce9', - } + }, + }, + legend: { + enable: true, + row: 1, + column: 'max', + valign: 'top', + sign: 'bar', + background_color: null, + offsetx: -80, + border: true, + color: 'gray', + }, + sub_option: { + smooth : true, + label: false, + point_size: 0, + }, + background_color: null, + border: { + enable: false, + width:0, + }, + crosshair: { + enable:true, + line_color:'#62bce9', + }, }; -/* Color output curve. */ -window.OUTPUT_COLORS = ['#D95C5C', '#6ECFF5', '#00B5AD']; - -/* The number of horizontal displayed points in dynamic graph. */ -window.NUM_OF_SCALE = 10; +/** + * @Adjustment data accuracy. + * + * @param {rowData} raw data. + * + * @return {data} data adjusted. + * + * @return {min} the accuracy. + * + */ +function AdjustDataY(rowData) { + var newData = new Array(); + var minAll = 999999; + for (var key in rowData) { + var min = 99999; + for (var i = 0; i < rowData[key].length; ++i) { + var num = parseFloat(rowData[key][i]).toExponential(PRECISION_Y) ; + var e = parseInt(num.split('e')[1]); + if (e < min) { + min = e; + } + } + if (min < minAll) { + minAll = min; + } + } + for (var key in rowData) { + var aNewData = new Array(); + for (var i = 0; i < rowData[key].length; ++i) { + aNewData.push(rowData[key][i] * Math.pow(10, -minAll)) + } + newData[key] = aNewData; + } + return {'data': newData, 'e': minAll}; +} /** * @Create static_box. @@ -104,15 +135,22 @@ function DrawStaticPerformance(labels, output) { CreateStaticBox(output.length); inputDatas = new Array(); + var es = new Array(); for (var i = 0; i < output.length; ++i) { var inputData = new Array(); inputData['var'] = output[i]['variable']; inputData['output'] = []; var count = 0; + var rowData = new Array(); + for (var outputName in output[i]['c']) { + rowData[outputName] = output[i]['c'][outputName]; + } + var newData = AdjustDataY(rowData); + es.push(newData['e']); for (var outputName in output[i]['c']) { inputData['output'].push({ name: outputName, - value: ArrayToExponential(output[i]['c'][outputName], STATIC_PRECISION_Y), + value: newData['data'][outputName], color: OUTPUT_COLORS[count++], line_width: 3, }); @@ -133,14 +171,22 @@ function DrawStaticPerformance(labels, output) { tip: SAME_PROPERTIES['tip'], legend: SAME_PROPERTIES['legend'], sub_option: SAME_PROPERTIES['sub_option'], - subtitle: SAME_PROPERTIES['subtitle'], + subtitle: { + text: 'Concentration of output(s)/10^' + es[i] + 'mM', + fontsize:12, + color:'gray', + textAlign:'left', + padding:'0 0 0 0', + height:30, + }, + crosshair: SAME_PROPERTIES['crosshair'], footnote:{ text: inputDatas[i]['var']+'/mM', padding:'20 20', height:30, }, coordinate: { - width: 380, + width: 360, height: 250, grid_color: 'gray', axis:{ @@ -162,7 +208,6 @@ function DrawStaticPerformance(labels, output) { width:0, }, }); - /* Pain the graph. */ var chart = new iChart.LineBasic2D(chartDirs[i]); chart.draw(); @@ -181,12 +226,17 @@ function DrawDynamicPerformance(tLabel, data) { var allData = new Array(); var count = 0; + var rowData = new Array(); + for (var key in data) { + rowData[key] = data[key]; + } + var newData = AdjustDataY(rowData); for (var key in data) { allData.push({ - name: key, - value: ArrayToExponential(data[key], DYNAMIC_PRECISION_Y), - color: OUTPUT_COLORS[count++], - line_width: 3, + name: key, + value: newData['data'][key], + color: OUTPUT_COLORS[count++], + line_width: 3, }); } @@ -200,8 +250,16 @@ function DrawDynamicPerformance(tLabel, data) { height : 320, background_color: SAME_PROPERTIES['background_color'], footnote: SAME_PROPERTIES['footnote'], + crosshair: SAME_PROPERTIES['crosshair'], tip: SAME_PROPERTIES['tip'], - subtitle: SAME_PROPERTIES['subtitle'], + subtitle: { + text: 'Concentration of output(s)/10^' + newData['e'] + 'mM', + fontsize:12, + color:'gray', + textAlign:'left', + padding:'0 0 0 0', + height:30 + }, footnote:{ text: 'time/min', padding:'20 20', @@ -248,17 +306,20 @@ $(ShowStaticModal = function() { /* Modify the properties of the graph. */ chartDirs[index].render = 'showgraph'; - chartDirs[index]['tip']['listeners'] = SAME_PROPERTIES['listeners']; - chartDirs[index]['crosshair'] = SAME_PROPERTIES['crosshair']; chartDirs[index].width = 780; chartDirs[index].height = 400; chartDirs[index].coordinate.width = 650; chartDirs[index].coordinate.height = 350; + var anotherVarName = chartDirs[negate[index]]['footnote']['text']; $('#dynamic_adjust_box').hide(); $('#static_adjust_box').show() - .find('h3').text('concentration of ' + chartDirs[negate[index]]['footnote']['text']); - $('#static_adjust_box').find('input[type=range]').prop('id', chartDirs[negate[index]]['footnote']['text']); - + .find('h3').text('Concentration of ' + anotherVarName); + $('#static_adjust_box') + .find('input[type=range]') + .prop('id', anotherVarName) + /* Set time interval value. */ + .val(recordAdjustValues[curCircuit]['c_static'][anotherVarName.substring(0, anotherVarName.length-3)]); + $('.adjust_input').mouseup(); /* Chart the graph in the modal box. */ var chart = new iChart.LineBasic2D(chartDirs[index]); chart.draw(); @@ -278,13 +339,15 @@ $(function() { /* Modify the properties of the graph. */ chartDir.render = 'showgraph'; - chartDir['tip']['listeners'] = SAME_PROPERTIES['listeners']; - chartDir['crosshair'] = SAME_PROPERTIES['crosshair']; chartDir.width = 780; chartDir.height = 400; chartDir.coordinate.width = 630; chartDir.coordinate.height = 350; - $('#dynamic_adjust_box').show(); + $('#dynamic_adjust_box') + .show() + /* Set time interval value. */ + .find('input[type=range]').val(recordAdjustValues[curCircuit]['t']); + $('.adjust_input').mouseup(); $('#static_adjust_box').hide(); /* Chart the graph in the modal box. */ diff --git a/server/templates/simulation.html b/server/templates/simulation.html index 857bff4..f905516 100644 --- a/server/templates/simulation.html +++ b/server/templates/simulation.html @@ -54,17 +54,17 @@

Concentration of input

0.0001 mM - 1 + 0.0001 1 mM
-

time interval

+

Time interval

20 min - + 60 min - 580 min + 600 min
diff --git a/server/views/__init__.py b/server/views/__init__.py index 2afc228..1c9d404 100644 --- a/server/views/__init__.py +++ b/server/views/__init__.py @@ -1,4 +1,4 @@ -from flask import render_template +from flask import render_template, redirect, url_for from .. import app @app.route('/') @@ -6,7 +6,11 @@ def index(): return render_template('circuit.html') @app.route('/') def goto(path): - return render_template(path + '.html') + pages = ["circuit", "shape", "simulation", "experiment", "help"]; + for page in pages: + if path == page: + return render_template(path + '.html') + return render_template('circuit.html') from . import biobrick from . import design