add new result presentation & new simulation

This commit is contained in:
ColsonZhang 2021-03-23 20:49:24 +08:00
parent c90af4e313
commit 1fc0a79137
10 changed files with 299 additions and 43 deletions

View File

@ -59,6 +59,15 @@ app.py ----服务器的主程序
## 更新日志 ## 更新日志
* 2021年3月23号前端更新
* 新增:多种仿真模式下的数据显示
* 2021年3月22号后端更新
* bug1当放置同一种组件时名称存在重复手动更改名称后需要将组件进行移动后名称才会修改。
* bug2当进行组件的复制后将组件的部分元件进行调整将无法提取spice。
* bug3Tab的作用域问题希望Tab的openmode函数中加入作用域。
* 新增DC仿真处理
* 2021年3月20号前端更新 * 2021年3月20号前端更新
* 新增:仿真结果数据显示,成功将仿真得到的节点电压绘制出来。 * 新增:仿真结果数据显示,成功将仿真得到的节点电压绘制出来。

View File

@ -3,17 +3,20 @@
class Sim_Data_Container : class Sim_Data_Container :
def __init__(self): def __init__(self):
self.sim_type = {'transient':False,'ac':False,'dc':False} self.sim_type = {'transient':False,'ac':False,'dc':False}
# self.analysis = None
self.result = {} self.result = {}
print('container initial sucessfully !!!') print('container initial sucessfully !!!')
def load_analysis(self, simtype, analysis): def load_analysis(self, simtype, analysis):
print()
self.sim_type[simtype] = True self.sim_type[simtype] = True
# self.analysis = analysis
# print("loading analysising")
if(simtype == 'transient'): if(simtype == 'transient'):
self.parse_transient(analysis) self.parse_transient(analysis)
elif(simtype == 'dc'):
self.parse_dc(analysis)
elif(simtype == 'ac'):
pass
def del_analysis(self): def del_analysis(self):
@ -21,7 +24,7 @@ class Sim_Data_Container :
self.result = {} self.result = {}
def parse_transient(self, analysis): def parse_transient(self, analysis):
# print('parsing the transient analysising !!!')
result_tran = {} result_tran = {}
result_tran['time'] = [float(i) for i in analysis.time] result_tran['time'] = [float(i) for i in analysis.time]
result_tran['nodes_name'] = list(analysis.nodes.keys()) result_tran['nodes_name'] = list(analysis.nodes.keys())
@ -38,5 +41,24 @@ class Sim_Data_Container :
self.result['transient'] = result_tran self.result['transient'] = result_tran
def parse_dc(self, analysis):
result_dc = {}
result_dc['sweep'] = [float(i) for i in analysis.sweep]
result_dc['nodes_name'] = list(analysis.nodes.keys())
nodes = {}
nodes = {}
for i in result_dc['nodes_name'] :
nodes[i] = [float(j) for j in analysis.nodes[i]]
result_dc['nodes'] = nodes
result_dc['branches_name'] = list(analysis.branches.keys())
branches = {}
for i in result_dc['branches_name']:
branches[i] = [float(j) for j in analysis.branches[i]]
result_dc['branches'] = branches
self.result['dc'] = result_dc
def simulation_info_request(self, simtype): def simulation_info_request(self, simtype):
return self.result[simtype] return self.result[simtype]

View File

