libsysprof-gtk: allow filling a line chart

This commit is contained in:
Christian Hergert
2023-06-20 16:55:34 -07:00
parent 122c4906b8
commit f71fbd9a31
3 changed files with 70 additions and 2 deletions

View File

@ -30,6 +30,7 @@ struct _SysprofLineLayer
GdkRGBA color; GdkRGBA color;
guint use_curves : 1; guint use_curves : 1;
guint flip_y : 1; guint flip_y : 1;
guint fill : 1;
}; };
G_DEFINE_FINAL_TYPE (SysprofLineLayer, sysprof_line_layer, SYSPROF_TYPE_CHART_LAYER) G_DEFINE_FINAL_TYPE (SysprofLineLayer, sysprof_line_layer, SYSPROF_TYPE_CHART_LAYER)
@ -37,6 +38,7 @@ G_DEFINE_FINAL_TYPE (SysprofLineLayer, sysprof_line_layer, SYSPROF_TYPE_CHART_LA
enum { enum {
PROP_0, PROP_0,
PROP_COLOR, PROP_COLOR,
PROP_FILL,
PROP_FLIP_Y, PROP_FLIP_Y,
PROP_SERIES, PROP_SERIES,
PROP_USE_CURVES, PROP_USE_CURVES,
@ -78,7 +80,6 @@ sysprof_line_layer_snapshot (GtkWidget *widget,
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height)); cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
gdk_cairo_set_source_rgba (cr, &self->color);
cairo_set_line_width (cr, 1./width); cairo_set_line_width (cr, 1./width);
if (!self->flip_y) if (!self->flip_y)
@ -89,7 +90,16 @@ sysprof_line_layer_snapshot (GtkWidget *widget,
last_x = values->x; last_x = values->x;
last_y = values->y; last_y = values->y;
cairo_move_to (cr, last_x, last_y);
if (self->fill)
{
cairo_move_to (cr, last_x, 0);
cairo_line_to (cr, last_x, last_y);
}
else
{
cairo_move_to (cr, last_x, last_y);
}
if (self->use_curves) if (self->use_curves)
{ {
@ -118,10 +128,25 @@ sysprof_line_layer_snapshot (GtkWidget *widget,
const SysprofXYSeriesValue *v = &values[i]; const SysprofXYSeriesValue *v = &values[i];
cairo_line_to (cr, v->x, v->y); cairo_line_to (cr, v->x, v->y);
last_x = v->x;
last_y = v->y;
} }
} }
if (self->fill)
{
GdkRGBA fill_color = self->color;
cairo_line_to (cr, last_x, 0);
fill_color.alpha *= .5;
cairo_fill_preserve (cr);
}
gdk_cairo_set_source_rgba (cr, &self->color);
cairo_stroke (cr); cairo_stroke (cr);
cairo_destroy (cr); cairo_destroy (cr);
} }
@ -149,6 +174,10 @@ sysprof_line_layer_get_property (GObject *object,
g_value_set_boxed (value, sysprof_line_layer_get_color (self)); g_value_set_boxed (value, sysprof_line_layer_get_color (self));
break; break;
case PROP_FILL:
g_value_set_boolean (value, sysprof_line_layer_get_fill (self));
break;
case PROP_FLIP_Y: case PROP_FLIP_Y:
g_value_set_boolean (value, sysprof_line_layer_get_flip_y (self)); g_value_set_boolean (value, sysprof_line_layer_get_flip_y (self));
break; break;
@ -180,6 +209,10 @@ sysprof_line_layer_set_property (GObject *object,
sysprof_line_layer_set_color (self, g_value_get_boxed (value)); sysprof_line_layer_set_color (self, g_value_get_boxed (value));
break; break;
case PROP_FILL:
sysprof_line_layer_set_fill (self, g_value_get_boolean (value));
break;
case PROP_FLIP_Y: case PROP_FLIP_Y:
sysprof_line_layer_set_flip_y (self, g_value_get_boolean (value)); sysprof_line_layer_set_flip_y (self, g_value_get_boolean (value));
break; break;
@ -214,6 +247,11 @@ sysprof_line_layer_class_init (SysprofLineLayerClass *klass)
GDK_TYPE_RGBA, GDK_TYPE_RGBA,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
properties [PROP_FILL] =
g_param_spec_boolean ("fill", NULL, NULL,
FALSE,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
properties [PROP_FLIP_Y] = properties [PROP_FLIP_Y] =
g_param_spec_boolean ("flip-y", NULL, NULL, g_param_spec_boolean ("flip-y", NULL, NULL,
FALSE, FALSE,
@ -297,6 +335,30 @@ sysprof_line_layer_set_series (SysprofLineLayer *self,
gtk_widget_queue_draw (GTK_WIDGET (self)); gtk_widget_queue_draw (GTK_WIDGET (self));
} }
gboolean
sysprof_line_layer_get_fill (SysprofLineLayer *self)
{
g_return_val_if_fail (SYSPROF_IS_LINE_LAYER (self), FALSE);
return self->fill;
}
void
sysprof_line_layer_set_fill (SysprofLineLayer *self,
gboolean fill)
{
g_return_if_fail (SYSPROF_IS_LINE_LAYER (self));
fill = !!fill;
if (fill != self->fill)
{
self->fill = fill;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILL]);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
gboolean gboolean
sysprof_line_layer_get_flip_y (SysprofLineLayer *self) sysprof_line_layer_get_flip_y (SysprofLineLayer *self)
{ {

View File

@ -45,6 +45,11 @@ SYSPROF_AVAILABLE_IN_ALL
void sysprof_line_layer_set_series (SysprofLineLayer *self, void sysprof_line_layer_set_series (SysprofLineLayer *self,
SysprofXYSeries *series); SysprofXYSeries *series);
SYSPROF_AVAILABLE_IN_ALL SYSPROF_AVAILABLE_IN_ALL
gboolean sysprof_line_layer_get_fill (SysprofLineLayer *self);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_line_layer_set_fill (SysprofLineLayer *self,
gboolean fill);
SYSPROF_AVAILABLE_IN_ALL
gboolean sysprof_line_layer_get_flip_y (SysprofLineLayer *self); gboolean sysprof_line_layer_get_flip_y (SysprofLineLayer *self);
SYSPROF_AVAILABLE_IN_ALL SYSPROF_AVAILABLE_IN_ALL
void sysprof_line_layer_set_flip_y (SysprofLineLayer *self, void sysprof_line_layer_set_flip_y (SysprofLineLayer *self,

View File

@ -185,6 +185,7 @@ main (int argc,
"top", g_object_new (SYSPROF_TYPE_LINE_LAYER, "top", g_object_new (SYSPROF_TYPE_LINE_LAYER,
"series", samples_series, "series", samples_series,
"title", "Stack Depth as Line", "title", "Stack Depth as Line",
"fill", TRUE,
NULL), NULL),
"bottom", g_object_new (SYSPROF_TYPE_LINE_LAYER, "bottom", g_object_new (SYSPROF_TYPE_LINE_LAYER,
"series", samples_series, "series", samples_series,