CircuitOnline/public/js/combinationalAnalysis.js

276 lines
10 KiB
JavaScript

var inputSample = 5;
var dataSample=[['01---','11110','01---','00000'],['01110','1-1-1','----0'],['01---','11110','01110','1-1-1','0---0'],['----1']];
var sampleInputListNames=["A", "B"];
var sampleOutputListNames=["X"];
createCombinationalAnalysisPrompt=function(scope=globalScope){
//console.log("Ya");
scheduleBackup();
$('#combinationalAnalysis').empty();
$('#combinationalAnalysis').append("<p>Enter Input names separated by commas: <input id='inputNameList' type='text' placeHolder='eg. In A, In B'></p>");
$('#combinationalAnalysis').append("<p>Enter Output names separated by commas: <input id='outputNameList' type='text' placeHolder='eg. Out X, Out Y'></p>");
$('#combinationalAnalysis').append("<p>Do you need a decimal column? <input id='decimalColumnBox' type='checkbox'></p>");
$('#combinationalAnalysis').dialog({
width:"auto",
buttons: [
{
text: "Next",
click: function() {
var inputList = $("#inputNameList").val().split(',');
var outputList = $("#outputNameList").val().split(',');
inputList = inputList.map(x => x.trim());
inputList = inputList.filter(e => e);
outputList = outputList.map(x => x.trim());
outputList = outputList.filter(e => e);
if(inputList.length > 0 && outputList.length > 0){
$(this).dialog("close");
createBooleanPrompt(inputList,outputList,scope);
}
else{
alert("Enter Input / Output Variable(s) !");
}
},
}
]
});
}
function createBooleanPrompt(inputListNames,outputListNames,scope=globalScope){
inputListNames=inputListNames||(prompt("Enter inputs separated by commas").split(','));
outputListNames=outputListNames||(prompt("Enter outputs separated by commas").split(','));
outputListNamesInteger=[];
for (var i = 0; i < outputListNames.length; i++)
outputListNamesInteger[i] = 7*i + 13;//assigning an integer to the value, 7*i + 13 is random
var s='<table>';
s+='<tbody style="display:block; max-height:70vh; overflow-y:scroll" >';
s+='<tr>';
if($("#decimalColumnBox").is(":checked"))
s+='<th>'+'dec'+'</th>';
for(var i=0;i<inputListNames.length;i++)
s+='<th>'+inputListNames[i]+'</th>';
for(var i=0;i<outputListNames.length;i++)
s+='<th>'+outputListNames[i]+'</th>';
s+='</tr>';
var matrix = [];
for(var i=0; i<inputListNames.length; i++) {
matrix[i] = new Array((1<<inputListNames.length));
}
for(var i=0;i<inputListNames.length;i++){
for(var j=0;j<(1<<inputListNames.length);j++){
matrix[i][j]=(+((j&(1<<(inputListNames.length-i-1)))!=0));
}
}
for(var j=0;j<(1<<inputListNames.length);j++){
s+='<tr>';
if($("#decimalColumnBox").is(":checked"))
s+='<td>'+j+'</td>';
for(var i=0;i<inputListNames.length;i++){
s+='<td>'+matrix[i][j]+'</td>';
}
for(var i=0;i<outputListNamesInteger.length;i++){
s+='<td class ="output '+outputListNamesInteger[i]+'" id="'+j+'">'+'x'+'</td>';
//using hash values as they'll be used in the generateBooleanTableData function
}
s+='</tr>';
}
s+='</tbody>';
s+='</table>';
//console.log(s)
$('#combinationalAnalysis').empty()
$('#combinationalAnalysis').append(s)
$('#combinationalAnalysis').dialog({
width:"auto",
buttons: [
{
text: "Generate Circuit",
click: function() {
$( this ).dialog( "close" );
var data = generateBooleanTableData(outputListNamesInteger);
//passing the hash values to avoid spaces being passed which is causing a problem
minmizedCircuit = [];
for(let output in data){
let temp = new BooleanMinimize(
inputListNames.length,
data[output][1].map(Number),
data[output]['x'].map(Number)
)
minmizedCircuit.push(temp.result);
}
// //console.log(dataSample);
drawCombinationalAnalysis(minmizedCircuit,inputListNames,outputListNames,scope)
},
},
{
text: "Print Truth Table",
click: function() {
var sTable = document.getElementById('combinationalAnalysis').innerHTML;
var style = "<style> table {font: 20px Calibri;} table, th, td {border: solid 1px #DDD;border-collapse: collapse;} padding: 2px 3px;text-align: center;} </style>";
var win = window.open('', '', 'height=700,width=700');
win.document.write('<html><head>');
win.document.write('<title>Boolean Logic Table</title>');
win.document.write(style);
win.document.write('</head>');
win.document.write('<body>');
win.document.write('<center>'+sTable+'</center>');
win.document.write('</body></html>');
win.document.close();
win.print();
},
},
]
});
$('.output').click(function (){
var v=$(this).html();
if(v==0)v=$(this).html(1);
else if(v==1)v=$(this).html('x');
else if(v=='x')v=$(this).html(0);
})
}
function generateBooleanTableData(outputListNames){
var data={};
for(var i=0;i<outputListNames.length;i++){
data[outputListNames[i]]={
'x':[],
'1':[],
'0':[],
}
$rows=$('.'+outputListNames[i]);
for(j=0;j<$rows.length;j++){
//console.log($rows[j].innerHTML)
data[outputListNames[i]][$rows[j].innerHTML].push($rows[j].id);
}
}
//console.log(data);
return data;
}
function drawCombinationalAnalysis(combinationalData,inputList,outputListNames,scope=globalScope){
//console.log(combinationalData);
var inputCount=inputList.length;
var maxTerms=0;
for(var i=0;i<combinationalData.length;i++)
maxTerms=Math.max(maxTerms,combinationalData[i].length);
var startPosX=200;
var startPosY=200;
var currentPosY=300;
var andPosX=startPosX+inputCount*40+40;
var orPosX=andPosX+Math.floor(maxTerms/2)*10+80;
var outputPosX=orPosX+60;
var inputObjects=[];
var logixNodes=[];
for(var i=0;i<inputCount;i++){
inputObjects.push(new Input(startPosX+i*40,startPosY,scope,"DOWN",1));
inputObjects[i].setLabel(inputList[i]);
inputObjects[i].newLabelDirection("UP");
var v1=new Node(startPosX+i*40,startPosY+20,2,scope.root);
inputObjects[i].output1.connect(v1);
var v2=new Node(startPosX+i*40+20,startPosY+20,2,scope.root);
v1.connect(v2);
var notG=new NotGate(startPosX+i*40+20, startPosY+40, scope, "DOWN", 1);
notG.inp1.connect(v2);
logixNodes.push(v1);
logixNodes.push(notG.output1);
}
function countTerm(s){
var c=0;
for(var i=0;i<s.length;i++)
if(s[i]!=='-')c++;
return c;
}
for(var i=0;i<combinationalData.length;i++){
// //console.log(combinationalData[i]);
var andGateNodes=[];
for(var j=0;j<combinationalData[i].length;j++){
var c=countTerm(combinationalData[i][j]);
if(c>1){
var andGate=new AndGate(andPosX, currentPosY, scope, "RIGHT", c, 1);
andGateNodes.push(andGate.output1);
var misses=0;
for(var k=0;k<combinationalData[i][j].length;k++){
if(combinationalData[i][j][k]=='-'){misses++;continue;}
var index=2*k+(combinationalData[i][j][k]==0);
//console.log(index);
//console.log(andGate);
var v=new Node(logixNodes[index].absX(),andGate.inp[k-misses].absY(),2,scope.root);
logixNodes[index].connect(v);
logixNodes[index]=v;
v.connect(andGate.inp[k-misses]);
}
}
else{
for(var k=0;k<combinationalData[i][j].length;k++){
if(combinationalData[i][j][k]=='-')continue;
var index=2*k+(combinationalData[i][j][k]==0);
var andGateSubstituteNode= new Node(andPosX, currentPosY, 2,scope.root);
var v=new Node(logixNodes[index].absX(),andGateSubstituteNode.absY(),2,scope.root);
logixNodes[index].connect(v);
logixNodes[index]=v;
v.connect(andGateSubstituteNode);
andGateNodes.push(andGateSubstituteNode);
}
}
currentPosY+=c*10+30;
}
var andGateCount=andGateNodes.length;
var midWay=Math.floor(andGateCount/2);
var orGatePosY=(andGateNodes[midWay].absY()+andGateNodes[Math.floor((andGateCount-1)/2)].absY())/2;
if( orGatePosY%10 == 5)
orGatePosY += 5; // To make or gate fall in grid
if(andGateCount>1){
var o=new OrGate(orPosX,orGatePosY,scope,"RIGHT",andGateCount,1);
if(andGateCount%2==1)andGateNodes[midWay].connect(o.inp[midWay]);
for(var j=0;j<midWay;j++){
var v=new Node(andPosX+30+(midWay-j)*10,andGateNodes[j].absY(),2,scope.root);
v.connect(andGateNodes[j]);
var v2=new Node(andPosX+30+(midWay-j)*10,o.inp[j].absY(),2,scope.root);
v2.connect(v)
o.inp[j].connect(v2);
var v=new Node(andPosX+30+(midWay-j)*10,andGateNodes[andGateCount-j-1].absY(),2,scope.root);
v.connect(andGateNodes[andGateCount-j-1]);
var v2=new Node(andPosX+30+(midWay-j)*10,o.inp[andGateCount-j-1].absY(),2,scope.root);
v2.connect(v)
o.inp[andGateCount-j-1].connect(v2);
}
var out=new Output(outputPosX,o.y,scope,"LEFT",1);
out.inp1.connect(o.output1);
}
else{
var out=new Output(outputPosX,andGateNodes[0].absY(),scope,"LEFT",1);
out.inp1.connect(andGateNodes[0]);
}
out.setLabel(outputListNames[i]);
out.newLabelDirection("RIGHT");
}
for(var i=0;i<logixNodes.length;i++){
if(logixNodes[i].absY()!=currentPosY){
var v=new Node(logixNodes[i].absX(),currentPosY,2,scope.root);
logixNodes[i].connect(v)
}
}
}