@ -30,7 +30,7 @@ class Simulator_CZ :
def Sim(self, sim_type,properties): def Sim(self, sim_type,properties):
parameter = self.Properties_Parse(sim_type,properties) parameter = self.Properties_Parse(sim_type,properties)
# print("parameter:\n",parameter) print("parameter:\n",parameter)
self.simulator = self.circuit.simulator(temperature=25, nominal_temperature=25) self.simulator = self.circuit.simulator(temperature=25, nominal_temperature=25)
# print('simulator:\n',self.simulator) # print('simulator:\n',self.simulator)
if(sim_type == 'transient'): if(sim_type == 'transient'):
@ -39,10 +39,22 @@ class Simulator_CZ :
start_time = parameter['start_time'], start_time = parameter['start_time'],
max_time = parameter['max_time'], max_time = parameter['max_time'],
use_initial_condition = parameter['use_initial_condition']) use_initial_condition = parameter['use_initial_condition'])
# print(self.analysis)
return self.analysis return self.analysis
elif(sim_type == 'dc' ): elif(sim_type == 'dc' ):
pass print("doing the dc simulation !!!")
src_name = parameter['src_name']
vstart = parameter['start']
vstop = parameter['stop']
vstep = parameter['step']
the_args = "{} = slice({},{},{})".format(src_name, vstart, vstop, vstep)
exec("self.analysis = self.simulator.dc( {} )".format(the_args))
print("dc simulation finished !!!")
# print(self.analysis)
return self.analysis
elif(sim_type == 'ac' ): elif(sim_type == 'ac' ):
pass pass
else: else:
@ -60,7 +72,11 @@ class Simulator_CZ :
parameter["use_initial_condition"] = self.unit_tran(properties["use_initial_condition"]) parameter["use_initial_condition"] = self.unit_tran(properties["use_initial_condition"])
elif(sim_type == 'dc' ): elif(sim_type == 'dc' ):
pass parameter["src_name"] = properties["src"]
parameter["start"] = properties["start"]
parameter["stop"] = properties["stop"]
parameter["step"] = properties["step"]
elif(sim_type == 'ac' ): elif(sim_type == 'ac' ):
pass pass
@ -116,6 +132,6 @@ class Simulator_CZ :
else: else:
the_num = float(0) the_num = float(0)
return the_num return the_num
pass

View File

@ -70,11 +70,18 @@ class SimulationInfoRequest_Handler(AuthBaseHandler):
def post(self,*args,**kwargs): def post(self,*args,**kwargs):
sim_type = self.get_argument('sim_type') sim_type = self.get_argument('sim_type')
print(sim_type)
sim_info = Container_SimResult.simulation_info_request(sim_type) sim_info = Container_SimResult.simulation_info_request(sim_type)
# sim_info = {'ab':1,'cd':2,'ef':'d2','hello':[1,2,3,4,5]} # sim_info = {'ab':1,'cd':2,'ef':'d2','hello':[1,2,3,4,5]}
print(sim_info)
sim_info_json = json.dumps( sim_info ) sim_info_json = json.dumps( sim_info )
# print('json transform ok !!') print('json transform ok !!')
self.write( sim_info_json ) self.write( sim_info_json )
print("send the simulation info request successfully!!!")
# self.write(json_decode(sim_info)) # self.write(json_decode(sim_info))
# self.write("successful") # self.write("successful")

View File

