基于 GTK 的图?

发布于 2024-08-28 20:32:23 字数 51 浏览 7 评论 0原文

我希望能够使用 GTK+ 制作折线图,但我不确定如何实现这一点。有人有任何提示或技巧吗?

I want to be able to make a line graph using GTK+ but I'm unsure how to approach this. Has anyone got any hints or tips?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱她像谁 2024-09-04 20:32:23

编辑:

以下是该程序的 GTK+ 2 和 GTK+ 3 版本:

原始答案:

这是 GTK2应用程序使用 cairo 绘制一个简单的数学函数:

#include <gtk/gtk.h>
#include <math.h>
#include <cairo.h>

#define WIDTH   640
#define HEIGHT  480

#define ZOOM_X  100.0
#define ZOOM_Y  100.0


gfloat f (gfloat x)
{
    return 0.03 * pow (x, 3);
}

static gboolean
on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
    cairo_t *cr = gdk_cairo_create (widget->window);
    GdkRectangle da;            /* GtkDrawingArea size */
    gdouble dx = 5.0, dy = 5.0; /* Pixels between each point */
    gdouble i, clip_x1 = 0.0, clip_y1 = 0.0, clip_x2 = 0.0, clip_y2 = 0.0;
    gint unused = 0;

    /* Define a clipping zone to improve performance */
    cairo_rectangle (cr, 
            event->area.x, 
            event->area.y, 
            event->area.width, 
            event->area.height);
    cairo_clip (cr);

    /* Determine GtkDrawingArea dimensions */
    gdk_window_get_geometry (widget->window, 
            &da.x, 
            &da.y, 
            &da.width, 
            &da.height, 
            &unused);

    /* Draw on a black background */
    cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
    cairo_paint (cr);

    /* Change the transformation matrix */
    cairo_translate (cr, da.width / 2, da.height / 2);
    cairo_scale (cr, ZOOM_X, -ZOOM_Y);  

    /* Determine the data points to calculate (ie. those in the clipping zone */
    cairo_device_to_user_distance (cr, &dx, &dy);
    cairo_clip_extents (cr, &clip_x1, &clip_y1, &clip_x2, &clip_y2);
    cairo_set_line_width (cr, dx);

    /* Draws x and y axis */
    cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
    cairo_move_to (cr, clip_x1, 0.0);
    cairo_line_to (cr, clip_x2, 0.0);
    cairo_move_to (cr, 0.0, clip_y1);
    cairo_line_to (cr, 0.0, clip_y2);
    cairo_stroke (cr);

    /* Link each data point */
    for (i = clip_x1; i < clip_x2; i += dx)
        cairo_line_to (cr, i, f (i));

    /* Draw the curve */
    cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
    cairo_stroke (cr);

    cairo_destroy (cr);
    return FALSE;
}


int
main (int argc, char **argv)
{
    GtkWidget *window;
    GtkWidget *da;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
    gtk_window_set_title (GTK_WINDOW (window), "Graph drawing");
    g_signal_connect (G_OBJECT (window), "destroy", gtk_main_quit, NULL);

    da = gtk_drawing_area_new ();
    gtk_container_add (GTK_CONTAINER (window), da);

    g_signal_connect (G_OBJECT (da), 
            "expose-event", 
            G_CALLBACK (on_expose_event), 
            NULL);

    gtk_widget_show_all (window);
    gtk_main ();

    return 0;
}

Edit:

Here are GTK+ 2 and GTK+ 3 versions of that program:

Original answer:

Here's a GTK2 application using cairo to draw a simple math function:

#include <gtk/gtk.h>
#include <math.h>
#include <cairo.h>

#define WIDTH   640
#define HEIGHT  480

#define ZOOM_X  100.0
#define ZOOM_Y  100.0


gfloat f (gfloat x)
{
    return 0.03 * pow (x, 3);
}

