天天看点

QwtPlot之绘制统计图

   QwtPlot是用来绘制二维图像的widget。在它的画板上可以无限制的显示绘画组件。绘画组件可以是曲线(QwtPlotCurve)、标记(QwtPlotMarker)、网格(QwtPlotGrid)、或者其它从QwtPlotItem继承的组件。             QwtScaleDraw可以用来绘制线性或对数尺度。一个标尺可以指定位置、对齐方式、长度等。标签可使用setLabelRotation()和setLabelAlignment()来设置旋转和对齐方式。通过QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s)设置独立的标尺QwtScaleDiv对象, 标尺可以使用QwtAbstractScaleDraw::draw()函数来绘制。           看了一下QWT中关于distrowatch的代码,将其修改为天龙八部中十大高手排行榜,并添加了一些注释,排名是否正确先不做讨论,重在代码,^_^便于理解!

//barchar.h

#ifndef BAR_CHART_H
#define BAR_CHART_H

#include 

class DistroChartItem;

class BarChart: public QwtPlot
{
    Q_OBJECT

public:
    BarChart(QWidget *parent = NULL);

public slots:
    void setOrientation(int value);
    void exportChart();

private:
    void populate();

private:
    DistroChartItem *d_barChartItem;
    QStringList d_distros;
};

#endif //BAR_CHART_H      
//barchar.cpp

#include "barchart.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class DistroScaleDraw: public QwtScaleDraw
{
public:
    DistroScaleDraw(Qt::Orientation orientation, const QStringList &labels)
        : d_labels(labels)
    {
        //设置间距、中间刻度、主刻度
        setTickLength(QwtScaleDiv::MinorTick, 0);
        setTickLength(QwtScaleDiv::MediumTick, 0);
        setTickLength(QwtScaleDiv::MajorTick, 5);

        //不显示主轴线
        enableComponent(QwtScaleDraw::Backbone, false);

        //设置旋转角度、对齐方式
        double rotation = (orientation == Qt::Vertical) ? -10.0 : -10.0;
        setLabelRotation(rotation);
        setLabelAlignment(Qt::AlignVCenter);
    }

    //用于显示文本
    virtual QwtText label(double value) const
    {
        QwtText text("");
        int index = static_cast(value); //qRound(value);
        if (index >= 0 && index < d_labels.size())
            text = d_labels[index];

        return text;
    }

private:
    QStringList d_labels;
};
#include 
class DistroChartItem: public QwtPlotBarChart
{
public:
    DistroChartItem(): QwtPlotBarChart()
    {
        setLegendMode(QwtPlotBarChart::LegendBarTitles);
        //设置项大小
        setLegendIconSize(QSize(15, 15));
    }

    void addDistro(const QString &distro, const QColor &color )
    {
        d_colors += color;
        d_distros += distro;
        itemChanged();
    }

    //用于显示设置项
    virtual QwtColumnSymbol *specialSymbol(int index, const QPointF &) const
    {
        //自定义项符号线度、样式、背景色
        QwtColumnSymbol *symbol = new QwtColumnSymbol(QwtColumnSymbol::Box);
        symbol->setLineWidth(5);
        symbol->setFrameStyle(QwtColumnSymbol::Raised);

        QColor color(Qt::white);
        if (index >= 0 && index < d_colors.size())
            color = d_colors[index];

        symbol->setPalette(color);
    
        return symbol;
    }

    //用于显示设置项文本
    virtual QwtText barTitle(int sampleIndex) const
    {
        QwtText title("");
        if (sampleIndex >= 0 && sampleIndex < d_distros.size())
            title = d_distros[sampleIndex];

        return title;
    }

private:
    QList d_colors;
    QList d_distros;
};