@ -1,37 +1,239 @@
// create some data and a ColumnDataSource /* bokeh.js
使用该文件前请现在html加载相关js文件*/
var source = new Bokeh.ColumnDataSource({ data: { x: [], y: [] } }); // 仿真结果数据
var SimResult = {} ;
var Flag_Refresh = {"transient":false,"dc":false,"ac":false} ;
var color_store = ["blue","brown","cyan","green","orange","pink","purple","red","whitesmoke","yellow"];
// create a data source to hold data
// var the_source = new Bokeh.ColumnDataSource({
// data: { x: [], y: [], color: [] }
// });
// make the plot function openMode_Bokeh(evt, tabMode) {
var plot = Bokeh.Plotting.figure({ var i, tabcontent, tablinks;
title: "BokehJS Plot", tabcontent = document.getElementsByClassName("tabcontent");
plot_width: 400, for (i = 0; i < tabcontent.length; i++) {
plot_height: 400, tabcontent[i].style.display = "none";
background_fill_color: "#F2F2F7" }
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(tabMode).style.display = "block";
evt.currentTarget.className += " active";
};
function plotPoint_tran() {
if(Flag_Refresh['transient'] == true){
the_source.data.x = [];
the_source.data.y = [];
the_source.data.color = [];
console.log("Flag_Refresh = true !");
var the_nodes_name = SimResult['transient']["nodes_name"];
var the_x = SimResult['transient']["time"];
for(var i=0; i < the_nodes_name.length; i++){
var the_y = SimResult['transient']["nodes"][the_nodes_name[i]] ;
the_source.data.x.push(the_x);
the_source.data.y.push(the_y);
the_source.data.color.push(color_store[i%color_store.length]);
}
the_source.change.emit();
}
else{
alert("The information has not been updated !!!");
}
};
function plotPoint_dc() {
if(Flag_Refresh['dc'] == true){
the_source.data.x = [];
the_source.data.y = [];
the_source.data.color = [];
console.log("Flag_Refresh = true !");
var the_nodes_name = SimResult['dc']["nodes_name"];
var the_x = SimResult['dc']["sweep"];
for(var i=0; i < the_nodes_name.length; i++){
var the_y = SimResult['dc']["nodes"][the_nodes_name[i]] ;
the_source.data.x.push(the_x);
the_source.data.y.push(the_y);
the_source.data.color.push(color_store[i%color_store.length]);
}
the_source.change.emit();
}
else{
alert("The information has not been updated !!!");
}
};
function plotPoint_ac() {
if(Flag_Refresh['ac'] == true){
the_source.data.x = [];
the_source.data.y = [];
the_source.data.color = [];
console.log("Flag_Refresh = true !");
var the_nodes_name = SimResult['ac']["nodes_name"];
var the_x = SimResult['ac']["fre"];
for(var i=0; i < the_nodes_name.length; i++){
var the_y = SimResult['ac']["nodes"][the_nodes_name[i]] ;
the_source.data.x.push(the_x);
the_source.data.y.push(the_y);
the_source.data.color.push(color_store[i%color_store.length]);
}
the_source.change.emit();
}
else{
alert("The information has not been updated !!!");
}
};
function PlotSimulationResult(sim_type){
if(sim_type == "transient"){
plotPoint_tran();
}
else if(sim_type == "dc"){
plotPoint_dc();
}
else if(sim_type == 'ac'){
plotPoint_ac();
}
};
function requestSimInfo(sim_type){
var data = new Object();
var sim_result ;
data["sim_type"] = sim_type;
console.log(sim_type);
console.log(data);
$.ajax({
type: 'POST',
url: "/getsiminfo",
data: data,
async:false, // 必须关闭异步!!!
dataType: "json",
success: function (siminfo) {
console.log("load sim result successfully !!");
sim_result = siminfo;
},
error: function(){
alert('ajax post failed !!!');
}
}); });
var count = 0 ; return sim_result ;
};
function Callback_Refresh(){
source.data.x = [];
source.data.y = [];
// var the_x = SimResult["time"];
var the_x = [2,4] ;
// var the_y = SimResult["nodes"][the_nodes_name[i]] ; function Callback_Refresh(sim_type){
var the_y = [1+count,3+count]; SimResult[sim_type] = requestSimInfo(sim_type);
source.data.x.push(the_x); Flag_Refresh[sim_type] = true;
source.data.y.push(the_y); };
count = count+1;
source.change.emit();
// bokeh组件相关变量
var bokeh_plot = [] ;
var the_source = {} ;
// 添加 Tab 组件
var sim_mode = ['transient', 'dc', 'ac'];
var div_node = document.createElement('div');
var div_tab = document.createElement('div');
div_tab.setAttribute('class','tab');
div_node.appendChild(div_tab);
var frame = $("#show_result");
frame.append(div_node);
for(var i=0; i<sim_mode.length; i++){
the_source[sim_mode[i]] = new Bokeh.ColumnDataSource({
data: { x: [], y: [], color: [] }
});
} }
plot.multi_line({field:"x"},{field:"y"},{source:source}); // 创建tab
// plot.multi_line([[1,2,3],[1,2,3]],[[2,4,6],[7,8,9]]); for(var i=0; i<sim_mode.length; i++){
var div_mode = document.createElement('button');
div_mode.setAttribute('class',"tablinks");
div_mode.setAttribute('onclick',"openMode_Bokeh(event, 'ShowResult"+ sim_mode[i] +"')");
Bokeh.Plotting.show(plot,'#bokeh_01'); div_mode.innerHTML = sim_mode[i] ;
div_tab.appendChild(div_mode);
};
for(var i=0; i<sim_mode.length; i++){
var div_mode = document.createElement('div');
div_mode.setAttribute('class',"tabcontent");
div_mode.setAttribute('id',"ShowResult"+sim_mode[i]);
var div_plot = document.createElement('div');
div_plot.setAttribute('id', 'ResultPlot'+sim_mode[i] );
div_mode.appendChild(div_plot);
var div_button = document.createElement('div');
div_button.setAttribute('id', 'button'+sim_mode[i] );
div_mode.appendChild(div_button);
div_node.appendChild(div_mode);
var RefreshButton = document.createElement("Button"); var RefreshButton = document.createElement("Button");
RefreshButton.appendChild(document.createTextNode("Refresh")); RefreshButton.appendChild(document.createTextNode("Refresh"));
document.currentScript.parentElement.appendChild(RefreshButton); document.currentScript.parentElement.appendChild(RefreshButton);
RefreshButton.addEventListener("click", Callback_Refresh); // RefreshButton.addEventListener("click", Callback_Refresh);
RefreshButton.onclick = function(){
Callback_Refresh(sim_mode[i]);
};
div_button.appendChild(RefreshButton);
var addDataButton = document.createElement("Button");
addDataButton.appendChild(document.createTextNode("Plot"));
document.currentScript.parentElement.appendChild(addDataButton);
// addDataButton.addEventListener("click", plotPoint_tran);
addDataButton.onclick = function(){
PlotSimulationResult(sim_mode[i]);
};
div_button.appendChild(addDataButton);
// div_tab.appendChild(div_mode);
};
for(var i=0; i<sim_mode.length; i++){
bokeh_plot[i] = Bokeh.Plotting.figure({
title: sim_mode[i],
tools: "pan,wheel_zoom,box_zoom,reset,save",
height: 300,
width: 400,
background_fill_color: "#F2F2F7"
});
// add a line with data from the source
bokeh_plot[i].multi_line({field:"x"},{field:"y"},{
source: the_source[sim_mode[i]],
color: {field:"color"},
line_width: 2
});
// Bokeh.Plotting.show(bokeh_plot[i],'#ResultPlot'+sim_mode[i]);
};
for(var i=0; i<sim_mode.length; i++){
Bokeh.Plotting.show(bokeh_plot[i],'#ResultPlot'+sim_mode[i]);
};

View File

@ -1202,7 +1202,7 @@ function showOutline(graph)
// let spice = get_spice(graph); // let spice = get_spice(graph);
var frame = document.createElement('div'); var frame = document.createElement('div');
frame.setAttribute('id','bokeh_02'); frame.setAttribute('id','simulator');
// var x = document.createElement('script'); // var x = document.createElement('script');
// x.setAttribute('src','static/spice/bokeh_02.js'); // x.setAttribute('src','static/spice/bokeh_02.js');
@ -1308,10 +1308,10 @@ function showOutline(graph)
{ {
var frame = document.createElement('div'); var frame = document.createElement('div');
frame.setAttribute('id','bokeh_01'); frame.setAttribute('id','show_result');
var x = document.createElement('script'); var x = document.createElement('script');
x.setAttribute('src','static/spice/show_result.js'); x.setAttribute('src','static/spice/show_result2.js');
frame.appendChild(x); frame.appendChild(x);