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
cc40a3c0
Commit
cc40a3c0
authored
Jan 27, 2012
by
cjt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated schematic tool files
parent
73622538
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
331 additions
and
45 deletions
+331
-45
js/cktsim.js
+43
-24
js/schematic.js
+288
-21
No files found.
js/cktsim.js
View file @
cc40a3c0
...
@@ -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 @
cc40a3c0
...
@@ -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,8 +1697,10 @@ schematic = (function() {
...
@@ -1694,8 +1697,10 @@ schematic = (function() {
if
(
nplaces
>
0
)
{
if
(
nplaces
>
0
)
{
endindex
+=
nplaces
+
1
;
endindex
+=
nplaces
+
1
;
if
(
endindex
>
mlen
)
endindex
=
mlen
;
if
(
endindex
>
mlen
)
endindex
=
mlen
;
while
(
mstring
.
charAt
(
endindex
-
1
)
==
'0'
)
endindex
-=
1
;
if
(
trim
)
{
if
(
mstring
.
charAt
(
endindex
-
1
)
==
'.'
)
endindex
-=
1
;
while
(
mstring
.
charAt
(
endindex
-
1
)
==
'0'
)
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
;
...
@@ -1735,7 +1742,7 @@ schematic = (function() {
...
@@ -1735,7 +1742,7 @@ schematic = (function() {
var
canvas
=
document
.
createElement
(
'canvas'
);
var
canvas
=
document
.
createElement
(
'canvas'
);
canvas
.
width
=
w
;
canvas
.
width
=
w
;
canvas
.
height
=
h
;
canvas
.
height
=
h
;
// the graph itself will be drawn here and this image will be copied
// the graph itself will be drawn here and this image will be copied
// onto canvas, where it can be overlayed with mouse cursors, etc.
// onto canvas, where it can be overlayed with mouse cursors, etc.
var
bg_image
=
document
.
createElement
(
'canvas'
);
var
bg_image
=
document
.
createElement
(
'canvas'
);
...
@@ -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,7 +2437,9 @@ schematic = (function() {
...
@@ -2343,7 +2437,9 @@ 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
)
fields
[
i
]
=
build_input
(
'text'
,
10
,
this
.
properties
[
i
]);
// underscore at beginning of property name => system property
if
(
i
.
charAt
(
0
)
!=
'_'
)
fields
[
i
]
=
build_input
(
'text'
,
10
,
this
.
properties
[
i
]);
var
content
=
build_table
(
fields
);
var
content
=
build_table
(
fields
);
content
.
fields
=
fields
;
content
.
fields
=
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