[gnome-disk-utility/ata-smart-ui-rework] Add dynamic y axis markers



commit e9fd032f4b2c6d471e777639102341b1072f9310
Author: David Zeuthen <davidz redhat com>
Date:   Sun Jul 12 15:02:44 2009 -0400

    Add dynamic y axis markers

 src/gdu-gtk/gdu-ata-smart-dialog.c |   98 +++++++-------------------------
 src/gdu-gtk/gdu-curve.c            |    2 +-
 src/gdu-gtk/gdu-graph.c            |  110 ++++++++++++++++++++++++++++++++++++
 src/gdu-gtk/gdu-gtk-enums.h        |   15 ++++-
 4 files changed, 145 insertions(+), 80 deletions(-)
---
diff --git a/src/gdu-gtk/gdu-ata-smart-dialog.c b/src/gdu-gtk/gdu-ata-smart-dialog.c
index 853618c..809c536 100644
--- a/src/gdu-gtk/gdu-ata-smart-dialog.c
+++ b/src/gdu-gtk/gdu-ata-smart-dialog.c
@@ -170,88 +170,16 @@ selection_changed (GtkTreeSelection *tree_selection,
         GArray *threshold_samples;
         GArray *raw_samples;
         GArray *band_samples;
+        GduCurveUnit raw_unit;
         GList *l;
         guint64 now;
+
         cur_samples = g_array_new (FALSE, FALSE, sizeof (GduSample));
         worst_samples = g_array_new (FALSE, FALSE, sizeof (GduSample));
         threshold_samples = g_array_new (FALSE, FALSE, sizeof (GduSample));
         raw_samples = g_array_new (FALSE, FALSE, sizeof (GduSample));
         band_samples = g_array_new (FALSE, FALSE, sizeof (GduSample));
-
-        guint64 raw_min;
-        guint64 raw_max;
-        GduAtaSmartAttributeUnit raw_unit;
-        raw_min = G_MAXUINT64;
-        raw_max = 0;
-        for (l = dialog->priv->historical_data; l != NULL; l = l->next) {
-                GduAtaSmartHistoricalData *data = GDU_ATA_SMART_HISTORICAL_DATA (l->data);
-                GduAtaSmartAttribute *attr;
-
-                attr = gdu_ata_smart_historical_data_get_attribute (data, attr_name);
-                if (attr != NULL) {
-                        guint64 raw;
-
-                        raw = gdu_ata_smart_attribute_get_pretty_value (attr);
-                        raw_unit = gdu_ata_smart_attribute_get_pretty_unit (attr);
-                        if (raw < raw_min)
-                                raw_min = raw;
-                        if (raw > raw_max)
-                                raw_max = raw;
-                        g_object_unref (attr);
-                }
-        }
-
-        guint64 time_factor;
-        switch (raw_unit) {
-        case GDU_ATA_SMART_ATTRIBUTE_UNIT_MSECONDS:
-                if (raw_min > 1000 * 60 * 60 * 24) {
-                        time_factor = 1000 * 60 * 60 * 24;
-                } else if (raw_min > 1000 * 60 * 60) {
-                        time_factor = 1000 * 60 * 60;
-                } else if (raw_min > 1000 * 60) {
-                        time_factor = 1000 * 60;
-                } else if (raw_min > 1000) {
-                        time_factor = 1000;
-                } else {
-                        time_factor = 1;
-                }
-
-                if (raw_max - raw_min < 5 * time_factor) {
-                        raw_min -= (raw_min % time_factor);
-                        raw_max = raw_min + 5 * time_factor;
-                }
-                break;
-        case GDU_ATA_SMART_ATTRIBUTE_UNIT_MKELVIN:
-                if (raw_max - raw_min < 5000) {
-                        raw_min -= (raw_min % 1000);
-                        raw_max = raw_min + 5000;
-                }
-                break;
-        case GDU_ATA_SMART_ATTRIBUTE_UNIT_SECTORS:
-        case GDU_ATA_SMART_ATTRIBUTE_UNIT_NONE:
-        case GDU_ATA_SMART_ATTRIBUTE_UNIT_UNKNOWN:
-                if (raw_min - raw_max < 5) {
-                        raw_max = raw_min + 5;
-                }
-                break;
-        }
-
-#if 0
-        gchar **y_axis_left;
-        y_axis_left = g_new0 (gchar *, 6);
-        for (n = 0; n < 5; n++) {
-                guint64 raw_marker_value;
-                gchar *s;
-
-                raw_marker_value = raw_min + n * ((gdouble) (raw_max - raw_min)) / (5 - 1);
-
-                s = pretty_to_string (raw_marker_value, raw_unit, FALSE);
-                y_axis_left[n] = s;
-        }
-        y_axis_left[n] = NULL;
-        gdu_graph_set_y_markers_left (GDU_GRAPH (dialog->priv->graph), (const gchar* const *) y_axis_left);
-        g_strfreev (y_axis_left);
-#endif
+        raw_unit = GDU_CURVE_UNIT_INTEGER;
 
         guint64 tolerance;
         guint64 timespan;
@@ -317,7 +245,24 @@ selection_changed (GtkTreeSelection *tree_selection,
                                 sample.value = threshold / 255.0f;
                                 g_array_append_val (threshold_samples, sample);
 
-                                sample.value = ((gdouble) (raw - raw_min)) / ((gdouble) (raw_max - raw_min));
+                                switch (gdu_ata_smart_attribute_get_pretty_unit (attr)) {
+                                case GDU_ATA_SMART_ATTRIBUTE_UNIT_MSECONDS:
+                                        sample.value = ((gdouble) raw) / 1000.0;
+                                        raw_unit = GDU_CURVE_UNIT_TIME_SECONDS;
+                                        break;
+                                case GDU_ATA_SMART_ATTRIBUTE_UNIT_MKELVIN:
+                                        sample.value = ((gdouble) raw) / 1000.0;
+                                        raw_unit = GDU_CURVE_UNIT_TEMPERATURE_KELVIN;
+                                        break;
+                                default:
+                                case GDU_ATA_SMART_ATTRIBUTE_UNIT_UNKNOWN:
+                                case GDU_ATA_SMART_ATTRIBUTE_UNIT_NONE:
+                                case GDU_ATA_SMART_ATTRIBUTE_UNIT_SECTORS:
+                                        sample.value = (gdouble) raw;
+                                        raw_unit = GDU_CURVE_UNIT_INTEGER;
+                                        break;
+                                }
+
                                 g_array_append_val (raw_samples, sample);
 
                                 g_object_unref (attr);
@@ -420,6 +365,7 @@ selection_changed (GtkTreeSelection *tree_selection,
         gdu_curve_set_legend (c, _("Raw")); /* TODO: units? */
         gdu_curve_set_z_order (c, z_order++);
         gdu_curve_set_samples (c, raw_samples);
+        gdu_curve_set_unit (c, raw_unit);
         gdu_curve_set_color (c, &raw_color);
         gdu_curve_set_fill_color (c, &raw_fill_color);
         gdu_curve_set_width (c, 2.0);
diff --git a/src/gdu-gtk/gdu-curve.c b/src/gdu-gtk/gdu-curve.c
index 545c789..048c734 100644
--- a/src/gdu-gtk/gdu-curve.c
+++ b/src/gdu-gtk/gdu-curve.c
@@ -211,7 +211,7 @@ gdu_curve_class_init (GduCurveClass *klass)
                                                             _("Unit"),
                                                             _("The unit used for the curve"),
                                                             GDU_TYPE_CURVE_UNIT,
-                                                            GDU_CURVE_UNIT_NUMBER,
+                                                            GDU_CURVE_UNIT_FLOATING,
                                                             G_PARAM_READABLE |
                                                             G_PARAM_WRITABLE |
                                                             G_PARAM_CONSTRUCT));
diff --git a/src/gdu-gtk/gdu-graph.c b/src/gdu-gtk/gdu-graph.c
index 3a16097..e877ddf 100644
--- a/src/gdu-gtk/gdu-graph.c
+++ b/src/gdu-gtk/gdu-graph.c
@@ -19,6 +19,8 @@
  * 02111-1307, USA.
  */
 
+#define _GNU_SOURCE
+
 #include <config.h>
 #include <glib/gi18n.h>
 #include <string.h>
@@ -885,6 +887,7 @@ draw_curves (cairo_t *cr,
                 GduColor *fill_color;
                 gdouble width;
                 GduCurveFlags flags;
+                GduCurveUnit unit;
                 GArray *samples;
                 guint m;
                 gdouble sample_value_min;
@@ -896,6 +899,7 @@ draw_curves (cairo_t *cr,
                         fill_color = color;
                 width = gdu_curve_get_width (c);
                 flags = gdu_curve_get_flags (c);
+                unit = gdu_curve_get_unit (c);
                 samples = gdu_curve_get_samples (c);
 
                 /* if normalization is requested, find min/max for sample values in curve on window */
@@ -934,6 +938,112 @@ draw_curves (cairo_t *cr,
                         sample_value_max = 1.0;
                 }
 
+                if (flags & GDU_CURVE_FLAGS_AXIS_MARKERS_LEFT) {
+                        gdouble sample_value_diff;
+                        gdouble step_size;
+                        gdouble step;
+                        gdouble step_end;
+
+                        //g_debug ("interval %f -> %f", sample_value_min, sample_value_max);
+
+                        sample_value_diff = sample_value_max - sample_value_min;
+                        //g_debug ("diff      = %f",        sample_value_diff);
+
+                        /* want at most fifteen axis markers bars (rounding means we'll get 1-10 bars) */
+                        step_size = ceil (sample_value_diff) / 10;
+                        //g_debug ("step_size = %f", step_size);
+
+                        /* round step_size to be a power of ten */
+                        step_size = pow10 (ceil (log10 (step_size)));
+                        //g_debug ("step_size (rounded) = %f", step_size);
+
+                        gdouble num_samples_after_adjust = sample_value_diff / step_size;
+                        //g_debug ("num_samples_after_adjust = %f", num_samples_after_adjust);
+
+                        if (num_samples_after_adjust < 2.0)
+                                step_size /= 2.0;
+
+                        //g_debug ("step_size (after adjust) = %f", step_size);
+
+
+                        step = sample_value_min - fmod (sample_value_min, step_size);
+
+                        step_end = sample_value_max - fmod (sample_value_max, step_size) + step_size;
+
+                        //g_debug ("step      = %f",        step);
+                        //g_debug ("step_end  = %f",        step_end);
+
+                        for ( ;step < step_end; step += step_size) {
+                                gdouble step_normalized;
+                                gchar buf[512];
+                                cairo_text_extents_t te;
+                                gint precision;
+
+                                step_normalized = (step - sample_value_min) /
+                                                  (sample_value_max - sample_value_min);
+
+                                y = ceil (gy + (gh - timebar_height) * (1.0f - step_normalized)) + 0.5;
+
+                                //g_debug ("axis line at %f -> %f", step, y);
+
+                                cairo_new_path (cr);
+                                cairo_move_to (cr, gx, y);
+                                cairo_line_to (cr, gx + gw, y);
+                                cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.75);
+                                cairo_set_line_width (cr, 1.0);
+                                cairo_set_dash (cr, NULL, 0, 0.0);
+                                cairo_stroke (cr);
+
+                                switch (unit) {
+                                case GDU_CURVE_UNIT_FLOATING:
+                                        g_snprintf (buf, sizeof buf, "%f", step);
+                                        break;
+                                case GDU_CURVE_UNIT_INTEGER:
+                                        g_snprintf (buf, sizeof buf, "%.0f", step);
+                                        break;
+                                case GDU_CURVE_UNIT_TIME_SECONDS:
+                                        precision = 0;
+                                        if (step > 60*60*24) {
+                                                if (step_size < 60*60*24)
+                                                        precision = 2;
+                                                g_snprintf (buf, sizeof buf, _("%.*f d"), precision, step / 60/60/24);
+                                        } else if (step > 60*60) {
+                                                if (step_size < 60*60)
+                                                        precision = 2;
+                                                g_snprintf (buf, sizeof buf, _("%.*f h"), precision, step / 60/60);
+                                        } else if (step > 60) {
+                                                if (step_size < 60)
+                                                        precision = 2;
+                                                g_snprintf (buf, sizeof buf, _("%.*f m"), precision, step / 60);
+                                        } else if (step > 1) {
+                                                if (step_size < 1)
+                                                        precision = 2;
+                                                g_snprintf (buf, sizeof buf, _("%.*f s"), precision, step);
+                                        } else {
+                                                g_snprintf (buf, sizeof buf, _("%.0f msec"), step * 1000);
+                                        }
+                                        break;
+                                case GDU_CURVE_UNIT_TEMPERATURE_KELVIN:
+                                        g_snprintf (buf, sizeof buf, _("%.0f\302\260 C"), step - 273.15);
+                                        break;
+                                }
+                                //g_debug ("buf = `%s'", buf);
+
+                                cairo_select_font_face (cr, "sans",
+                                                        CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+                                cairo_set_font_size (cr, 8.0);
+                                cairo_text_extents (cr, buf, &te);
+
+                                y = ceil (gy + te.y_bearing/2 + (gh - timebar_height) * (1.0f - step_normalized)) + 0.5;
+
+                                cairo_move_to (cr,
+                                               gx + 4,
+                                               y);
+                                cairo_set_source_rgba (cr, 0, 0, 0, 1.0);
+                                cairo_show_text (cr, buf);
+                        }
+                }
+
                 /* draw the curve */
                 m = 0;
                 while (m < samples->len) {
diff --git a/src/gdu-gtk/gdu-gtk-enums.h b/src/gdu-gtk/gdu-gtk-enums.h
index c9b5ad5..3b7dfad 100644
--- a/src/gdu-gtk/gdu-gtk-enums.h
+++ b/src/gdu-gtk/gdu-gtk-enums.h
@@ -37,10 +37,19 @@ typedef enum {
         GDU_CURVE_FLAGS_NORMALIZE           = (1 << 4),
 } GduCurveFlags;
 
+/**
+ * GduCurveUnit:
+ * @GDU_CURVE_UNIT_FLOATING: Value is a floating point number.
+ * @GDU_CURVE_UNIT_INTEGER: Value is an integer number, such as a count of some sort.
+ * @GDU_CURVE_UNIT_TIME_SECONDS: Value is a measure of time, in seconds.
+ * @GDU_CURVE_UNIT_TEMPERATURE_KELVIN: Value is a measure of temperature, in degrees Kelvin.
+ *
+ */
 typedef enum {
-        GDU_CURVE_UNIT_NUMBER      = 0,
-        GDU_CURVE_UNIT_TIME        = 1,
-        GDU_CURVE_UNIT_TEMPERATURE = 2
+        GDU_CURVE_UNIT_FLOATING            = 0,
+        GDU_CURVE_UNIT_INTEGER             = 1,
+        GDU_CURVE_UNIT_TIME_SECONDS        = 2,
+        GDU_CURVE_UNIT_TEMPERATURE_KELVIN  = 3
 } GduCurveUnit;
 
 #endif /* GDU_GTK_ENUMS_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]