Skip to content

Commit

Permalink
interactivity in svg added, click on text to get values
Browse files Browse the repository at this point in the history
  • Loading branch information
sahilbansal17 committed Mar 31, 2018
1 parent 82db90f commit 5b67527
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 54 deletions.
22 changes: 18 additions & 4 deletions src/ac_circuit_solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,6 @@ int main(int argc, char** argv){
VoltageNode.push_back(temp);
}

// call the main draw function to render netlist as svg
drawMain(fileNameSVG, totalNodes + 1, circuitElements, iSource, vSource);
// since 0 is not included in totalNodes

// now we will use the Eigen library functions to construct the required matrices in the modified nodal analysis method

/* for interconnections between passive circuit elements */
Expand Down Expand Up @@ -397,6 +393,7 @@ int main(int argc, char** argv){
fout << circuitElements[i].elementName[0] << circuitElements[i].elementNum << " ";
complex <double> voltDiff = VoltageNode[ns] - VoltageNode[ne];
circuitElements[i].voltage = voltDiff; // to be used in current computation
circuitElements[i].netVoltage += voltDiff;
fout << round_3(abs(voltDiff)) << " " << round_3(phase(voltDiff)) << "\n";
}
if(sameFreqCount == 1)
Expand All @@ -414,6 +411,7 @@ int main(int argc, char** argv){
else
voltDiff = VoltageNode[ns] - VoltageNode[ne];
sourceElements[T1].voltage = voltDiff;
sourceElements[T1].netVoltage += voltDiff;
fout << round_3(abs(voltDiff)) << " " << round_3(phase(voltDiff)) << "\n";
}

Expand All @@ -422,6 +420,7 @@ int main(int argc, char** argv){
for(int i = 0 ; i < circuitElements.size(); i ++){
complex<double> res = circuitElements[i].voltage * circuitElements[i].admittance;
circuitElements[i].current = res;
circuitElements[i].netCurrent += res;
fout << circuitElements[i].elementName[0] << circuitElements[i].elementNum << " ";
fout << round_3(abs(res)) << " " << round_3(phase(res)) << "\n";
}
Expand All @@ -444,10 +443,25 @@ int main(int argc, char** argv){
break;
}
sourceElements[T1].current = res;
sourceElements[T1].netCurrent += res;
fout << round_3(abs(res)) << " " << round_3(phase(res)) << "\n";
}
T += sameFreqCount - 1; // so that same sources are not considered again
}
fout.close();

// calculate current and voltage phases and store for helping in draw
for(int i = 0 ; i < sourceElements.size(); i ++){
sourceElements[i].curPhase = round_3(phase(sourceElements[i].netCurrent));
sourceElements[i].volPhase = round_3(phase(sourceElements[i].netVoltage));
}
for(int i = 0 ; i < circuitElements.size(); i ++){
circuitElements[i].curPhase = round_3(phase(circuitElements[i].netCurrent));
circuitElements[i].volPhase = round_3(phase(circuitElements[i].netVoltage));
}

// call the main draw function to render netlist as svg after calcuating net currents and voltages
drawMain(fileNameSVG, totalNodes + 1, circuitElements, sourceElements);

return 0;
}
83 changes: 43 additions & 40 deletions src/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ struct component{
char* name;
int num, netStart, netEnd;
double value;
complex <double> current, voltage;
complex <double> current, voltage;
double cPhase, vPhase;
bool updated; // tells whether netStart and netEnd are swapped or not
};

Expand All @@ -25,35 +26,49 @@ bool orderByNetEnd(const component &a, const component &b){
return a.netEnd <= b.netEnd; // two components CAN have the same netEnd since THEN their diff between netEnds is same in the vector
}

