mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-19 14:25:27 +00:00
Plot of the Cylinder Pressure over time.
a few code was moved around, a macro that contained the form of x ? : y; had to be rewritten to x ? x : y since c++ doesn't allow ternarys without the middle operator. The color-choosing for the Cylinder Pressure broke on the Qt port - but it's a small issue. I'm painting everyone as 'dark green' now, will fix that later. Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
This commit is contained in:
parent
d120fed211
commit
9554cb5767
4 changed files with 121 additions and 108 deletions
114
profile.c
114
profile.c
|
@ -25,14 +25,6 @@ static struct plot_data *last_pi_entry = NULL;
|
|||
#define cairo_set_line_width_scaled(cr, w) \
|
||||
cairo_set_line_width((cr), (w) * plot_scale);
|
||||
|
||||
|
||||
|
||||
#define SENSOR_PR 0
|
||||
#define INTERPOLATED_PR 1
|
||||
#define SENSOR_PRESSURE(_entry) (_entry)->pressure[SENSOR_PR]
|
||||
#define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR]
|
||||
#define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? : INTERPOLATED_PRESSURE(_entry))
|
||||
|
||||
#if USE_GTK_UI
|
||||
|
||||
/* keep the last used gc around so we can invert the SCALEX calculation in
|
||||
|
@ -518,46 +510,28 @@ static void plot_temperature_text(struct graphics_context *gc, struct plot_info
|
|||
}
|
||||
|
||||
/* gets both the actual start and end pressure as well as the scaling factors */
|
||||
static int get_cylinder_pressure_range(struct graphics_context *gc, struct plot_info *pi)
|
||||
|
||||
#endif /* USE_GTK_UI */
|
||||
|
||||
int get_cylinder_pressure_range(struct graphics_context *gc)
|
||||
{
|
||||
gc->leftx = 0;
|
||||
gc->rightx = get_maxtime(pi);
|
||||
gc->rightx = get_maxtime(&gc->pi);
|
||||
|
||||
if (PP_GRAPHS_ENABLED)
|
||||
gc->bottomy = -pi->maxpressure * 0.75;
|
||||
gc->bottomy = -gc->pi.maxpressure * 0.75;
|
||||
else
|
||||
gc->bottomy = 0;
|
||||
gc->topy = pi->maxpressure * 1.5;
|
||||
if (!pi->maxpressure)
|
||||
gc->topy = gc->pi.maxpressure * 1.5;
|
||||
if (!gc->pi.maxpressure)
|
||||
return FALSE;
|
||||
|
||||
while (pi->endtempcoord <= SCALEY(gc, pi->minpressure - (gc->topy) * 0.1))
|
||||
while (gc->pi.endtempcoord <= SCALEY(gc, gc->pi.minpressure - (gc->topy) * 0.1))
|
||||
gc->bottomy -= gc->topy * 0.1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* set the color for the pressure plot according to temporary sac rate
|
||||
* as compared to avg_sac; the calculation simply maps the delta between
|
||||
* sac and avg_sac to indexes 0 .. (SAC_COLORS - 1) with everything
|
||||
* more than 6000 ml/min below avg_sac mapped to 0 */
|
||||
void set_sac_color(struct graphics_context *gc, int sac, int avg_sac)
|
||||
{
|
||||
int sac_index = 0;
|
||||
int delta = sac - avg_sac + 7000;
|
||||
|
||||
if (!gc->printer) {
|
||||
sac_index = delta / 2000;
|
||||
if (sac_index < 0)
|
||||
sac_index = 0;
|
||||
if (sac_index > SAC_COLORS - 1)
|
||||
sac_index = SAC_COLORS - 1;
|
||||
set_source_rgba(gc, SAC_COLORS_START_IDX + sac_index);
|
||||
} else {
|
||||
set_source_rgba(gc, SAC_DEFAULT);
|
||||
}
|
||||
}
|
||||
#endif /* USE_GTK_UI */
|
||||
|
||||
/* Get local sac-rate (in ml/min) between entry1 and entry2 */
|
||||
int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive)
|
||||
|
@ -590,78 +564,8 @@ int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct div
|
|||
return airuse / atm * 60 / duration;
|
||||
}
|
||||
|
||||
/* calculate the current SAC in ml/min and convert to int */
|
||||
#define GET_LOCAL_SAC(_entry1, _entry2, _dive) \
|
||||
get_local_sac(_entry1, _entry2, _dive)
|
||||
|
||||
#define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */
|
||||
|
||||
#if USE_GTK_UI
|
||||
static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info *pi,
|
||||
struct dive *dive, struct divecomputer *dc)
|
||||
{
|
||||
int i;
|
||||
int last = -1, last_index = -1;
|
||||
int lift_pen = FALSE;
|
||||
int first_plot = TRUE;
|
||||
int sac = 0;
|
||||
struct plot_data *last_entry = NULL;
|
||||
|
||||
if (!get_cylinder_pressure_range(gc, pi))
|
||||
return;
|
||||
|
||||
cairo_set_line_width_scaled(gc->cr, 2);
|
||||
|
||||
for (i = 0; i < pi->nr; i++) {
|
||||
int mbar;
|
||||
struct plot_data *entry = pi->entry + i;
|
||||
|
||||
mbar = GET_PRESSURE(entry);
|
||||
if (entry->cylinderindex != last_index) {
|
||||
lift_pen = TRUE;
|
||||
last_entry = NULL;
|
||||
}
|
||||
if (!mbar) {
|
||||
lift_pen = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (!last_entry) {
|
||||
last = i;
|
||||
last_entry = entry;
|
||||
sac = GET_LOCAL_SAC(entry, pi->entry + i + 1, dive);
|
||||
} else {
|
||||
int j;
|
||||
sac = 0;
|
||||
for (j = last; j < i; j++)
|
||||
sac += GET_LOCAL_SAC(pi->entry + j, pi->entry + j + 1, dive);
|
||||
sac /= (i - last);
|
||||
if (entry->sec - last_entry->sec >= SAC_WINDOW) {
|
||||
last++;
|
||||
last_entry = pi->entry + last;
|
||||
}
|
||||
}
|
||||
set_sac_color(gc, sac, dive->sac);
|
||||
if (lift_pen) {
|
||||
if (!first_plot && entry->cylinderindex == last_index) {
|
||||
/* if we have a previous event from the same tank,
|
||||
* draw at least a short line */
|
||||
int prev_pr;
|
||||
prev_pr = GET_PRESSURE(entry - 1);
|
||||
move_to(gc, (entry-1)->sec, prev_pr);
|
||||
line_to(gc, entry->sec, mbar);
|
||||
} else {
|
||||
first_plot = FALSE;
|
||||
move_to(gc, entry->sec, mbar);
|
||||
}
|
||||
lift_pen = FALSE;
|
||||
} else {
|
||||
line_to(gc, entry->sec, mbar);
|
||||
}
|
||||
cairo_stroke(gc->cr);
|
||||
move_to(gc, entry->sec, mbar);
|
||||
last_index = entry->cylinderindex;
|
||||
}
|
||||
}
|
||||
|
||||
static void plot_pressure_value(struct graphics_context *gc, int mbar, int sec,
|
||||
int xalign, int yalign)
|
||||
|
|
12
profile.h
12
profile.h
|
@ -39,6 +39,7 @@ struct plot_data {
|
|||
void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc);
|
||||
struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc);
|
||||
int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi);
|
||||
int get_cylinder_pressure_range(struct graphics_context *gc);
|
||||
|
||||
struct ev_select {
|
||||
char *ev_name;
|
||||
|
@ -60,6 +61,9 @@ int get_maxtime(struct plot_info *pi);
|
|||
* partial pressure graphs */
|
||||
int get_maxdepth(struct plot_info *pi);
|
||||
|
||||
int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive);
|
||||
|
||||
|
||||
#define ALIGN_LEFT 1
|
||||
#define ALIGN_RIGHT 2
|
||||
#define INVISIBLE 4
|
||||
|
@ -92,6 +96,14 @@ int get_maxdepth(struct plot_info *pi);
|
|||
#define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy)
|
||||
#define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y)
|
||||
|
||||
#define SENSOR_PR 0
|
||||
#define INTERPOLATED_PR 1
|
||||
#define SENSOR_PRESSURE(_entry) (_entry)->pressure[SENSOR_PR]
|
||||
#define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR]
|
||||
#define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? SENSOR_PRESSURE(_entry) : INTERPOLATED_PRESSURE(_entry))
|
||||
|
||||
#define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -238,10 +238,10 @@ void ProfileGraphicsView::plot(struct dive *dive)
|
|||
|
||||
/* Temperature profile */
|
||||
plot_temperature_profile();
|
||||
#if 0
|
||||
/* Cylinder pressure plot */
|
||||
plot_cylinder_pressure(gc, pi, dive, dc);
|
||||
|
||||
/* Cylinder pressure plot */
|
||||
plot_cylinder_pressure(dive, dc);
|
||||
#if 0
|
||||
/* Text on top of all graphs.. */
|
||||
plot_temperature_text(gc, pi);
|
||||
plot_depth_text(gc, pi);
|
||||
|
@ -288,6 +288,100 @@ void ProfileGraphicsView::plot(struct dive *dive)
|
|||
#endif
|
||||
}
|
||||
|
||||
void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc)
|
||||
{
|
||||
int i;
|
||||
int last = -1, last_index = -1;
|
||||
int lift_pen = FALSE;
|
||||
int first_plot = TRUE;
|
||||
int sac = 0;
|
||||
struct plot_data *last_entry = NULL;
|
||||
|
||||
if (!get_cylinder_pressure_range(&gc))
|
||||
return;
|
||||
|
||||
QPointF from, to;
|
||||
for (i = 0; i < gc.pi.nr; i++) {
|
||||
int mbar;
|
||||
struct plot_data *entry = gc.pi.entry + i;
|
||||
|
||||
mbar = GET_PRESSURE(entry);
|
||||
if (entry->cylinderindex != last_index) {
|
||||
lift_pen = TRUE;
|
||||
last_entry = NULL;
|
||||
}
|
||||
if (!mbar) {
|
||||
lift_pen = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (!last_entry) {
|
||||
last = i;
|
||||
last_entry = entry;
|
||||
sac = get_local_sac(entry, gc.pi.entry + i + 1, dive);
|
||||
} else {
|
||||
int j;
|
||||
sac = 0;
|
||||
for (j = last; j < i; j++)
|
||||
sac += get_local_sac(gc.pi.entry + j, gc.pi.entry + j + 1, dive);
|
||||
sac /= (i - last);
|
||||
if (entry->sec - last_entry->sec >= SAC_WINDOW) {
|
||||
last++;
|
||||
last_entry = gc.pi.entry + last;
|
||||
}
|
||||
}
|
||||
|
||||
// QColor c = get_sac_color(sac, dive->sac); Buggy TODO: fix.
|
||||
QColor c = QColor(Qt::darkGreen);
|
||||
|
||||
if (lift_pen) {
|
||||
if (!first_plot && entry->cylinderindex == last_index) {
|
||||
/* if we have a previous event from the same tank,
|
||||
* draw at least a short line */
|
||||
int prev_pr;
|
||||
prev_pr = GET_PRESSURE(entry - 1);
|
||||
|
||||
QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC((entry-1)->sec, prev_pr), SCALEGC(entry->sec, mbar));
|
||||
item->setPen(QPen(c, 2));
|
||||
scene()->addItem(item);
|
||||
} else {
|
||||
first_plot = FALSE;
|
||||
from = QPointF(SCALEGC(entry->sec, mbar));
|
||||
}
|
||||
lift_pen = FALSE;
|
||||
} else {
|
||||
to = QPointF(SCALEGC(entry->sec, mbar));
|
||||
QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y());
|
||||
item->setPen(QPen(c, 2));
|
||||
scene()->addItem(item);
|
||||
}
|
||||
|
||||
|
||||
from = QPointF(SCALEGC(entry->sec, mbar));
|
||||
last_index = entry->cylinderindex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* set the color for the pressure plot according to temporary sac rate
|
||||
* as compared to avg_sac; the calculation simply maps the delta between
|
||||
* sac and avg_sac to indexes 0 .. (SAC_COLORS - 1) with everything
|
||||
* more than 6000 ml/min below avg_sac mapped to 0 */
|
||||
QColor ProfileGraphicsView::get_sac_color(int sac, int avg_sac)
|
||||
{
|
||||
int sac_index = 0;
|
||||
int delta = sac - avg_sac + 7000;
|
||||
|
||||
if (!gc.printer) {
|
||||
sac_index = delta / 2000;
|
||||
if (sac_index < 0)
|
||||
sac_index = 0;
|
||||
if (sac_index > SAC_COLORS - 1)
|
||||
sac_index = SAC_COLORS - 1;
|
||||
return profile_color[ (color_indice_t) (SAC_COLORS_START_IDX + sac_index)].first();
|
||||
}
|
||||
return profile_color[SAC_DEFAULT].first();
|
||||
}
|
||||
|
||||
void ProfileGraphicsView::plot_events(struct divecomputer *dc)
|
||||
{
|
||||
struct event *event = dc->events;
|
||||
|
|
|
@ -96,6 +96,9 @@ private:
|
|||
void plot_events(struct divecomputer *dc);
|
||||
void plot_one_event(struct event *event);
|
||||
void plot_temperature_profile();
|
||||
void plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc);
|
||||
|
||||
QColor get_sac_color(int sac, int avg_sac);
|
||||
|
||||
QPen defaultPen;
|
||||
QBrush defaultBrush;
|
||||
|
|
Loading…
Add table
Reference in a new issue