BarChart::BarChart(QWidget *parent):
    QwtPlot(parent)
{
    const struct 
    {
        QString distro;
        int hits;
        QColor color;
    }
    pageHits[] =
    {
        {QString::fromLocal8Bit("扫地神僧"), 10000, QColor(0, 160, 230)},
        {QString::fromLocal8Bit("无崖子"), 9500, QColor(115, 185, 35)},
        {QString::fromLocal8Bit("萧远山"), 8888, QColor(235, 30, 35)},
        {QString::fromLocal8Bit("慕容博"), 8500, QColor(160, 70, 164)},
        {QString::fromLocal8Bit("虚竹"), 8000, QColor(255, 130, 0)},
        {QString::fromLocal8Bit("萧峰"), 7888, QColor(125, 125, 125)},
        {QString::fromLocal8Bit("段誉"), 7000, QColor(125, 125, 255)},
        {QString::fromLocal8Bit("天山童姥"), 6500, QColor(180, 255, 180)},
        {QString::fromLocal8Bit("李秋水"), 5000, QColor(135, 205, 250)},
        {QString::fromLocal8Bit("鸠摩智"), 4500, QColor(255, 175, 200)}
    };

    //设置标题、背景色
    setAutoFillBackground(true);
    setPalette(QColor("Linen"));
    setTitle(QStringLiteral("天龙八部十大高手排行榜"));

    //设置画布边框宽度、样式、圆角大小、背景色
    QwtPlotCanvas *canvas = new QwtPlotCanvas();
    canvas->setLineWidth(2);
    canvas->setFrameStyle(QFrame::Box | QFrame::Sunken);
    canvas->setBorderRadius(10);
    QPalette canvasPalette(QColor("Plum"));
    canvasPalette.setColor(QPalette::Foreground, QColor("Indigo"));
    canvas->setPalette(canvasPalette);
    setCanvas(canvas);

    d_barChartItem = new DistroChartItem();

    QVector samples;
    for (int i = 0; i < sizeof(pageHits) / sizeof(pageHits[0]); i++)
    {
        d_distros += pageHits[i].distro;
        samples += pageHits[i].hits;
        d_barChartItem->addDistro(pageHits[i].distro, pageHits[i].color);
    }
    d_barChartItem->setSamples(samples);
    d_barChartItem->attach(this);
    insertLegend(new QwtLegend());
    setOrientation(0);
    setAutoReplot(false);
}

void BarChart::setOrientation(int value)
{
    //设置水平或垂直显示
    Qt::Orientation orientation = (value == 0) ? Qt::Vertical : Qt::Horizontal;
    int xBottomAxisId = QwtPlot::xBottom;
    int yLeftAxisId = QwtPlot::yLeft;

    if (orientation == Qt::Horizontal)
        qSwap(xBottomAxisId, yLeftAxisId);

    d_barChartItem->setOrientation(orientation);

    //设置X/Y轴标题、显示范围、轴线的最大间隔
    setAxisTitle(xBottomAxisId, QStringLiteral("人物"));
    setAxisMaxMinor(xBottomAxisId, 3);
    setAxisScale(xBottomAxisId, 0, d_barChartItem->dataSize() - 1, 1.0);
    setAxisScaleDraw(xBottomAxisId, new DistroScaleDraw(orientation, d_distros));

    setAxisTitle(yLeftAxisId, QStringLiteral("战斗力"));
    setAxisScale(yLeftAxisId, 0, 10000);
    setAxisMaxMinor(yLeftAxisId, 5);
    setAxisScaleDraw(yLeftAxisId, new QwtScaleDraw());

    //设置画布页边距
    plotLayout()->setCanvasMargin(5);

    //重新绘制
    replot();
}

//导出pdf
void BarChart::exportChart()
{
    QwtPlotRenderer renderer;
    renderer.exportTo(this, QStringLiteral("天龙八部十大高手排行榜.pdf"));
}      
//main.cpp

#include 
#include 
#include 
#include 
#include 
#include "barchart.h"

class MainWindow: public QMainWindow
{
public:
    MainWindow(QWidget *parent = NULL);

private:
    BarChart *d_chart;
};

MainWindow::MainWindow(QWidget *parent):
    QMainWindow(parent)
{
    d_chart = new BarChart(this);
    setCentralWidget(d_chart);

    QToolBar *toolBar = new QToolBar(this);

    QComboBox *orientationBox = new QComboBox(toolBar);
    orientationBox->addItem("Vertical");
    orientationBox->addItem("Horizontal");
    orientationBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    QToolButton *btnExport = new QToolButton(toolBar);
    btnExport->setText("Export");
    btnExport->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    connect(btnExport, SIGNAL(clicked()), d_chart, SLOT(exportChart()));

    toolBar->addWidget(orientationBox);
    toolBar->addWidget(btnExport);
    addToolBar(toolBar);

    d_chart->setOrientation(orientationBox->currentIndex());
    connect(orientationBox, SIGNAL(currentIndexChanged(int)), d_chart, SLOT(setOrientation(int)));
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow mainWindow;
    mainWindow.resize(600, 500);
    mainWindow.show();

    return a.exec();
}      

效果如下:

QwtPlot之绘制统计图

注:     技术在于交流、沟通,转载请注明出处并保持作品的完整性。      作者: ╰☆奋斗ing❤孩子`    原文: http://blog.sina.com.cn/s/blog_a6fb6cc90102v2ef.html

Qt

继续阅读