static gboolean
on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
    cairo_t *cr = gdk_cairo_create (widget->window);
    GdkRectangle da;            /* GtkDrawingArea size */
    gdouble dx = 5.0, dy = 5.0; /* Pixels between each point */
    gdouble i, clip_x1 = 0.0, clip_y1 = 0.0, clip_x2 = 0.0, clip_y2 = 0.0;
    gint unused = 0;

    /* Define a clipping zone to improve performance */
    cairo_rectangle (cr, 
            event->area.x, 
            event->area.y, 
            event->area.width, 
            event->area.height);
    cairo_clip (cr);

    /* Determine GtkDrawingArea dimensions */
    gdk_window_get_geometry (widget->window, 
            &da.x, 
            &da.y, 
            &da.width, 
            &da.height, 
            &unused);

    /* Draw on a black background */
    cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
    cairo_paint (cr);

    /* Change the transformation matrix */
    cairo_translate (cr, da.width / 2, da.height / 2);
    cairo_scale (cr, ZOOM_X, -ZOOM_Y);  

    /* Determine the data points to calculate (ie. those in the clipping zone */
    cairo_device_to_user_distance (cr, &dx, &dy);
    cairo_clip_extents (cr, &clip_x1, &clip_y1, &clip_x2, &clip_y2);
    cairo_set_line_width (cr, dx);

    /* Draws x and y axis */
    cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
    cairo_move_to (cr, clip_x1, 0.0);
    cairo_line_to (cr, clip_x2, 0.0);
    cairo_move_to (cr, 0.0, clip_y1);
    cairo_line_to (cr, 0.0, clip_y2);
    cairo_stroke (cr);

    /* Link each data point */
    for (i = clip_x1; i < clip_x2; i += dx)
        cairo_line_to (cr, i, f (i));

    /* Draw the curve */
    cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
    cairo_stroke (cr);

    cairo_destroy (cr);
    return FALSE;
}


int
main (int argc, char **argv)
{
    GtkWidget *window;
    GtkWidget *da;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
    gtk_window_set_title (GTK_WINDOW (window), "Graph drawing");
    g_signal_connect (G_OBJECT (window), "destroy", gtk_main_quit, NULL);

    da = gtk_drawing_area_new ();
    gtk_container_add (GTK_CONTAINER (window), da);

    g_signal_connect (G_OBJECT (da), 
            "expose-event", 
            G_CALLBACK (on_expose_event), 
            NULL);

    gtk_widget_show_all (window);
    gtk_main ();

    return 0;
}
爱给你人给你 2024-09-04 20:32:23

我只是想为这个常见请求添加更多替代方案。

  1. libgoffice
    这是 GnumericAbiWord 使用的库,因此它得到积极维护并且相当稳定:是当前可用的最明智的替代方案之一。不幸的是,没有官方主页并且缺乏初学者文档。
  2. GtkDatabox
    最近更换了维护者,所以未来存在一些不确定性。它曾经是在线图中渲染大量数据的一个很好的解决方案。
  3. GtkExtra2
    这是 GTK+ 中绘制图表的事实上的旧标准。跳转到 GTK+2 似乎对这个项目来说是致命的。
  4. GTK+ 仪器小部件GLineGraph
    有点斯巴达式的风格,但适合简单的事情。

除此之外,许多项目在内部实施某种 GTK+ 图表。除了尚未引用的 Gnuplot 之外,还有 Gwyddiongretl。我很确定我错过了很多其他人。

总之,GTK+ 世界中的图表既没有普遍共识,也没有事实上的标准……

I just want to add some more alternatives to this common request.

  1. libgoffice
    This is the library used by Gnumeric and AbiWord, so it is actively maintained and fairly stable: one of the sanest alternative currently available. Unfortunately, there is no official home page and it lacks beginners documentation.
  2. GtkDatabox
    It recently changed the maintainer, so there is some uncertainty in the future. It used to be a good solution for rendering a lot of data in line plots.
  3. GtkExtra2
    This was the old de-facto standard of plotting charts in GTK+. The jump to GTK+2 seems to have been fatal to this project.
  4. GTK+ instrumentation widgets and GLineGraph
    Somewhat spartans but good for simple stuff.

Other than that, a lot of projects implement internally some kind of GTK+ charting. Other than the yet cited Gnuplot, there is also Gwyddion and gretl. And I'm pretty sure I'm missing tons of others.

In conclusion, there is no general consensus nor a de-facto standard for charting in the GTK+ world...

泼猴你往哪里跑 2024-09-04 20:32:23

看看 gnuplot 有一些 C++ 与 gnuplot 交互的库,它可以完成您正在寻找的事情,然后再做一些事情。如果您曾经使用过 gnuplot,那么它会非常容易使用。

Have a look at the gnuplot there are some C++ libraries that interface with gnuplot, which do what you are looking for and then some. It is very easy to use if you've ever used gnuplot.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文