Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
0510e96a
Commit
0510e96a
authored
Jan 27, 2012
by
Kyle Fiedler
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
2676c55e
cc40a3c0
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
327 additions
and
41 deletions
+327
-41
js/cktsim.js
+43
-24
js/schematic.js
+284
-17
No files found.
js/cktsim.js
View file @
0510e96a
...
@@ -44,6 +44,7 @@ cktsim = (function() {
...
@@ -44,6 +44,7 @@ cktsim = (function() {
this
.
devices
=
[];
// list of devices
this
.
devices
=
[];
// list of devices
this
.
device_map
=
new
Array
();
// map name -> device
this
.
device_map
=
new
Array
();
// map name -> device
this
.
voltage_sources
=
[];
// list of voltage sources
this
.
finalized
=
false
;
this
.
finalized
=
false
;
this
.
diddc
=
false
;
this
.
diddc
=
false
;
...
@@ -104,10 +105,14 @@ cktsim = (function() {
...
@@ -104,10 +105,14 @@ cktsim = (function() {
var
type
=
component
[
0
];
var
type
=
component
[
0
];
// ignore wires, ground connections, scope probes and view info
// ignore wires, ground connections, scope probes and view info
if
(
type
==
'view'
||
type
==
'w'
||
type
==
'g'
||
type
==
's'
||
type
==
'L'
)
continue
;
if
(
type
==
'view'
||
type
==
'w'
||
type
==
'g'
||
type
==
's'
||
type
==
'L'
)
{
continue
;
}
var
properties
=
component
[
2
];
var
properties
=
component
[
2
];
var
name
=
properties
[
'name'
];
var
name
=
properties
[
'name'
];
if
(
name
==
undefined
||
name
==
''
)
name
=
'_'
+
properties
[
'_json_'
].
toString
();
// convert node names to circuit indicies
// convert node names to circuit indicies
var
connections
=
component
[
3
];
var
connections
=
component
[
3
];
...
@@ -134,11 +139,9 @@ cktsim = (function() {
...
@@ -134,11 +139,9 @@ cktsim = (function() {
else
if
(
type
==
'o'
)
// op amp
else
if
(
type
==
'o'
)
// op amp
this
.
opamp
(
connections
[
0
],
connections
[
1
],
connections
[
2
],
properties
[
'A'
],
name
);
this
.
opamp
(
connections
[
0
],
connections
[
1
],
connections
[
2
],
properties
[
'A'
],
name
);
else
if
(
type
==
'n'
)
// n fet
else
if
(
type
==
'n'
)
// n fet
this
.
n
(
connections
[
0
],
connections
[
1
],
connections
[
2
],
this
.
n
(
connections
[
0
],
connections
[
1
],
connections
[
2
],
properties
[
'W/L'
],
name
);
properties
[
'W/L'
],
name
);
else
if
(
type
==
'p'
)
// p fet
else
if
(
type
==
'p'
)
// p fet
this
.
p
(
connections
[
0
],
connections
[
1
],
connections
[
2
],
this
.
p
(
connections
[
0
],
connections
[
1
],
connections
[
2
],
properties
[
'W/L'
],
name
);
properties
[
'W/L'
],
name
);
}
}
}
}
...
@@ -214,10 +217,16 @@ cktsim = (function() {
...
@@ -214,10 +217,16 @@ cktsim = (function() {
this
.
diddc
=
true
;
this
.
diddc
=
true
;
// create solution dictionary
// create solution dictionary
var
result
=
new
Array
();
var
result
=
new
Array
();
// capture node voltages
for
(
var
name
in
this
.
node_map
)
{
for
(
var
name
in
this
.
node_map
)
{
var
index
=
this
.
node_map
[
name
];
var
index
=
this
.
node_map
[
name
];
result
[
name
]
=
(
index
==
-
1
)
?
0
:
this
.
solution
[
index
];
result
[
name
]
=
(
index
==
-
1
)
?
0
:
this
.
solution
[
index
];
}
}
// capture branch currents from voltage sources
for
(
var
i
=
this
.
voltage_sources
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
v
=
this
.
voltage_sources
[
i
];
result
[
'I('
+
v
.
name
+
')'
]
=
this
.
solution
[
v
.
branch
];
}
return
result
;
return
result
;
}
}
}
}
...
@@ -457,6 +466,12 @@ cktsim = (function() {
...
@@ -457,6 +466,12 @@ cktsim = (function() {
var
index
=
this
.
node_map
[
name
];
var
index
=
this
.
node_map
[
name
];
result
[
name
]
=
(
index
==
-
1
)
?
0
:
response
[
index
];
result
[
name
]
=
(
index
==
-
1
)
?
0
:
response
[
index
];
}
}
// capture branch currents from voltage sources
for
(
var
i
=
this
.
voltage_sources
.
length
-
1
;
i
>=
0
;
--
i
)
{
var
v
=
this
.
voltage_sources
[
i
];
result
[
'I('
+
v
.
name
+
')'
]
=
response
[
v
.
branch
];
}
result
[
'time'
]
=
response
[
this
.
N
];
result
[
'time'
]
=
response
[
this
.
N
];
return
result
;
return
result
;
}
}
...
@@ -537,6 +552,7 @@ cktsim = (function() {
...
@@ -537,6 +552,7 @@ cktsim = (function() {
Circuit
.
prototype
.
add_device
=
function
(
d
,
name
)
{
Circuit
.
prototype
.
add_device
=
function
(
d
,
name
)
{
// Add device to list of devices and to device map
// Add device to list of devices and to device map
this
.
devices
.
push
(
d
);
this
.
devices
.
push
(
d
);
d
.
name
=
name
;
if
(
name
)
{
if
(
name
)
{
if
(
this
.
device_map
[
name
]
===
undefined
)
if
(
this
.
device_map
[
name
]
===
undefined
)
this
.
device_map
[
name
]
=
d
;
this
.
device_map
[
name
]
=
d
;
...
@@ -599,6 +615,7 @@ cktsim = (function() {
...
@@ -599,6 +615,7 @@ cktsim = (function() {
Circuit
.
prototype
.
v
=
function
(
n1
,
n2
,
v
,
name
)
{
Circuit
.
prototype
.
v
=
function
(
n1
,
n2
,
v
,
name
)
{
var
branch
=
this
.
node
(
undefined
,
T_CURRENT
);
var
branch
=
this
.
node
(
undefined
,
T_CURRENT
);
var
d
=
new
VSource
(
n1
,
n2
,
branch
,
v
);
var
d
=
new
VSource
(
n1
,
n2
,
branch
,
v
);
this
.
voltage_sources
.
push
(
d
);
return
this
.
add_device
(
d
,
name
);
return
this
.
add_device
(
d
,
name
);
}
}
...
@@ -1029,9 +1046,11 @@ cktsim = (function() {
...
@@ -1029,9 +1046,11 @@ cktsim = (function() {
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// argument is a string describing the source's value (see comments for details)
// argument is a string describing the source's value (see comments for details)
// source types: dc,step,square,triangle,sin,pulse,pwl,pwl
r
// source types: dc,step,square,triangle,sin,pulse,pwl,pwl
_repeating
// returns an object with the following attributes:
// returns an object with the following attributes:
// fun -- name of source function
// args -- list of argument values
// value(t) -- compute source value at time t
// value(t) -- compute source value at time t
// inflection_point(t) -- compute time after t when a time point is needed
// inflection_point(t) -- compute time after t when a time point is needed
// dc -- value at time 0
// dc -- value at time 0
...
@@ -1071,32 +1090,35 @@ cktsim = (function() {
...
@@ -1071,32 +1090,35 @@ cktsim = (function() {
// post-processing for constant sources
// post-processing for constant sources
// dc(v)
// dc(v)
if
(
src
.
fun
==
'dc'
)
{
if
(
src
.
fun
==
'dc'
)
{
var
v
alue
=
src
.
args
[
0
]
;
var
v
=
arg_value
(
src
.
args
,
0
,
0
)
;
if
(
value
===
undefined
)
value
=
0
;
src
.
args
=
[
v
]
;
src
.
value
=
function
(
t
)
{
return
v
alue
;
}
// closure
src
.
value
=
function
(
t
)
{
return
v
;
}
// closure
}
}
// post-processing for step sources
// post-processing for step sources
// step(v_init,v_plateau,t_delay,t_rise
,t_fall
)
// step(v_init,v_plateau,t_delay,t_rise)
else
if
(
src
.
fun
==
'step'
)
{
else
if
(
src
.
fun
==
'step'
)
{
var
v1
=
arg_value
(
src
.
args
,
0
,
0
);
// default init value: 0V
var
v1
=
arg_value
(
src
.
args
,
0
,
0
);
// default init value: 0V
var
v2
=
arg_value
(
src
.
args
,
1
,
1
);
// default plateau value: 1V
var
v2
=
arg_value
(
src
.
args
,
1
,
1
);
// default plateau value: 1V
var
td
=
Math
.
max
(
0
,
arg_value
(
src
.
args
,
2
,
0
));
// time step starts
var
td
=
Math
.
max
(
0
,
arg_value
(
src
.
args
,
2
,
0
));
// time step starts
var
tr
=
Math
.
abs
(
arg_value
(
src
.
args
,
3
,
1
e
-
9
));
// default rise time: 1ns
var
tr
=
Math
.
abs
(
arg_value
(
src
.
args
,
3
,
1
e
-
9
));
// default rise time: 1ns
src
.
args
=
[
v1
,
v2
,
td
,
tr
];
// remember any defaulted values
pwl_source
(
src
,[
td
,
v1
,
td
+
tr
,
v2
],
false
);
pwl_source
(
src
,[
td
,
v1
,
td
+
tr
,
v2
],
false
);
}
}
// post-processing for square wave
// post-processing for square wave
// square(v_init,v_plateau,
t_period
)
// square(v_init,v_plateau,
freq
)
else
if
(
src
.
fun
==
'square'
)
{
else
if
(
src
.
fun
==
'square'
)
{
var
v1
=
arg_value
(
src
.
args
,
0
,
0
);
// default init value: 0V
var
v1
=
arg_value
(
src
.
args
,
0
,
0
);
// default init value: 0V
var
v2
=
arg_value
(
src
.
args
,
1
,
1
);
// default plateau value: 1V
var
v2
=
arg_value
(
src
.
args
,
1
,
1
);
// default plateau value: 1V
var
freq
=
Math
.
abs
(
arg_value
(
src
.
args
,
2
,
1
));
// default frequency: 1s
var
freq
=
Math
.
abs
(
arg_value
(
src
.
args
,
2
,
1
));
// default frequency: 1Hz
src
.
args
=
[
v1
,
v2
,
freq
];
// remember any defaulted values
var
per
=
freq
==
0
?
Infinity
:
1
/
freq
;
var
per
=
freq
==
0
?
Infinity
:
1
/
freq
;
var
t_change
=
0.01
*
per
;
// rise and fall time
var
t_change
=
0.01
*
per
;
// rise and fall time
var
t_pw
=
0.49
*
per
;
// half the cycle minus rise and fall time
var
t_pw
=
0.49
*
per
;
// half the cycle minus rise and fall time
pwl_source
(
src
,[
0
,
v1
,
t_change
,
v2
,
t_change
+
t_pw
,
v2
,
t_change
+
t_pw
+
t_change
,
v1
,
per
,
v1
],
true
);
pwl_source
(
src
,[
0
,
v1
,
t_change
,
v2
,
t_change
+
t_pw
,
v2
,
t_change
+
t_pw
+
t_change
,
v1
,
per
,
v1
],
true
);
}
}
// post-processing for triangle
// post-processing for triangle
...
@@ -1105,6 +1127,7 @@ cktsim = (function() {
...
@@ -1105,6 +1127,7 @@ cktsim = (function() {
var
v1
=
arg_value
(
src
.
args
,
0
,
0
);
// default init value: 0V
var
v1
=
arg_value
(
src
.
args
,
0
,
0
);
// default init value: 0V
var
v2
=
arg_value
(
src
.
args
,
1
,
1
);
// default plateau value: 1V
var
v2
=
arg_value
(
src
.
args
,
1
,
1
);
// default plateau value: 1V
var
freq
=
Math
.
abs
(
arg_value
(
src
.
args
,
2
,
1
));
// default frequency: 1s
var
freq
=
Math
.
abs
(
arg_value
(
src
.
args
,
2
,
1
));
// default frequency: 1s
src
.
args
=
[
v1
,
v2
,
freq
];
// remember any defaulted values
var
per
=
freq
==
0
?
Infinity
:
1
/
freq
;
var
per
=
freq
==
0
?
Infinity
:
1
/
freq
;
pwl_source
(
src
,[
0
,
v1
,
per
/
2
,
v2
,
per
,
v1
],
true
);
pwl_source
(
src
,[
0
,
v1
,
per
/
2
,
v2
,
per
,
v1
],
true
);
...
@@ -1112,8 +1135,8 @@ cktsim = (function() {
...
@@ -1112,8 +1135,8 @@ cktsim = (function() {
// post-processing for pwl and pwlr sources
// post-processing for pwl and pwlr sources
// pwl[r](t1,v1,t2,v2,...)
// pwl[r](t1,v1,t2,v2,...)
else
if
(
src
.
fun
==
'pwl'
||
src
.
fun
==
'pwl
r
'
)
{
else
if
(
src
.
fun
==
'pwl'
||
src
.
fun
==
'pwl
_repeating
'
)
{
pwl_source
(
src
,
src
.
args
,
src
.
fun
==
'pwl
r
'
);
pwl_source
(
src
,
src
.
args
,
src
.
fun
==
'pwl
_repeating
'
);
}
}
// post-processing for pulsed sources
// post-processing for pulsed sources
...
@@ -1122,18 +1145,18 @@ cktsim = (function() {
...
@@ -1122,18 +1145,18 @@ cktsim = (function() {
var
v1
=
arg_value
(
src
.
args
,
0
,
0
);
// default init value: 0V
var
v1
=
arg_value
(
src
.
args
,
0
,
0
);
// default init value: 0V
var
v2
=
arg_value
(
src
.
args
,
1
,
1
);
// default plateau value: 1V
var
v2
=
arg_value
(
src
.
args
,
1
,
1
);
// default plateau value: 1V
var
td
=
Math
.
max
(
0
,
arg_value
(
src
.
args
,
2
,
0
));
// time pulse starts
var
td
=
Math
.
max
(
0
,
arg_value
(
src
.
args
,
2
,
0
));
// time pulse starts
var
tr
=
Math
.
abs
(
arg_value
(
src
.
args
,
3
,
1
e
-
9
));
// default rise time: 1ns
var
tr
=
Math
.
abs
(
arg_value
(
src
.
args
,
3
,
1
e
-
9
));
// default rise time: 1ns
var
tf
=
Math
.
abs
(
arg_value
(
src
.
args
,
4
,
1
e
-
9
));
// default rise time: 1ns
var
tf
=
Math
.
abs
(
arg_value
(
src
.
args
,
4
,
1
e
-
9
));
// default rise time: 1ns
var
pw
=
Math
.
abs
(
arg_value
(
src
.
args
,
5
,
1
e9
));
// default pulse width: "infinite"
var
pw
=
Math
.
abs
(
arg_value
(
src
.
args
,
5
,
1
e9
));
// default pulse width: "infinite"
var
per
=
Math
.
abs
(
arg_value
(
src
.
args
,
6
,
1
e9
));
// default period: "infinite"
var
per
=
Math
.
abs
(
arg_value
(
src
.
args
,
6
,
1
e9
));
// default period: "infinite"
src
.
args
=
[
v1
,
v2
,
td
,
tr
,
tf
,
pw
,
per
];
var
t1
=
td
;
// time when v1 -> v2 transition starts
var
t1
=
td
;
// time when v1 -> v2 transition starts
var
t2
=
t1
+
tr
;
// time when v1 -> v2 transition ends
var
t2
=
t1
+
tr
;
// time when v1 -> v2 transition ends
var
t3
=
t2
+
pw
;
// time when v2 -> v1 transition starts
var
t3
=
t2
+
pw
;
// time when v2 -> v1 transition starts
var
t4
=
t3
+
tf
;
// time when v2 -> v1 transition ends
var
t4
=
t3
+
tf
;
// time when v2 -> v1 transition ends
pwl_source
(
src
,[
t1
,
v1
,
t2
,
v2
,
t3
,
v2
,
t4
,
v1
,
per
,
v1
],
true
);
pwl_source
(
src
,[
t1
,
v1
,
t2
,
v2
,
t3
,
v2
,
t4
,
v1
,
per
,
v1
],
true
);
}
}
// post-processing for sinusoidal sources
// post-processing for sinusoidal sources
...
@@ -1144,16 +1167,14 @@ cktsim = (function() {
...
@@ -1144,16 +1167,14 @@ cktsim = (function() {
var
freq
=
Math
.
abs
(
arg_value
(
src
.
args
,
2
,
1
));
// default frequency: 1Hz
var
freq
=
Math
.
abs
(
arg_value
(
src
.
args
,
2
,
1
));
// default frequency: 1Hz
var
td
=
Math
.
max
(
0
,
arg_value
(
src
.
args
,
3
,
0
));
// default time delay: 0sec
var
td
=
Math
.
max
(
0
,
arg_value
(
src
.
args
,
3
,
0
));
// default time delay: 0sec
var
phase
=
arg_value
(
src
.
args
,
4
,
0
);
// default phase offset: 0 degrees
var
phase
=
arg_value
(
src
.
args
,
4
,
0
);
// default phase offset: 0 degrees
src
.
args
=
[
voffset
,
va
,
freq
,
td
,
phase
];
phase
/=
360.0
;
phase
/=
360.0
;
// return value of source at time t
// return value of source at time t
src
.
value
=
function
(
t
)
{
// closure
src
.
value
=
function
(
t
)
{
// closure
if
(
t
<
td
)
return
voffset
+
va
*
Math
.
sin
(
2
*
Math
.
PI
*
phase
);
if
(
t
<
td
)
return
voffset
+
va
*
Math
.
sin
(
2
*
Math
.
PI
*
phase
);
else
{
else
return
voffset
+
va
*
Math
.
sin
(
2
*
Math
.
PI
*
(
freq
*
(
t
-
td
)
+
phase
));
var
val
=
voffset
+
va
*
Math
.
sin
(
2
*
Math
.
PI
*
(
freq
*
(
t
-
td
)
+
phase
));
return
val
;
}
}
}
// return time of next inflection point after time t
// return time of next inflection point after time t
...
@@ -1163,9 +1184,6 @@ cktsim = (function() {
...
@@ -1163,9 +1184,6 @@ cktsim = (function() {
}
}
}
}
// to do:
// post-processing for piece-wise linear sources
// object has all the necessary info to compute the source value and inflection points
// object has all the necessary info to compute the source value and inflection points
src
.
dc
=
src
.
value
(
0
);
// DC value is value at time 0
src
.
dc
=
src
.
value
(
0
);
// DC value is value at time 0
return
src
;
return
src
;
...
@@ -1531,6 +1549,7 @@ cktsim = (function() {
...
@@ -1531,6 +1549,7 @@ cktsim = (function() {
var
module
=
{
var
module
=
{
'Circuit'
:
Circuit
,
'Circuit'
:
Circuit
,
'parse_number'
:
parse_number
,
'parse_number'
:
parse_number
,
'parse_source'
:
parse_source
,
}
}
return
module
;
return
module
;
}());
}());
js/schematic.js
View file @
0510e96a
...
@@ -594,8 +594,9 @@ schematic = (function() {
...
@@ -594,8 +594,9 @@ schematic = (function() {
var
json
=
[];
var
json
=
[];
// output all the components/wires in the diagram
// output all the components/wires in the diagram
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
var
n
=
this
.
components
.
length
;
json
.
push
(
this
.
components
[
i
].
json
());
for
(
var
i
=
0
;
i
<
n
;
i
++
)
json
.
push
(
this
.
components
[
i
].
json
(
i
));
// capture the current view parameters
// capture the current view parameters
json
.
push
([
'view'
,
this
.
origin_x
,
this
.
origin_y
,
this
.
scale
,
json
.
push
([
'view'
,
this
.
origin_x
,
this
.
origin_y
,
this
.
scale
,
...
@@ -932,6 +933,10 @@ schematic = (function() {
...
@@ -932,6 +933,10 @@ schematic = (function() {
// for each electrical node
// for each electrical node
for
(
var
location
in
this
.
connection_points
)
for
(
var
location
in
this
.
connection_points
)
(
this
.
connection_points
[
location
])[
0
].
display_voltage
(
c
,
temp
);
(
this
.
connection_points
[
location
])[
0
].
display_voltage
(
c
,
temp
);
// let components display branch current info if available
for
(
var
i
=
this
.
components
.
length
-
1
;
i
>=
0
;
--
i
)
this
.
components
[
i
].
display_current
(
c
,
temp
)
}
}
}
}
...
@@ -980,9 +985,6 @@ schematic = (function() {
...
@@ -980,9 +985,6 @@ schematic = (function() {
c
.
fillText
(
text
,(
x
-
this
.
origin_x
)
*
this
.
scale
,(
y
-
this
.
origin_y
)
*
this
.
scale
);
c
.
fillText
(
text
,(
x
-
this
.
origin_x
)
*
this
.
scale
,(
y
-
this
.
origin_y
)
*
this
.
scale
);
}
}
HTMLCanvasElement
.
prototype
.
totalOffset
=
function
(){
}
// add method to canvas to compute relative coords for event
// add method to canvas to compute relative coords for event
HTMLCanvasElement
.
prototype
.
relMouseCoords
=
function
(
event
){
HTMLCanvasElement
.
prototype
.
relMouseCoords
=
function
(
event
){
// run up the DOM tree to figure out coords for top,left of canvas
// run up the DOM tree to figure out coords for top,left of canvas
...
@@ -1678,8 +1680,9 @@ schematic = (function() {
...
@@ -1678,8 +1680,9 @@ schematic = (function() {
return
[
vmin
,
vmax
,
1.0
/
scale
];
return
[
vmin
,
vmax
,
1.0
/
scale
];
}
}
function
engineering_notation
(
n
,
nplaces
)
{
function
engineering_notation
(
n
,
nplaces
,
trim
)
{
if
(
n
==
0
)
return
(
"0"
);
if
(
n
==
0
)
return
(
"0"
);
if
(
trim
==
undefined
)
trim
=
true
;
var
sign
=
n
<
0
?
-
1
:
1
;
var
sign
=
n
<
0
?
-
1
:
1
;
var
log10
=
Math
.
log
(
sign
*
n
)
/
Math
.
LN10
;
var
log10
=
Math
.
log
(
sign
*
n
)
/
Math
.
LN10
;
...
@@ -1694,9 +1697,11 @@ schematic = (function() {
...
@@ -1694,9 +1697,11 @@ schematic = (function() {
if
(
nplaces
>
0
)
{
if
(
nplaces
>
0
)
{
endindex
+=
nplaces
+
1
;
endindex
+=
nplaces
+
1
;
if
(
endindex
>
mlen
)
endindex
=
mlen
;
if
(
endindex
>
mlen
)
endindex
=
mlen
;
if
(
trim
)
{
while
(
mstring
.
charAt
(
endindex
-
1
)
==
'0'
)
endindex
-=
1
;
while
(
mstring
.
charAt
(
endindex
-
1
)
==
'0'
)
endindex
-=
1
;
if
(
mstring
.
charAt
(
endindex
-
1
)
==
'.'
)
endindex
-=
1
;
if
(
mstring
.
charAt
(
endindex
-
1
)
==
'.'
)
endindex
-=
1
;
}
}
}
if
(
endindex
<
mlen
)
if
(
endindex
<
mlen
)
mstring
=
mstring
.
substring
(
0
,
endindex
);
mstring
=
mstring
.
substring
(
0
,
endindex
);
}
}
...
@@ -1717,6 +1722,9 @@ schematic = (function() {
...
@@ -1717,6 +1722,9 @@ schematic = (function() {
return
n
.
toString
();
return
n
.
toString
();
}
}
var
grid_pattern
=
[
1
,
2
];
var
cursor_pattern
=
[
5
,
5
];
// x_values is an array of x coordinates for each of the plots
// x_values is an array of x coordinates for each of the plots
// y_values is an array of [color, value_array], one entry for each plot
// y_values is an array of [color, value_array], one entry for each plot
Schematic
.
prototype
.
graph
=
function
(
x_values
,
y_values
,
x_legend
,
y_legend
)
{
Schematic
.
prototype
.
graph
=
function
(
x_values
,
y_values
,
x_legend
,
y_legend
)
{
...
@@ -1727,7 +1735,6 @@ schematic = (function() {
...
@@ -1727,7 +1735,6 @@ schematic = (function() {
var
right_margin
=
25
;
var
right_margin
=
25
;
var
bottom_margin
=
45
;
var
bottom_margin
=
45
;
var
tick_length
=
5
;
var
tick_length
=
5
;
var
pattern
=
[
1
,
2
];
var
w
=
pwidth
+
left_margin
+
right_margin
;
var
w
=
pwidth
+
left_margin
+
right_margin
;
var
h
=
pheight
+
top_margin
+
bottom_margin
;
var
h
=
pheight
+
top_margin
+
bottom_margin
;
...
@@ -1779,7 +1786,7 @@ schematic = (function() {
...
@@ -1779,7 +1786,7 @@ schematic = (function() {
c
.
moveTo
(
temp
,
top_margin
);
c
.
moveTo
(
temp
,
top_margin
);
c
.
lineTo
(
temp
,
end
);
c
.
lineTo
(
temp
,
end
);
}
else
}
else
c
.
dashedLineTo
(
temp
,
top_margin
,
temp
,
end
,
pattern
);
c
.
dashedLineTo
(
temp
,
top_margin
,
temp
,
end
,
grid_
pattern
);
c
.
stroke
();
c
.
stroke
();
// tick mark
// tick mark
...
@@ -1821,7 +1828,7 @@ schematic = (function() {
...
@@ -1821,7 +1828,7 @@ schematic = (function() {
c
.
moveTo
(
left_margin
,
temp
);
c
.
moveTo
(
left_margin
,
temp
);
c
.
lineTo
(
left_margin
+
pwidth
,
temp
);
c
.
lineTo
(
left_margin
+
pwidth
,
temp
);
}
else
}
else
c
.
dashedLineTo
(
left_margin
,
temp
,
left_margin
+
pwidth
,
temp
,
pattern
);
c
.
dashedLineTo
(
left_margin
,
temp
,
left_margin
+
pwidth
,
temp
,
grid_
pattern
);
c
.
stroke
();
c
.
stroke
();
// tick mark
// tick mark
...
@@ -1864,6 +1871,27 @@ schematic = (function() {
...
@@ -1864,6 +1871,27 @@ schematic = (function() {
c
.
fillText
(
y_legend
,
0
,
0
);
c
.
fillText
(
y_legend
,
0
,
0
);
c
.
restore
();
c
.
restore
();
// save info need for interactions with the graph
canvas
.
x_values
=
x_values
;
canvas
.
y_values
=
y_values
;
canvas
.
x_legend
=
x_legend
;
canvas
.
y_legend
=
y_legend
;
canvas
.
x_min
=
x_min
;
canvas
.
x_scale
=
x_scale
;
canvas
.
y_min
=
y_min
;
canvas
.
y_scale
=
y_scale
;
canvas
.
left_margin
=
left_margin
;
canvas
.
top_margin
=
top_margin
;
canvas
.
pwidth
=
pwidth
;
canvas
.
pheight
=
pheight
;
canvas
.
tick_length
=
tick_length
;
canvas
.
cursor_x
=
undefined
;
canvas
.
sch
=
this
;
// do something useful when user mouses over graph
canvas
.
addEventListener
(
'mousemove'
,
graph_mouse_move
,
false
);
// return our masterpiece
// return our masterpiece
redraw_plot
(
canvas
);
redraw_plot
(
canvas
);
return
canvas
;
return
canvas
;
...
@@ -1883,9 +1911,73 @@ schematic = (function() {
...
@@ -1883,9 +1911,73 @@ schematic = (function() {
return
min
;
return
min
;
}
}
function
redraw_plot
(
canvas
)
{
function
redraw_plot
(
graph
)
{
var
c
=
canvas
.
getContext
(
'2d'
);
var
c
=
graph
.
getContext
(
'2d'
);
c
.
drawImage
(
canvas
.
bg_image
,
0
,
0
);
c
.
drawImage
(
graph
.
bg_image
,
0
,
0
);
if
(
graph
.
cursor_x
!=
undefined
)
{
// draw dashed vertical marker that follows mouse
var
x
=
graph
.
left_margin
+
graph
.
cursor_x
;
var
end_y
=
graph
.
top_margin
+
graph
.
pheight
+
graph
.
tick_length
;
c
.
strokeStyle
=
grid_style
;
c
.
lineWidth
=
1
;
c
.
beginPath
();
c
.
dashedLineTo
(
x
,
graph
.
top_margin
,
x
,
end_y
,
cursor_pattern
);
c
.
stroke
();
// add x label at bottom of marker
var
graph_x
=
graph
.
cursor_x
/
graph
.
x_scale
+
graph
.
x_min
;
c
.
font
=
'10pt sans-serif'
;
c
.
textAlign
=
'center'
;
c
.
textBaseline
=
'top'
;
c
.
fillStyle
=
background_style
;
c
.
fillText
(
'
\
u2588
\
u2588
\
u2588
\
u2588
\
u2588'
,
x
,
end_y
);
c
.
fillStyle
=
normal_style
;
c
.
fillText
(
engineering_notation
(
graph_x
,
3
,
false
),
x
,
end_y
);
// compute which points marker is between
var
x_values
=
graph
.
x_values
;
var
len
=
x_values
.
length
;
var
index
=
0
;
while
(
index
<
len
&&
graph_x
>=
x_values
[
index
])
index
+=
1
;
var
x1
=
(
index
==
0
)
?
x_values
[
0
]
:
x_values
[
index
-
1
];
var
x2
=
x_values
[
index
];
// for each plot, interpolate and output value at intersection with marker
c
.
textAlign
=
'left'
;
var
tx
=
graph
.
left_margin
+
4
;
var
ty
=
graph
.
top_margin
;
for
(
var
plot
=
0
;
plot
<
graph
.
y_values
.
length
;
plot
++
)
{
var
values
=
graph
.
y_values
[
plot
][
1
];
// interpolate signal value at graph_x using values[index-1] and values[index]
var
y1
=
(
index
==
0
)
?
values
[
0
]
:
values
[
index
-
1
];
var
y2
=
values
[
index
];
var
y
=
y1
;
if
(
graph_x
!=
x1
)
y
+=
(
graph_x
-
x1
)
*
(
y2
-
y1
)
/
(
x2
-
x1
);
// annotate plot with value of signal at marker
c
.
fillStyle
=
element_style
;
c
.
fillText
(
'
\
u2588
\
u2588
\
u2588
\
u2588
\
u2588'
,
tx
-
3
,
ty
);
c
.
fillStyle
=
probe_colors_rgb
[
graph
.
y_values
[
plot
][
0
]];
c
.
fillText
(
engineering_notation
(
y
,
3
,
false
),
tx
,
ty
);
ty
+=
14
;
}
}
}
function
graph_mouse_move
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
g
=
(
window
.
event
)
?
event
.
srcElement
:
event
.
target
;
g
.
relMouseCoords
(
event
);
// not sure yet where the 3,-3 offset correction comes from (borders? padding?)
var
gx
=
g
.
mouse_x
-
g
.
left_margin
-
3
;
var
gy
=
g
.
pheight
-
(
g
.
mouse_y
-
g
.
top_margin
)
+
3
;
if
(
gx
>=
0
&&
gx
<=
g
.
pwidth
&&
gy
>=
0
&&
gy
<=
g
.
pheight
)
g
.
cursor_x
=
gx
;
else
g
.
cursor_x
=
undefined
;
redraw_plot
(
g
);
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
...
@@ -2112,7 +2204,9 @@ schematic = (function() {
...
@@ -2112,7 +2204,9 @@ schematic = (function() {
this
.
connections
=
[];
this
.
connections
=
[];
}
}
Component
.
prototype
.
json
=
function
()
{
Component
.
prototype
.
json
=
function
(
index
)
{
this
.
properties
[
'_json_'
]
=
index
;
// remember where we are in the JSON list
var
props
=
{};
var
props
=
{};
for
(
var
p
in
this
.
properties
)
props
[
p
]
=
this
.
properties
[
p
];
for
(
var
p
in
this
.
properties
)
props
[
p
]
=
this
.
properties
[
p
];
...
@@ -2343,6 +2437,8 @@ schematic = (function() {
...
@@ -2343,6 +2437,8 @@ schematic = (function() {
// make an <input> widget for each property
// make an <input> widget for each property
var
fields
=
new
Array
();
var
fields
=
new
Array
();
for
(
var
i
in
this
.
properties
)
for
(
var
i
in
this
.
properties
)
// underscore at beginning of property name => system property
if
(
i
.
charAt
(
0
)
!=
'_'
)
fields
[
i
]
=
build_input
(
'text'
,
10
,
this
.
properties
[
i
]);
fields
[
i
]
=
build_input
(
'text'
,
10
,
this
.
properties
[
i
]);
var
content
=
build_table
(
fields
);
var
content
=
build_table
(
fields
);
...
@@ -2383,6 +2479,10 @@ schematic = (function() {
...
@@ -2383,6 +2479,10 @@ schematic = (function() {
}
}
}
}
// default behavior: nothing to display for DC analysis
Component
.
prototype
.
display_current
=
function
(
c
,
vmap
)
{
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Connection point
// Connection point
...
@@ -2507,7 +2607,7 @@ schematic = (function() {
...
@@ -2507,7 +2607,7 @@ schematic = (function() {
return
'<Wire ('
+
this
.
x
+
','
+
this
.
y
+
') ('
+
(
this
.
x
+
this
.
dx
)
+
','
+
(
this
.
y
+
this
.
dy
)
+
')>'
;
return
'<Wire ('
+
this
.
x
+
','
+
this
.
y
+
') ('
+
(
this
.
x
+
this
.
dx
)
+
','
+
(
this
.
y
+
this
.
dy
)
+
')>'
;
}
}
Wire
.
prototype
.
json
=
function
()
{
Wire
.
prototype
.
json
=
function
(
index
)
{
var
json
=
[
'w'
,[
this
.
x
,
this
.
y
,
this
.
x
+
this
.
dx
,
this
.
y
+
this
.
dy
]];
var
json
=
[
'w'
,[
this
.
x
,
this
.
y
,
this
.
x
+
this
.
dx
,
this
.
y
+
this
.
dy
]];
return
json
;
return
json
;
}
}
...
@@ -3024,14 +3124,18 @@ schematic = (function() {
...
@@ -3024,14 +3124,18 @@ schematic = (function() {
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
function
Source
(
x
,
y
,
rotation
,
name
,
type
,
value
)
{
function
Source
(
x
,
y
,
rotation
,
name
,
type
,
value
)
{
Component
.
call
(
this
,
type
,
x
,
y
,
rotation
);
Component
.
call
(
this
,
type
,
x
,
y
,
rotation
);
this
.
properties
[
'name'
]
=
name
;
this
.
properties
[
'name'
]
=
name
;
this
.
properties
[
'value'
]
=
value
?
value
:
'1'
;
if
(
value
==
undefined
)
value
=
'dc(1)'
;
this
.
properties
[
'value'
]
=
value
;
this
.
add_connection
(
0
,
0
);
this
.
add_connection
(
0
,
0
);
this
.
add_connection
(
0
,
48
);
this
.
add_connection
(
0
,
48
);
this
.
bounding_box
=
[
-
12
,
0
,
12
,
48
];
this
.
bounding_box
=
[
-
12
,
0
,
12
,
48
];
this
.
update_coords
();
this
.
update_coords
();
this
.
content
=
document
.
createElement
(
'div'
);
// used by edit_properties
}
}
Source
.
prototype
=
new
Component
();
Source
.
prototype
=
new
Component
();
Source
.
prototype
.
constructor
=
Source
;
Source
.
prototype
.
constructor
=
Source
;
...
@@ -3068,10 +3172,141 @@ schematic = (function() {
...
@@ -3068,10 +3172,141 @@ schematic = (function() {
this
.
draw_text
(
c
,
this
.
properties
[
'value'
],
13
,
24
,
3
,
property_size
);
this
.
draw_text
(
c
,
this
.
properties
[
'value'
],
13
,
24
,
3
,
property_size
);
}
}
Source
.
prototype
.
clone
=
function
(
x
,
y
)
{
// map source function name to labels for each source parameter
return
new
Source
(
x
,
y
,
this
.
rotation
,
this
.
properties
[
'name'
],
this
.
type
,
this
.
properties
[
'value'
]);
source_functions
=
{
'dc'
:
[
'DC value'
],
'step'
:
[
'Initial value'
,
'Plateau value'
,
'Delay until step (secs)'
,
'Rise time (secs)'
],
'square'
:
[
'Initial value'
,
'Plateau value'
,
'Frequency (Hz)'
],
'triangle'
:
[
'Initial value'
,
'Plateau value'
,
'Frequency (Hz)'
],
'pwl'
:
[
'Comma-separated list of alternating times and values'
],
'pwl_repeating'
:
[
'Comma-separated list of alternating times and values'
],
'pulse'
:
[
'Initial value'
,
'Plateau value'
,
'Delay until pulse (secs)'
,
'Time for first transition (secs)'
,
'Time for second transition (secs)'
,
'Pulse width (secs)'
,
'Period (secs)'
],
'sin'
:
[
'Offset value'
,
'Amplitude'
,
'Frequency (Hz)'
,
'Delay until sin starts (secs)'
,
'Phase offset (degrees)'
],
}
// build property editor div
Source
.
prototype
.
build_content
=
function
(
src
)
{
// make an <input> widget for each property
var
fields
=
[]
fields
[
'name'
]
=
build_input
(
'text'
,
10
,
this
.
properties
[
'name'
]);
if
(
src
==
undefined
)
{
fields
[
'value'
]
=
this
.
properties
[
'value'
];
}
else
{
// fancy version: add select tag for source type
var
src_types
=
[];
for
(
var
t
in
source_functions
)
src_types
.
push
(
t
);
var
type_select
=
build_select
(
src_types
,
src
.
fun
);
type_select
.
component
=
this
;
type_select
.
addEventListener
(
'change'
,
source_type_changed
,
false
)
fields
[
'type'
]
=
type_select
;
if
(
src
.
fun
==
'pwl'
||
src
.
run
==
'pwl_repeating'
)
{
var
v
=
''
;
var
first
=
true
;
for
(
var
i
=
0
;
i
<
src
.
args
.
length
;
i
++
)
{
if
(
first
)
first
=
false
;
else
v
+=
','
;
v
+=
engineering_notation
(
src
.
args
[
i
],
3
);
if
(
i
%
2
==
0
)
v
+=
's'
;
}
fields
[
source_functions
[
src
.
fun
][
0
]]
=
build_input
(
'text'
,
30
,
v
);
}
else
{
// followed separate input tag for each parameter
var
labels
=
source_functions
[
src
.
fun
];
for
(
var
i
=
0
;
i
<
labels
.
length
;
i
++
)
{
var
v
=
engineering_notation
(
src
.
args
[
i
],
3
);
fields
[
labels
[
i
]]
=
build_input
(
'text'
,
10
,
v
);
}
}
}
var
div
=
this
.
content
;
if
(
div
.
hasChildNodes
())
div
.
removeChild
(
div
.
firstChild
);
// remove table of input fields
div
.
appendChild
(
build_table
(
fields
));
div
.
fields
=
fields
;
div
.
component
=
this
;
return
div
;
}
function
source_type_changed
(
event
)
{
if
(
!
event
)
event
=
window
.
event
;
var
select
=
(
window
.
event
)
?
event
.
srcElement
:
event
.
target
;
// see where to get source parameters from
var
type
=
select
.
options
[
select
.
selectedIndex
].
value
;
var
src
=
undefined
;
if
(
this
.
src
!=
undefined
&&
type
==
this
.
src
.
fun
)
src
=
this
.
src
;
else
if
(
typeof
cktsim
!=
'undefined'
)
src
=
cktsim
.
parse_source
(
type
+
'()'
);
select
.
component
.
build_content
(
src
);
}
Source
.
prototype
.
edit_properties
=
function
(
x
,
y
)
{
if
(
this
.
near
(
x
,
y
))
{
this
.
src
=
undefined
;
if
(
typeof
cktsim
!=
'undefined'
)
this
.
src
=
cktsim
.
parse_source
(
this
.
properties
[
'value'
]);
var
content
=
this
.
build_content
(
this
.
src
);
this
.
sch
.
dialog
(
'Edit Properties'
,
content
,
function
(
content
)
{
var
c
=
content
.
component
;
var
fields
=
content
.
fields
;
var
first
=
true
;
var
value
=
''
;
for
(
var
label
in
fields
)
{
if
(
label
==
'name'
)
c
.
properties
[
'name'
]
=
fields
[
'name'
].
value
;
else
if
(
label
==
'value'
)
{
// if unknown source type
value
=
fields
[
'value'
].
value
;
c
.
sch
.
redraw_background
();
return
;
}
else
if
(
label
==
'type'
)
{
var
select
=
fields
[
'type'
];
value
=
select
.
options
[
select
.
selectedIndex
].
value
+
'('
;
}
else
{
if
(
first
)
first
=
false
;
else
value
+=
','
;
value
+=
fields
[
label
].
value
;
}
}
c
.
properties
[
'value'
]
=
value
+
')'
;
c
.
sch
.
redraw_background
();
});
return
true
;
}
else
return
false
;
}
}
function
VSource
(
x
,
y
,
rotation
,
name
,
value
)
{
function
VSource
(
x
,
y
,
rotation
,
name
,
value
)
{
Source
.
call
(
this
,
x
,
y
,
rotation
,
name
,
'v'
,
value
);
Source
.
call
(
this
,
x
,
y
,
rotation
,
name
,
'v'
,
value
);
this
.
type
=
'v'
;
this
.
type
=
'v'
;
...
@@ -3081,6 +3316,32 @@ schematic = (function() {
...
@@ -3081,6 +3316,32 @@ schematic = (function() {
VSource
.
prototype
.
toString
=
Source
.
prototype
.
toString
;
VSource
.
prototype
.
toString
=
Source
.
prototype
.
toString
;
VSource
.
prototype
.
draw
=
Source
.
prototype
.
draw
;
VSource
.
prototype
.
draw
=
Source
.
prototype
.
draw
;
VSource
.
prototype
.
clone
=
Source
.
prototype
.
clone
;
VSource
.
prototype
.
clone
=
Source
.
prototype
.
clone
;
VSource
.
prototype
.
build_content
=
Source
.
prototype
.
build_content
;
VSource
.
prototype
.
edit_properties
=
Source
.
prototype
.
edit_properties
;
// display current for DC analysis
VSource
.
prototype
.
display_current
=
function
(
c
,
vmap
)
{
var
name
=
this
.
properties
[
'name'
];
var
label
=
'I('
+
(
name
?
name
:
'_'
+
this
.
properties
[
'_json_'
])
+
')'
;
var
v
=
vmap
[
label
];
if
(
v
!=
undefined
)
{
// first draw some solid blocks in the background
c
.
globalAlpha
=
0.85
;
this
.
draw_text
(
c
,
'
\
u2588
\
u2588
\
u2588'
,
0
,
24
,
4
,
annotation_size
,
element_style
);
c
.
globalAlpha
=
1.0
;
// display the node voltage at this connection point
var
i
=
engineering_notation
(
v
,
2
)
+
'A'
;
this
.
draw_text
(
c
,
i
,
0
,
24
,
4
,
annotation_size
,
annotation_style
);
// only display each current once
delete
vmap
[
label
];
}
}
VSource
.
prototype
.
clone
=
function
(
x
,
y
)
{
return
new
VSource
(
x
,
y
,
this
.
rotation
,
this
.
properties
[
'name'
],
this
.
properties
[
'value'
]);
}
function
ISource
(
x
,
y
,
rotation
,
name
,
value
)
{
function
ISource
(
x
,
y
,
rotation
,
name
,
value
)
{
Source
.
call
(
this
,
x
,
y
,
rotation
,
name
,
'i'
,
value
);
Source
.
call
(
this
,
x
,
y
,
rotation
,
name
,
'i'
,
value
);
...
@@ -3091,6 +3352,12 @@ schematic = (function() {
...
@@ -3091,6 +3352,12 @@ schematic = (function() {
ISource
.
prototype
.
toString
=
Source
.
prototype
.
toString
;
ISource
.
prototype
.
toString
=
Source
.
prototype
.
toString
;
ISource
.
prototype
.
draw
=
Source
.
prototype
.
draw
;
ISource
.
prototype
.
draw
=
Source
.
prototype
.
draw
;
ISource
.
prototype
.
clone
=
Source
.
prototype
.
clone
;
ISource
.
prototype
.
clone
=
Source
.
prototype
.
clone
;
ISource
.
prototype
.
build_content
=
Source
.
prototype
.
build_content
;
ISource
.
prototype
.
edit_properties
=
Source
.
prototype
.
edit_properties
;
ISource
.
prototype
.
clone
=
function
(
x
,
y
)
{
return
new
ISource
(
x
,
y
,
this
.
rotation
,
this
.
properties
[
'name'
],
this
.
properties
[
'value'
]);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
//
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment