用 C++ 和 libgd 来绘图

用 C++ 和 libgd 来绘图

[TOC]

旧文转贴, 代码很久以前写的, 大约至今有十年了, 最近看到有人问如何用 C++ 来生成图表.
有一个 graphviz 的开源库可以用, 它用了自己的领域特定语言 DSL: dot 来生成图表, 具体应用可见 http://graphviz.org/

当然也可以不用这么重的开源库, 这里介绍了以前写的一个chart 库, 千余行代码, 采用了比较原始的作法, 调用了 libgd 基础API, 如画点, 画线等原子方法来绘制图表, 可以应用于一些比较简单的场合

实例

先看看生成的图表实例

折线图和鱼骨头图

这里写图片描述

圆饼图和直方图

这里写图片描述

示例代码

上面两个图表由以下几十行代码来实现

#include "TinyUtil.h"
#include "TinyChart.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory>


int main(int argc, char **argv)
{
    printf("-- write image by gd ---");
    {
        STR_VEC xScales;
        xScales.reserve(10);
        xScales.push_back("11-09");
        xScales.push_back("11-10");
        xScales.push_back("11-11");
        xScales.push_back("11-12");
        xScales.push_back("11-13");
        xScales.push_back("11-14");
        xScales.push_back("11-15");
        xScales.push_back("11-16");
        xScales.push_back("11-17");
        xScales.push_back("11-18");
        xScales.push_back("11-19");
        xScales.push_back("11-20");
        xScales.push_back("11-21");
        xScales.push_back("11-22");

        INT_VEC yScales;
        yScales.reserve(10);
        yScales.push_back(200);
        yScales.push_back(130);
        yScales.push_back(3456);
        yScales.push_back(2345);
        yScales.push_back(1320);
        yScales.push_back(30);
        yScales.push_back(2200);
        yScales.push_back(1330);
        yScales.push_back(3330);
        yScales.push_back(332);
        yScales.push_back(788);
        yScales.push_back(200);
        yScales.push_back(13890);
        yScales.push_back(200);

        TinyTrendlineDiagram* pt = new TinyTrendlineDiagram(
                "latency_trendline.png", 800, 250);
        pt->SetTitle("Trend of Latency (the middle network latency is the value of 0 coordinate)");
        pt->SetLabels(xScales);
        pt->SetValues(yScales);

        pt->Draw();
        pt->WriteImage();
        delete pt;
    }

    {
        STR_VEC xScales;
        xScales.push_back("America");
        xScales.push_back("China");
        xScales.push_back("Japan");
        xScales.push_back("England");
        xScales.push_back("France");
        xScales.push_back("Germany");
        xScales.push_back("South Korean");
        xScales.push_back("India");

        INT_VEC yScales;
        yScales.push_back(4800);
        yScales.push_back(3008);
        yScales.push_back(100);
        yScales.push_back(20);
        yScales.push_back(2000);
        yScales.push_back(178);
        yScales.push_back(258);
        yScales.push_back(1789);

        TinyDistributionDiagram* pd = new TinyDistributionDiagram(
                "users_distribution.png", 800, 600);
        pd->SetTitle("Daily active users distribution among the countries");
        pd->SetLabels(xScales);
        pd->SetValues(yScales);
        pd->Draw();
        pd->WriteImage();
        delete pd;
    }
    return 0;
}

设计与实现

其实, 也就是封装了libgd 的原子操作, 绘制了基本的图形单元

1) 首先下载并编译依赖库 libgd

  • 下载: Download libgd-2.2.1.tar.gz
  • 解压: tar xvfz libgd-2.2.1.tar.gz
  • 构建步骤 build steps
    cd libgd-2.2.1
    mkdir bld
    cd bld
    cmake -DENABLE_PNG=1 -DENABLE_JPEG=1 -DENABLE_FREETYPE=1 ..
    make
    make install

2) 然后实现上图所示的类, 大约千余行代码, 放在 github 里

https://gist.github.com/walterfan/b7200fd3e5315ec1e16551fca096a67e

附录

  • libgd site: https://libgd.github.io/
  • http://yuml.me 以上类图由其按下面的代码生成

    // Cool Class Diagram
    [Sharp]^[Arc]
    [Arc]^[Eclipse]
    [Arc]^[Circle]
    [Sharp]^[Rectangle]
    [Sharp]^[Scale]
    [Sharp]^[Chart]
    [Chart]^[CurveChart]
    [Chart]^[ColumnChart]
    [Chart]^[PieChart]
    [Chart]^[HistogramChart]
    [Diagram]-[note:Aggregate chart{bg:wheat}]
    [Diagram]^[DistributionDiagram]
    [Diagram]^[TrendlineDiagram]
    [TrendlineDiagram]<>-0..*>[CurveChart]
    [TrendlineDiagram]<>-0..*>[ColumnChart]
    [DistributionDiagram]<>-0..*>[PieChart]
    [DistributionDiagram]<>-0..*>[HistogramChart]

本人最近在学习利用c语言将字符串转成图片的操作,碰巧在网上看到有大神提到可以用这个第三方库,发现功能挺强大的。 官网地址:https://libgd.github.io/ 使用过程中出现的问题:在编译运行测试代码时,提示error while loading shared libraries: libgd.so.3: cannot open shared object file: No such file or directory。 解决方案: 默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件,通常通过源码包进行安装时,如果不指定--prefix,会将库安装在/usr/local/lib目录下;当运行程序需要链接动态库时,提示找不到相关的.so库,会报错。也就是说,/usr/local/lib目录不在系统默认的库搜索目录中,需要将目录加进去。   1、首先打开/etc/ld.so.conf文件   2、加入动态库文件所在的目录:执行vi /etc/ld.so.conf,在"include ld.so.conf.d/*.conf"下方增加"/usr/local/lib"。   3、保存后,在命令行终端执行:/sbin/ldconfig -v;其作用是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用,因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新搜索路径,需要运行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,可能会找不到刚安装的库。   经过以上三个步骤,"error while loading shared libraries"的问题通常情况下就可以解决了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值