Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
Printrun
Project
Project
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
machinery
Printrun
Commits
edb2c12c
Commit
edb2c12c
authored
May 28, 2013
by
Guillaume Seguin
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'resizing_graph' of
https://github.com/sbliven/Printrun
into experimental
parents
0ab0d9af
a008aa47
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
169 additions
and
31 deletions
+169
-31
graph.py
printrun/graph.py
+169
-31
No files found.
printrun/graph.py
View file @
edb2c12c
...
...
@@ -16,6 +16,7 @@
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import
wx
,
random
from
math
import
log10
,
floor
,
ceil
from
bufferedcanvas
import
*
...
...
@@ -39,15 +40,18 @@ class Graph(BufferedCanvas):
self
.
timer
=
wx
.
Timer
(
self
)
self
.
Bind
(
wx
.
EVT_TIMER
,
self
.
updateTemperatures
,
self
.
timer
)
self
.
minyvalue
=
0
self
.
maxyvalue
=
250
self
.
rescaley
=
True
# should the Y axis be rescaled dynamically?
if
self
.
rescaley
:
self
.
_ybounds
=
Graph
.
_YBounds
(
self
)
#If rescaley is set then ybars gives merely an estimate
#Note that "bars" actually indicate the number of grid _intervals_
self
.
ybars
=
5
self
.
xbars
=
6
# One bar per 10 second
self
.
xsteps
=
60
# Covering 1 minute in the graph
self
.
y_offset
=
1
# This is to show the line even when value is 0 and maxyvalue
self
.
_lastyvalue
=
0
def
OnPaint
(
self
,
evt
):
dc
=
wx
.
PaintDC
(
self
)
gc
=
wx
.
GraphicsContext
.
Create
(
dc
)
...
...
@@ -57,8 +61,10 @@ class Graph(BufferedCanvas):
self
.
AddBedTargetTemperature
(
self
.
bedtargettemps
[
-
1
])
self
.
AddExtruder0Temperature
(
self
.
extruder0temps
[
-
1
])
self
.
AddExtruder0TargetTemperature
(
self
.
extruder0targettemps
[
-
1
])
#self.AddExtruder1Temperature(self.extruder1temps[-1])
#self.AddExtruder1TargetTemperature(self.extruder1targettemps[-1])
self
.
AddExtruder1Temperature
(
self
.
extruder1temps
[
-
1
])
self
.
AddExtruder1TargetTemperature
(
self
.
extruder1targettemps
[
-
1
])
if
self
.
rescaley
:
self
.
_ybounds
.
update
()
self
.
Refresh
()
def
drawgrid
(
self
,
dc
,
gc
):
...
...
@@ -68,36 +74,35 @@ class Graph(BufferedCanvas):
#b = gc.CreateLinearGradientBrush(0, 0, w, h, col1, col2)
gc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
255
,
0
,
0
,
0
),
4
))
gc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
255
,
0
,
0
,
0
),
1
))
#gc.SetBrush(wx.Brush(wx.Colour(245, 245, 255, 52)))
#gc.SetBrush(gc.CreateBrush(wx.Brush(wx.Colour(0, 0, 0, 255))))
#gc.SetPen(wx.Pen(wx.Colour(255, 0, 0, 0), 4
))
gc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
255
,
0
,
0
,
255
),
1
))
#gc.DrawLines(wx.Point(0, 0), wx.Point(50, 10))
#path = gc.CreatePath()
#path.MoveToPoint(0.0, 0.0)
#path.AddLineToPoint(0.0, 100.0)
#path.AddLineToPoint(100.0, 0.0)
#path.AddCircle( 50.0, 50.0, 50.0 )
#path.CloseSubpath()
#gc.DrawPath(path)
#gc.StrokePath(path)
font
=
wx
.
Font
(
10
,
wx
.
DEFAULT
,
wx
.
NORMAL
,
wx
.
BOLD
)
gc
.
SetFont
(
font
,
wx
.
Colour
(
23
,
44
,
44
))
# draw vertical bars
dc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
225
,
225
,
225
),
1
))
for
x
in
range
(
self
.
xbars
):
dc
.
DrawLine
(
x
*
(
float
(
self
.
width
)
/
self
.
xbars
),
0
,
x
*
(
float
(
self
.
width
)
/
self
.
xbars
),
self
.
height
)
for
x
in
range
(
self
.
xbars
+
1
):
dc
.
DrawLine
(
x
*
(
float
(
self
.
width
-
1
)
/
(
self
.
xbars
-
1
)),
0
,
x
*
(
float
(
self
.
width
-
1
)
/
(
self
.
xbars
-
1
)),
self
.
height
)
# draw horizontal bars
spacing
=
self
.
_calculate_spacing
()
#spacing between bars, in degrees
yspan
=
self
.
maxyvalue
-
self
.
minyvalue
ybars
=
int
(
yspan
/
spacing
)
#Should be close to self.ybars
firstbar
=
int
(
ceil
(
self
.
minyvalue
/
spacing
))
#in degrees
dc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
225
,
225
,
225
),
1
))
for
y
in
range
(
self
.
ybars
):
y_pos
=
y
*
(
float
(
self
.
height
)
/
self
.
ybars
)
for
y
in
xrange
(
firstbar
,
firstbar
+
ybars
+
1
):
#y_pos = y*(float(self.height)/self.ybars)
degrees
=
y
*
spacing
y_pos
=
self
.
_y_pos
(
degrees
)
dc
.
DrawLine
(
0
,
y_pos
,
self
.
width
,
y_pos
)
gc
.
DrawText
(
unicode
(
int
(
self
.
maxyvalue
-
(
y
*
(
self
.
maxyvalue
/
self
.
ybars
)))
),
1
,
y_pos
-
(
font
.
GetPointSize
()
/
2
))
gc
.
DrawText
(
unicode
(
y
*
spacing
),
1
,
y_pos
-
(
font
.
GetPointSize
()
/
2
))
if
self
.
timer
.
IsRunning
()
==
False
:
font
=
wx
.
Font
(
14
,
wx
.
DEFAULT
,
wx
.
NORMAL
,
wx
.
BOLD
)
...
...
@@ -110,6 +115,33 @@ class Graph(BufferedCanvas):
#gc.DrawLines([[20, 30], [10, 53]])
#dc.SetPen(wx.Pen(wx.Colour(255, 0, 0, 0), 1))
def
_y_pos
(
self
,
temperature
):
"""Converts a temperature, in degrees, to a pixel position"""
#fraction of the screen from the bottom
frac
=
float
(
temperature
-
self
.
minyvalue
)
/
(
self
.
maxyvalue
-
self
.
minyvalue
)
return
int
(
(
1.0
-
frac
)
*
(
self
.
height
-
1
)
)
def
_calculate_spacing
(
self
):
# Allow grids of spacings 1,2.5,5,10,25,50,100,etc
yspan
=
float
(
self
.
maxyvalue
-
self
.
minyvalue
)
log_yspan
=
log10
(
yspan
/
self
.
ybars
)
exponent
=
int
(
floor
(
log_yspan
)
)
#calculate boundary points between allowed spacings
log1_25
=
log10
(
2
)
+
log10
(
1
)
+
log10
(
2.5
)
-
log10
(
1
+
2.5
)
log25_5
=
log10
(
2
)
+
log10
(
2.5
)
+
log10
(
5
)
-
log10
(
2.5
+
5
)
log5_10
=
log10
(
2
)
+
log10
(
5
)
+
log10
(
10
)
-
log10
(
5
+
10
)
if
log_yspan
-
exponent
<
log1_25
:
return
10
**
exponent
elif
log1_25
<=
log_yspan
-
exponent
<
log25_5
:
return
25
*
10
**
(
exponent
-
1
)
elif
log25_5
<=
log_yspan
-
exponent
<
log5_10
:
return
5
*
10
**
exponent
else
:
return
10
**
(
exponent
+
1
)
def
drawtemperature
(
self
,
dc
,
gc
,
temperature_list
,
text
,
text_xoffset
,
r
,
g
,
b
,
a
):
if
self
.
timer
.
IsRunning
()
==
False
:
dc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
128
,
128
,
128
,
128
),
1
))
...
...
@@ -117,17 +149,18 @@ class Graph(BufferedCanvas):
dc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
r
,
g
,
b
,
a
),
1
))
x_add
=
float
(
self
.
width
)
/
self
.
xsteps
x_pos
=
float
(
0.0
)
lastxvalue
=
float
(
0.0
)
x_pos
=
0.0
lastxvalue
=
0.0
lastyvalue
=
temperature_list
[
-
1
]
for
temperature
in
(
temperature_list
):
y_pos
=
int
((
float
(
self
.
height
-
self
.
y_offset
)
/
self
.
maxyvalue
)
*
temperature
)
+
self
.
y_offset
y_pos
=
self
.
_y_pos
(
temperature
)
if
(
x_pos
>
0.0
):
# One need 2 points to draw a line.
dc
.
DrawLine
(
lastxvalue
,
self
.
height
-
self
.
_lastyvalue
,
x_pos
,
self
.
height
-
y_pos
)
dc
.
DrawLine
(
lastxvalue
,
lastyvalue
,
x_pos
,
y_pos
)
lastxvalue
=
x_pos
x_pos
=
float
(
x_pos
)
+
x_add
self
.
_
lastyvalue
=
y_pos
lastyvalue
=
y_pos
if
len
(
text
)
>
0
:
font
=
wx
.
Font
(
8
,
wx
.
DEFAULT
,
wx
.
NORMAL
,
wx
.
BOLD
)
...
...
@@ -137,9 +170,7 @@ class Graph(BufferedCanvas):
else
:
gc
.
SetFont
(
font
,
wx
.
Colour
(
r
,
g
,
b
))
#gc.DrawText(text, self.width - (font.GetPointSize() * ((len(text) * text_xoffset + 1))), self.height - self._lastyvalue - (font.GetPointSize() / 2))
gc
.
DrawText
(
text
,
x_pos
-
x_add
-
(
font
.
GetPointSize
()
*
((
len
(
text
)
*
text_xoffset
+
1
))),
self
.
height
-
self
.
_lastyvalue
-
(
font
.
GetPointSize
()
/
2
))
#gc.DrawText(text, self.width - (font.GetPixelSize().GetWidth() * ((len(text) * text_xoffset + 1) + 1)), self.height - self._lastyvalue - (font.GetPointSize() / 2))
gc
.
DrawText
(
text
,
x_pos
-
x_add
-
(
font
.
GetPointSize
()
*
((
len
(
text
)
*
text_xoffset
+
1
))),
lastyvalue
-
(
font
.
GetPointSize
()
/
2
))
def
drawbedtemp
(
self
,
dc
,
gc
):
...
...
@@ -238,3 +269,110 @@ class Graph(BufferedCanvas):
self
.
drawextruder0temp
(
dc
,
gc
)
self
.
drawextruder1targettemp
(
dc
,
gc
)
self
.
drawextruder1temp
(
dc
,
gc
)
class
_YBounds
(
object
):
"""Small helper class to claculate y bounds dynamically"""
def
__init__
(
self
,
graph
,
minimum_scale
=
5.0
,
buffer
=
0.10
):
"""_YBounds(Graph,float,float)
graph parent object to calculate scales for
minimum_scale minimum range to show on the graph
buffer amount of padding to add above & below the
displayed temperatures. Given as a fraction of the
total range. (Eg .05 to use 90
%
of the range for
temperatures)
"""
self
.
graph
=
graph
self
.
min_scale
=
minimum_scale
self
.
buffer
=
buffer
# Frequency to rescale the graph
self
.
update_freq
=
10
self
.
_last_update
=
self
.
update_freq
#number of updates since last full refresh
def
update
(
self
,
forceUpdate
=
False
):
"""Updates graph.minyvalue and graph.maxyvalue based on current temperatures
"""
self
.
_last_update
+=
1
#TODO Smart update. Only do full calculation every 10s. Otherwise, just look at current graph & expand if necessary
if
forceUpdate
or
self
.
_last_update
>=
self
.
update_freq
:
self
.
graph
.
minyvalue
,
self
.
graph
.
maxyvalue
=
self
.
getBounds
()
self
.
_last_update
=
0
else
:
self
.
graph
.
minyvalue
,
self
.
graph
.
maxyvalue
=
self
.
getBoundsQuick
()
def
getBounds
(
self
):
"""
Calculates the bounds based on the current temperatures
Rules:
* Include the full extruder0 history
* Include the current target temp (but not necessarily old settings)
* Include the extruder1 and/or bed temp if
1) The target temp is >0
2) The history has ever been above 5
* Include at least min_scale
* Include at least buffer above & below the extreme temps
"""
extruder0_min
=
min
(
self
.
graph
.
extruder0temps
)
extruder0_max
=
max
(
self
.
graph
.
extruder0temps
)
extruder0_target
=
self
.
graph
.
extruder0targettemps
[
-
1
]
extruder1_min
=
min
(
self
.
graph
.
extruder1temps
)
extruder1_max
=
max
(
self
.
graph
.
extruder1temps
)
extruder1_target
=
self
.
graph
.
extruder1targettemps
[
-
1
]
bed_min
=
min
(
self
.
graph
.
bedtemps
)
bed_max
=
max
(
self
.
graph
.
bedtemps
)
bed_target
=
self
.
graph
.
bedtargettemps
[
-
1
]
miny
=
min
(
extruder0_min
,
extruder0_target
)
maxy
=
max
(
extruder0_max
,
extruder0_target
)
if
extruder1_target
>
0
or
extruder1_max
>
5
:
#use extruder1
miny
=
min
(
miny
,
extruder1_min
,
extruder1_target
)
maxy
=
max
(
maxy
,
extruder1_max
,
extruder1_target
)
if
bed_target
>
0
or
bed_max
>
5
:
#use HBP
miny
=
min
(
miny
,
bed_min
,
bed_target
)
maxy
=
max
(
maxy
,
bed_max
,
bed_target
)
padding
=
(
maxy
-
miny
)
*
self
.
buffer
/
(
1.0
-
2
*
self
.
buffer
)
miny
-=
padding
maxy
+=
padding
if
maxy
-
miny
<
self
.
min_scale
:
extrapadding
=
(
self
.
min_scale
-
maxy
+
miny
)
/
2.0
miny
-=
extrapadding
maxy
+=
extrapadding
return
(
miny
,
maxy
)
def
getBoundsQuick
(
self
):
# Only look at current temps
extruder0_min
=
self
.
graph
.
extruder0temps
[
-
1
]
extruder0_max
=
self
.
graph
.
extruder0temps
[
-
1
]
extruder0_target
=
self
.
graph
.
extruder0targettemps
[
-
1
]
extruder1_min
=
self
.
graph
.
extruder1temps
[
-
1
]
extruder1_max
=
self
.
graph
.
extruder1temps
[
-
1
]
extruder1_target
=
self
.
graph
.
extruder1targettemps
[
-
1
]
bed_min
=
self
.
graph
.
bedtemps
[
-
1
]
bed_max
=
self
.
graph
.
bedtemps
[
-
1
]
bed_target
=
self
.
graph
.
bedtargettemps
[
-
1
]
miny
=
min
(
extruder0_min
,
extruder0_target
)
maxy
=
max
(
extruder0_max
,
extruder0_target
)
if
extruder1_target
>
0
or
extruder1_max
>
5
:
#use extruder1
miny
=
min
(
miny
,
extruder1_min
,
extruder1_target
)
maxy
=
max
(
maxy
,
extruder1_max
,
extruder1_target
)
if
bed_target
>
0
or
bed_max
>
5
:
#use HBP
miny
=
min
(
miny
,
bed_min
,
bed_target
)
maxy
=
max
(
maxy
,
bed_max
,
bed_target
)
#We have to rescale, so add padding
if
miny
<
self
.
graph
.
minyvalue
:
padding
=
(
self
.
graph
.
maxyvalue
-
miny
)
*
self
.
buffer
/
(
1.0
-
self
.
buffer
)
miny
-=
padding
if
maxy
>
self
.
graph
.
maxyvalue
:
padding
=
(
maxy
-
self
.
graph
.
minyvalue
)
*
self
.
buffer
/
(
1.0
-
self
.
buffer
)
maxy
+=
padding
return
min
(
miny
,
self
.
graph
.
minyvalue
),
max
(
maxy
,
self
.
graph
.
maxyvalue
)
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