Skip to content

Commit b552cdf

Browse files
committed
user can set number of calc points. Saves rotation in URL. fix reset button. Add share btn
1 parent b7071b2 commit b552cdf

4 files changed

Lines changed: 92 additions & 29 deletions

File tree

circuitSolver/modules/View.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SelectionMenuPolicy } from "./wdk_draw2d.js";
1+
import { SelectionMenuPolicy, wdkRotate } from "./wdk_draw2d.js";
22

33
const connectionDefault = {
44
type: "draw2d.Connection",
@@ -59,7 +59,7 @@ export class View extends draw2d.Canvas {
5959
} else return name;
6060
}
6161

62-
addShapeToSchem(type, x, y, id) {
62+
addShapeToSchem(type, x, y, id, angle) {
6363
// console.log(type, x, y)
6464
// console.log(this.getElements());
6565

@@ -72,7 +72,7 @@ export class View extends draw2d.Canvas {
7272
relocate: function (index, figure) {
7373
var parent = figure.getParent();
7474
var rotAngle = parent.getRotationAngle();
75-
75+
7676
if (rotAngle > 0) {
7777
// var newX =
7878
figure.setPosition(this.y, this.x);
@@ -181,6 +181,9 @@ export class View extends draw2d.Canvas {
181181
this.x = x;
182182
this.y = y;
183183
e.resizeable = false;
184+
if (angle) {
185+
if (angle > 0) wdkRotate(e);
186+
}
184187
// console.log('add', add);
185188
var add = this.dropCb(e, (a) => this.addToSchematic(a));
186189
// add = true;
@@ -231,7 +234,7 @@ export class View extends draw2d.Canvas {
231234
else if (firstLetter == "Y") type = "iprobe";
232235
// console.log(item, type)
233236

234-
this.addShapeToSchem(type, item.x, item.y, item.id);
237+
this.addShapeToSchem(type, item.x, item.y, item.id, item.angle);
235238
}
236239
});
237240

circuitSolver/modules/main.js

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ var initialState = {
2020
value: 100,
2121
unit: "G",
2222
},
23+
numSteps: 100,
2324
schematic: startupSchematic,
2425
};
2526
var startState = {...initialState};
@@ -38,6 +39,7 @@ if (encodedCompressed) {
3839
if ('elements' in decodedObject) startState.elements = decodedObject.elements;
3940
if ('fmin' in decodedObject) startState.fmin = decodedObject.fmin;
4041
if ('fmax' in decodedObject) startState.fmax = decodedObject.fmax;
42+
if ('numSteps' in decodedObject) startState.numSteps = decodedObject.numSteps;
4143

4244
}
4345
const html = htm.bind(React.createElement);
@@ -56,13 +58,18 @@ function navBar(props) {
5658
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"></path>
5759
</svg>
5860
</button>
59-
<a href="/" style=${{'color':'#fff','text-decoration':'none'}}>
61+
<a href=${location.protocol + '//' + location.host + location.pathname} style=${{'color':'#fff','text-decoration':'none'}}>
6062
<button type="button" className="btn btn-secondary py-0 ms-2" title="restart" key="undoC">
6163
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16">
6264
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
6365
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/>
6466
</svg>
6567
</button></a>
68+
<button type="button" className="btn btn-secondary py-0 ms-2" title="share" onClick=${() => {navigator.clipboard.writeText(window.location.href); props.copiedToastURL.show()}} key="share">
69+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-share" viewBox="0 0 16 16">
70+
<path d="M13.5 1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3M11 2.5a2.5 2.5 0 1 1 .603 1.628l-6.718 3.12a2.5 2.5 0 0 1 0 1.504l6.718 3.12a2.5 2.5 0 1 1-.488.876l-6.718-3.12a2.5 2.5 0 1 1 0-3.256l6.718-3.12A2.5 2.5 0 0 1 11 2.5m-8.5 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3m11 5.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3"/>
71+
</svg>
72+
</button>
6673
</div>
6774
<div className="col d-grid d-md-flex justify-content-md-end" key="navButtons">
6875
<a className="btn btn-light py-0" title="home" href="../" key="home">
@@ -79,7 +86,7 @@ function navBar(props) {
7986
</div>`;
8087
}
8188

82-
function Toasts({ toastMxVIsource, toastCopiedLatex, toastCopiedMathML }) {
89+
function Toasts({ toastMxVIsource, toastCopiedLatex, toastCopiedMathML, toastCopiedURL }) {
8390
return html`
8491
<div className="toast-container position-fixed top-0 end-0 p-3">
8592
<div id="liveToast" className="toast bg-warning" role="alert" ref=${toastMxVIsource}>
@@ -111,6 +118,16 @@ function Toasts({ toastMxVIsource, toastCopiedLatex, toastCopiedMathML }) {
111118
<a className="text-white" href="https://codepen.io/bqlou/pen/yOgbmb" target="_blank">https://codepen.io/bqlou/pen/yOgbmb</a>
112119
</div>
113120
</div>
121+
122+
<div id="liveToast" className="toast bg-success text-white" role="alert" ref=${toastCopiedURL}>
123+
<div className="toast-header">
124+
<strong className="me-auto">Copied to clipboard</strong>
125+
<button type="button" className="btn-close" data-bs-dismiss="toast"></button>
126+
</div>
127+
<div className="toast-body">
128+
Shareable URL copied to your clipboard (same as in URL bar)
129+
</div>
130+
</div>
114131
</div>
115132
`;
116133
}
@@ -327,7 +344,7 @@ var plotlyLayout = {
327344
showspikes: true,
328345
title: "amplitude (dB)",
329346
},
330-
hovermode: "y unified",
347+
hovermode: "x unified",
331348
autosize: true,
332349
margin: { t: 0 },
333350
};
@@ -608,6 +625,12 @@ function FreqResponseControllers(props) {
608625
</select>
609626
</div>
610627
</div>
628+
<div className="col" key="numstep">
629+
<div className="input-group mt-1">
630+
<span className="input-group-text">Calculation Points</span>
631+
<input type="text" className="form-control" value="${props.numStepsValue}" onChange=${(e) => props.onChange(e, "numSteps")} />
632+
</div>
633+
</div>
611634
</div>
612635
`;
613636
}
@@ -691,6 +714,7 @@ class Game extends React.Component {
691714
this.toastMxVIsource = React.createRef();
692715
this.toastCopiedLatex = React.createRef();
693716
this.toastCopiedMathML = React.createRef();
717+
this.toastCopiedURL = React.createRef();
694718
}
695719

696720
schematicReady() {
@@ -728,7 +752,7 @@ class Game extends React.Component {
728752

729753
var fmin = current.fmin.value * unitStrToVal(current.fmin.unit);
730754
var fmax = current.fmax.value * unitStrToVal(current.fmax.unit);
731-
var fstepdB_20 = Math.log10(fmax / fmin) / 100;
755+
var fstepdB_20 = Math.log10(fmax / fmin) / current.numSteps;
732756
var fstep = 10 ** fstepdB_20;
733757
// console.log(fmin, fmax, fstep)
734758
// console.log(fmin, fmax, fstep, fstepdB_20, this.freq)
@@ -797,7 +821,7 @@ class Game extends React.Component {
797821
//add new elements
798822
//handle the parameter input
799823
for (const key in newElementMap) {
800-
if (key == "gnd" || key == "xvout" || key == "vin" || key[0] == "o" || key[0] == "Y") continue;
824+
if (key == "gnd" || key == "xvout" || key == "vin" || key == "iin" || key[0] == "o" || key[0] == "Y") continue;
801825
var allLetters = Array.from(key);
802826
var firstLetter = allLetters[0];
803827
if (!(key in elements)) {
@@ -841,6 +865,7 @@ class Game extends React.Component {
841865

842866
//build up a simplified schematic state
843867
canvasState.forEach((item) => {
868+
// if (item.id == "R2") console.log('ii',{...item})
844869
if (item.type == "draw2d.Connection") {
845870
// newConn.source = item.source,
846871
// target: {node: 'vout', port: 'hybrid0'},
@@ -854,6 +879,7 @@ class Game extends React.Component {
854879
schematicState.push({
855880
type: "component",
856881
id: item.id,
882+
angle: item.angle,
857883
x: item.x,
858884
y: item.y,
859885
});
@@ -920,6 +946,7 @@ class Game extends React.Component {
920946
this.bsToast = bootstrap.Toast.getOrCreateInstance(this.toastMxVIsource.current);
921947
this.copiedToast = bootstrap.Toast.getOrCreateInstance(this.toastCopiedLatex.current);
922948
this.copiedToastML = bootstrap.Toast.getOrCreateInstance(this.toastCopiedMathML.current);
949+
this.copiedToastURL = bootstrap.Toast.getOrCreateInstance(this.toastCopiedURL.current);
923950

924951
//enable tooltips
925952
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
@@ -933,6 +960,8 @@ class Game extends React.Component {
933960
current.fmin.value = e.target.value;
934961
} else if (i == "fmax") {
935962
current.fmax.value = e.target.value;
963+
} else if (i == "numSteps") {
964+
current.numSteps = Math.round(e.target.value);
936965
} else {
937966
current.elements[i].value = e.target.value;
938967
}
@@ -1051,8 +1080,8 @@ class Game extends React.Component {
10511080

10521081
// Update the DOM
10531082
return html`
1054-
<${navBar} title="ONLINE CIRCUIT SOLVER" key="navBar" onClickUndo=${() => this.handleUndo(true)}/>
1055-
<${Toasts} key="toasts" toastMxVIsource=${this.toastMxVIsource} toastCopiedLatex=${this.toastCopiedLatex} toastCopiedMathML=${this.toastCopiedMathML} />
1083+
<${navBar} title="ONLINE CIRCUIT SOLVER" key="navBar" onClickUndo=${() => this.handleUndo(true)} copiedToastURL=${this.copiedToastURL} />
1084+
<${Toasts} key="toasts" toastMxVIsource=${this.toastMxVIsource} toastCopiedLatex=${this.toastCopiedLatex} toastCopiedMathML=${this.toastCopiedMathML} toastCopiedURL=${this.toastCopiedURL} />
10561085
<div className="w-100 p-2 bg-green" key="wrapper">
10571086
<div className="container-xl" key="topContainer">
10581087
<div className="row">
@@ -1094,6 +1123,7 @@ class Game extends React.Component {
10941123
<${FreqResponse} key="FreqResponse" />
10951124
<${FreqResponseControllers}
10961125
key="FreqResponseControllers"
1126+
numStepsValue=${current.numSteps}
10971127
fminValue=${current.fmin.value}
10981128
fminUnit=${current.fmin.unit}
10991129
fmaxValue=${current.fmax.value}

circuitSolver/modules/wdk_draw2d.js

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ export class init_draw2d {
5656
}
5757
}
5858

59+
export function wdkRotate (figure)
60+
{
61+
// use a Command and CommandStack for undo/redo support
62+
//
63+
// var command = new draw2d.command.CommandDelete(figure);
64+
// canvas.getCommandStack().execute(command);
65+
var w = figure.getWidth();
66+
var h = figure.getHeight();
67+
var a = (figure.getRotationAngle() + 270) % 540;
68+
var id = figure.getId();
69+
// var letters = Array.from(id);
70+
var rot = (a == 0) ^ (id[0] == "C") ? new draw2d.layout.locator.TopLocator() : new draw2d.layout.locator.RightLocator();
71+
// console.log(figure.getChildren())
72+
figure.resetChildren();
73+
74+
figure.add(new draw2d.shape.basic.Text({ text: id, stroke: 0 }), rot);
75+
// console.log(a,h,w)
76+
figure.attr({ angle: a, width: h, height: w });
77+
}
78+
5979
export var SelectionMenuPolicy = draw2d.policy.figure.SelectionPolicy.extend({
6080
NAME: "SelectionMenuPolicy",
6181

@@ -86,24 +106,25 @@ export var SelectionMenuPolicy = draw2d.policy.figure.SelectionPolicy.extend({
86106
</svg>`
87107
);
88108
$("#canvasHolder").append(this.overlay);
89-
this.overlay.on("click", function () {
90-
// use a Command and CommandStack for undo/redo support
91-
//
92-
// var command = new draw2d.command.CommandDelete(figure);
93-
// canvas.getCommandStack().execute(command);
94-
var w = figure.getWidth();
95-
var h = figure.getHeight();
96-
var a = (figure.getRotationAngle() + 270) % 540;
97-
var id = figure.getId();
98-
// var letters = Array.from(id);
99-
var rot = (a == 0) ^ (id[0] == "C") ? new draw2d.layout.locator.TopLocator() : new draw2d.layout.locator.RightLocator();
100-
// console.log(figure.getChildren())
101-
figure.resetChildren();
102-
103-
figure.add(new draw2d.shape.basic.Text({ text: id, stroke: 0 }), rot);
104-
// console.log(a,h,w)
105-
figure.attr({ angle: a, width: h, height: w });
106-
});
109+
this.overlay.on("click", ()=>wdkRotate(figure))
110+
// this.overlay.on("click", function () {
111+
// // use a Command and CommandStack for undo/redo support
112+
// //
113+
// // var command = new draw2d.command.CommandDelete(figure);
114+
// // canvas.getCommandStack().execute(command);
115+
// var w = figure.getWidth();
116+
// var h = figure.getHeight();
117+
// var a = (figure.getRotationAngle() + 270) % 540;
118+
// var id = figure.getId();
119+
// // var letters = Array.from(id);
120+
// var rot = (a == 0) ^ (id[0] == "C") ? new draw2d.layout.locator.TopLocator() : new draw2d.layout.locator.RightLocator();
121+
// // console.log(figure.getChildren())
122+
// figure.resetChildren();
123+
124+
// figure.add(new draw2d.shape.basic.Text({ text: id, stroke: 0 }), rot);
125+
// // console.log(a,h,w)
126+
// figure.attr({ angle: a, width: h, height: w });
127+
// });
107128
}
108129
this.posOverlay(figure);
109130
},

circuitSolver/toDo.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11

22

3+
4+
5+
36
-- Below is done later, after laplace derivation is more thoroughly verified... --
47
3 - Show bilinear transform equation
58
4 - Show state space representation
69
5 - Draw amplitude response of those 3 transforms
710

11+
# Done on Jan 6 2024
12+
1 - mouse over tie to x
13+
2 - let user control number of steps
14+
3 - iin should not show cap size!
15+
4 - rotation state saved to the URL
16+
5 - Add url shareable button and toast
817

918
# Draw2D
1019
- [x] Add a resistor shape to toolbar

0 commit comments

Comments
 (0)