inline void drawComponent(char name, int num, bool updated, int xCor1, int yCor, int xCor2, int cmax = 0){
// function for rounding decimal upto 3 places
inline double roundMe(double val){
double val_mul_1000 = val * 1000.0;
if(val_mul_1000 < 0){
val_mul_1000 = ceil(val_mul_1000 - 0.5);
}
else{
val_mul_1000 = floor(val_mul_1000 + 0.5);
}
return val_mul_1000/1000.0 ;
}

inline void drawComponent(component c, int xCor1, int yCor, int xCor2, int cmax = 0){
char name = c.name[0];
int num = c.num;
bool updated = c.updated;
switch(name){
case 'R':
drawResistor(xCor1, yCor + cmax*30, xCor2);
drawText("R"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10);
drawText("R"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10, c.value, roundMe(abs(c.current)), roundMe(abs(c.voltage)), c.cPhase, c.vPhase);
break;
case 'L':
drawInductor(xCor1, yCor + cmax*30, xCor2);
drawText("L"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10);
drawText("L"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10, c.value, roundMe(abs(c.current)), roundMe(abs(c.voltage)), c.cPhase, c.vPhase);
break;
case 'C':
drawCapacitor(xCor1, yCor + cmax*30, xCor2);
drawText("C"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10);
drawText("C"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10, c.value, roundMe(abs(c.current)), roundMe(abs(c.voltage)), c.cPhase, c.vPhase);
break;
case 'V':
drawVoltage(xCor1, yCor + cmax*30, xCor2);
drawText("V"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10);
drawText("V"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10, c.value, roundMe(abs(c.current)), roundMe(abs(c.voltage)), c.cPhase, c.vPhase);
break;
case 'I':
drawCurrent(xCor1, yCor, xCor2, updated); // draw +ve at ns and -ve at ne
drawText("I"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10);
drawText("I"+to_string(num),(xCor1 + xCor2)/2, yCor + cmax*30 - 10, c.value, roundMe(abs(c.current)), roundMe(abs(c.voltage)), c.cPhase, c.vPhase);
break;
}
}

void drawMain(string fileName, int N, vector <element> el, vector <source> cs, vector <source> vs){
void drawMain(string fileName, int N, vector <element> el, vector <source> so){
int E = el.size(); // total number of circuit elements
int VS = vs.size(); // total no of voltage sources
int CS = cs.size(); // total no of current sources
int S = so.size(); // total no of sources

int distBWnets = 50 ; // fixed
int xNets[N]; // x coordinates of nets
Expand All @@ -63,7 +78,7 @@ void drawMain(string fileName, int N, vector <element> el, vector <source> cs, v
xNets[i] = xNets[i-1] + distBWnets;
}

int height = 200 + 30*(E + VS + CS) + 40 ; // this is the max possible height, all connections in parallel, each connection has height of around 30, extra 40 for text
int height = 200 + 30*(E + S) + 40 ; // this is the max possible height, all connections in parallel, each connection has height of around 30, extra 40 for text
int width = xNets[N-1] + 100; // maximum width of the screen
start(fileName, height, width);

Expand All @@ -77,8 +92,10 @@ void drawMain(string fileName, int N, vector <element> el, vector <source> cs, v
c.name = el[i].elementName;
c.num = el[i].elementNum;
c.value = el[i].valWithUnit;
c.current = el[i].current;
c.voltage = el[i].voltage;
c.current = el[i].netCurrent;
c.voltage = el[i].netVoltage;
c.cPhase = el[i].curPhase;
c.vPhase = el[i].volPhase;
int ns = el[i].netStart, ne = el[i].netEnd;
if(ns > ne){
swap(ns, ne);
Expand All @@ -90,29 +107,15 @@ void drawMain(string fileName, int N, vector <element> el, vector <source> cs, v
ordByNetDiff[diff].push_back(c);
}

for(int i = 0 ; i < VS ; i ++){
c.name = vs[i].sourceName;
c.num = vs[i].sourceNum;
c.value = vs[i].amplitude;
c.current = vs[i].current;
c.voltage = vs[i].voltage;
int ns = vs[i].netStart, ne = vs[i].netEnd;
if(ns > ne){
swap(ns, ne);
c.updated = 1;
}
int diff = ne - ns;
c.netStart = ns;
c.netEnd = ne;
ordByNetDiff[diff].push_back(c);
}
for(int i = 0 ; i < CS ; i ++){
c.name = cs[i].sourceName;
c.num = cs[i].sourceNum;
c.value = cs[i].amplitude;
c.current = cs[i].current;
c.voltage = cs[i].voltage;
int ns = cs[i].netStart, ne = cs[i].netEnd;
for(int i = 0 ; i < S ; i ++){
c.name = so[i].sourceName;
c.num = so[i].sourceNum;
c.value = so[i].amplitude;
c.current = so[i].netCurrent;
c.voltage = so[i].netVoltage;
c.cPhase = so[i].curPhase;
c.vPhase = so[i].volPhase;
int ns = so[i].netStart, ne = so[i].netEnd;
if(ns > ne){
swap(ns, ne);
c.updated = 1;
Expand Down Expand Up @@ -172,7 +175,7 @@ void drawMain(string fileName, int N, vector <element> el, vector <source> cs, v
xCor1 = xNets[ns], xCor2 = xNets[ne];
yCor = yNet;
// cout << "Drawing " << name << ": " << ns << " to " << ne << "\n";
drawComponent(name, c.num, c.updated, xCor1, yCor, xCor2);
drawComponent(c, xCor1, yCor, xCor2);
visitedC[startC] = 1;
countedC ++;
int cmax = 1; // for one iteration, the current max between current ns and ne
Expand All @@ -189,7 +192,7 @@ void drawMain(string fileName, int N, vector <element> el, vector <source> cs, v
// we won't change yNet but while drawing, we use an incrementer for yNet

// cout << "Drawing " << name << ": " << ns << " to " << ne << "\n";
drawComponent(name, c.num, c.updated, xCor1, yCor, xCor2, cmax);
drawComponent(c, xCor1, yCor, xCor2, cmax);
visitedC[j] = 1;
countedC ++;
cmax ++;
Expand All @@ -206,7 +209,7 @@ void drawMain(string fileName, int N, vector <element> el, vector <source> cs, v
name = c.name[0];
xCor1 = xNets[ns], xCor2 = xNets[ne];
// cout << "Drawing " << name << ": " << ns << " to " << ne << "\n";
drawComponent(name, c.num, c.updated, xCor1, yCor, xCor2);
drawComponent(c, xCor1, yCor, xCor2);
visitedC[j] = 1;
countedC ++;
}
Expand All @@ -230,7 +233,7 @@ void drawMain(string fileName, int N, vector <element> el, vector <source> cs, v
else
drawVerticalLine(xNets[i], yStart, yEnd, 0.5);
string res = "NET"+to_string(i);
drawText(res, xNets[i], yEnd + 30);
drawText(res, xNets[i], yEnd + 30, 0, 0, 0, 0, 0);
}
end();
}
10 changes: 6 additions & 4 deletions src/draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
This file will contain the DECLARATIONS of functions DEFINED in draw.cpp
*/

void drawMain(string fileName, int N, vector <element> el, vector <source> cs, vector <source> vs);
void drawMain(string fileName, int N, vector <element> el, vector <source> so);

/*
N : total number of nets
el : elements (R, L, C)
cs : current sources
vs : voltage sources
so : sources
*/

// combining elements and sources into components for ease of drawing
Expand All @@ -18,4 +17,7 @@ struct component;
bool orderByNetEnd(const component &a, const component &b);

// to draw an individual component
inline void drawComponent(char name, int num, bool updated, int xCor1, int yCor, int xCor2, int cmax = 0);
inline void drawComponent(component c, int xCor1, int yCor, int xCor2, int cmax = 0);

// function for rounding decimal upto 3 places
inline double roundMe(double val);
4 changes: 4 additions & 0 deletions src/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ struct element{
char* unit;

complex <double> current, voltage, admittance; // the part required for solving the circuit
complex <double> netCurrent, netVoltage; // superposition of currents and voltages due to all source
double curPhase, volPhase;
double valWithUnit;
};

Expand All @@ -28,6 +30,8 @@ struct source{

// currently assuming dcOffset = 0
complex <double> current, voltage; // part required for solving the circuit
complex <double> netCurrent, netVoltage; // superposition of currents and voltages due to all source
double curPhase, volPhase;
};

// the vector storing the element/source connections
Expand Down
17 changes: 12 additions & 5 deletions src/svg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ void drawCurrent(int X1, int Y1, int X2, bool np) {
fout << res;

}


void drawInductor(int X1, int Y1, int X2) { // minimum 30
float pt = X2 - X1;
pt = pt - 20;
Expand Down Expand Up @@ -225,24 +227,29 @@ void drawInductor(int X1, int Y1, int X2) { // minimum 30
fout << res;
}

void drawText(string txt, int X1, int Y1) {
void drawText(string txt, int X1, int Y1, double val, double cur, double vol, double cPhase, double vPhase) {
string res;

res = "<g font-size=\"" + to_string(10) +
"\" font-family=\"sans-serif\" fill=\"black\" stroke=\"none\" text-anchor=\"middle\">" +
"\n<text x=\"" + to_string(X1) + "\" y=\"" + to_string(Y1) + "\">"+txt+"</text>" +
"\n<text x=\"" + to_string(X1) + "\" y=\"" + to_string(Y1) + "\" onClick=\"showResult("+to_string(val)+","+to_string(cur)+","+to_string(vol)+","+to_string(cPhase)+","+to_string(vPhase)+")\">"+txt+"</text>" +
"\n</g>";
fout << res;
}

void addInteraction(){
fout << " <script type=\"text/JavaScript\"> <![CDATA[ function showResult(val, cur, vol, cPhase, vPhase) { alert(\"Value: \"+ val + \", Current: \"+ cur + \"<\"+ cPhase + \">, Voltage: \"+ vol + \"<\"+ vPhase + \">\"); } ]]> </script> ";
}

void start(string fileName, int h, int w) {
fout.open(fileName);
fout.open(fileName+".html");
fout << "<html> <title> Circuit Drawer </title> <body>";
fout << "<svg height=\"" << to_string(h) << "\" width= \"" << to_string(w)
<< "\" xmlns=\"http://www.w3.org/2000/svg\">";
addInteraction();
}

void end() {
fout << "\n</svg>";
fout << "\n</svg> </body> </html>";
fout.close();
}

4 changes: 3 additions & 1 deletion src/svg.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ void drawInductor(int X1, int Y1, int X2);
// vertical drawer functions
void drawVerticalLine(int X1, int Y1, int Y2, float width); // width specified to adjust nets 0 and N-1
// text drawing
void drawText(string txt, int X1, int Y1);
void drawText(string txt, int X1, int Y1, double val, double cur, double vol, double cPhase, double vPhase);

void addInteraction();

0 comments on commit 5b67527

Please sign in to comment.