ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Paint boxes without gap
Posted by marcus on Mar-05-2018 17:13
Attachments:
Hi

I'm using BoxWhisker to paint boxes like in: http://www.advsofteng.com/doc/cdcppdoc/#waterfall.htm
(see 1st image)


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
QChartViewer viewer;

    const int MY_COLOR = 0x808fc38f;

    double data_00[] = {85, 156, 179, 211, 123,
                       115, 156, 179, 211, 123,
                       100, 90};
    double data_01[] = {65, 56, 79, 111, 63,
                       65, 56, 79, 111, 63,
                       80, 75};
    double data_x[] = {
        0, 1, 2, 3, 4,
        6, 7, 8, 9, 10,
       12, 13
    };
    int data_x_length = 12;

    const char *labels[] = {"Monday", "Tuesday", "Wednesday",
                            "Thursday", "Friday", "Text", "Long Text",
                           "Text", "TEXT", "Text Text", "And Text",
                           "Text", "Text", "Text"};

    XYChart *c = new XYChart(500, 500);
    c->setAntiAlias(true, true);

    c->setPlotArea(30, 20, 400, 400,
                   0xf0f0f0,
                   Chart::Transparent, Chart::Transparent,
                   0x666666,
                   0x666666
                   );
    c->yAxis()->setLinearScale(1, 250, 10, 0);
    c->yAxis()->setLabelStyle(QString("segoeui.ttf").toUtf8(), 9, Chart::TextColor);
    c->xAxis()->setLabelStyle(QString("segoeui.ttf").toUtf8(), 9, Chart::TextColor, 60);

    BoxWhiskerLayer* p_bw_layer_00 = c->addBoxWhiskerLayer(
                DoubleArray(data_00, sizeof(data_00)/sizeof(data_00[0])),
                DoubleArray(data_01, sizeof(data_01)/sizeof(data_01[0]))
                );
    p_bw_layer_00->setXData(DoubleArray(data_x, sizeof(data_x)/sizeof(data_x[0])));

    // color
    for (int i = 0; i < data_x_length; ++i)
    {
        p_bw_layer_00->setBoxColor(i, MY_COLOR);
    }
    p_bw_layer_00->setBorderColor(MY_COLOR);

    c->xAxis()->setLabels(StringArray(labels, sizeof(labels)/sizeof(labels[0])));

    viewer.setChart(c);

    delete c;
    viewer.show();
    return app.exec();
}

But i need the Boxes without gaps. (see 2nd image) **required look**

And without overlapping. (see 3rd image)

And i can rescale the window, so chartsize can change during displaying the chart.

Regards

Marcus
likeItLooks.png
likeItShouldLook.png
overlaping.png

  Re: Paint boxes without gap
Posted by Peter Kwan on Mar-06-2018 02:38
Attachments:
Hi Marcus,

You can use BaseBoxLayer.setDataWidth to set the width of the bars. To make the bars touch each others with no gap and no ovelrapping, the bar width must be:

int bar_width = plot_area_width / x_slots;

Because of integer rounding, we must adjust the plot_area_width to the exact multiple of the bar_width, otherwise there may still be gaps. For example, if the plot_area_width is 400, and there are 14 positions on the x-axis (including the gaps), the bar_width is 400 / 14 = 28 (truncated to an integer). Now the total width of all bars is just 28 x 14 = 392 and there will be 8 extra pixels that will become the gaps. We must adjust the plot area width to 392 to avoid the gaps.

plotAreaWidth = box_width * x_slots;

The complete code is as follows:


#include <QApplication>
#include "qchartviewer.h"


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QChartViewer viewer;

    const int MY_COLOR = 0x808fc38f;

    double data_00[] = {85, 156, 179, 211, 123,
                       115, 156, 179, 211, 123,
                       100, 90};
    double data_01[] = {65, 56, 79, 111, 63,
                       65, 56, 79, 111, 63,
                       80, 75};
    double data_x[] = {
        0, 1, 2, 3, 4,
        6, 7, 8, 9, 10,
        12, 13
    };

    int data_length = sizeof(data_x)/sizeof(data_x[0]);
    int x_slots = data_x[data_length - 1] + 1;

    int plotAreaWidth = 400;

    // Adjust plot area width to an exact multiple of the box_width
    box_width = plotAreaWidth / x_slots;
    plotAreaWidth = box_width * x_slots;

    const char *labels[] = {"Monday", "Tuesday", "Wednesday",
                            "Thursday", "Friday", "Text", "Long Text",
                           "Text", "TEXT", "Text Text", "And Text",
                           "Text", "Text", "Text"};

    XYChart *c = new XYChart(500, 500);
    c->setPlotArea(30, 20, plotAreaWidth, 400,
                   0xf0f0f0,
                   Chart::Transparent, Chart::Transparent,
                   0x666666,
                   0x666666
                   );
    c->yAxis()->setLinearScale(1, 250, 10, 0);
    c->yAxis()->setLabelStyle(QString("segoeui.ttf").toUtf8(), 9, Chart::TextColor);
    c->xAxis()->setLabelStyle(QString("segoeui.ttf").toUtf8(), 9, Chart::TextColor, 60);

    BoxWhiskerLayer* p_bw_layer_00 = c->addBoxLayer(
        DoubleArray(data_00, data_length),
        DoubleArray(data_01, data_length),
        MY_COLOR);
    p_bw_layer_00->setBorderColor(MY_COLOR);
    p_bw_layer_00->setXData(DoubleArray(data_x, data_length));
    p_bw_layer_00->setDataWidth(box_width);

    c->xAxis()->setLabels(StringArray(labels, sizeof(labels)/sizeof(labels[0])));

    viewer.setChart(c);

    delete c;
    viewer.show();
    return app.exec();
}


Hope this can help.

Regards
Peter Kwan
test.png

  Re: Paint boxes without gap
Posted by Peter Kwan on Mar-06-2018 02:42
Attachments:
Hi Marcus,

Sorry, the image in the last file is incorrect. The correct image is as follows.

Regards
Peter Kwan
test.png

  Re: Paint boxes without gap
Posted by Michael P. on Apr-10-2018 20:44
Hi Peter,
out of curiosity: what is the BoxWhiskerLayer.setDataGap(double) then for?

best regards,
Michael

  Re: Paint boxes without gap
Posted by Peter Kwan on Apr-11-2018 01:24
Hi Michael,

The setDataGap sets the gap between the boxes as a ration between 0 to 1 (which means 0% gap to 100% gap). You cannot use both setDataWidth and setDataGap, as setting one forces the other to certain values.

Also, due to various graphics constraints, the realized gap may not be exactly as configured. The constraints are:

- The box-width must be an integral number of pixels
- The box-width must be the same for all boxes.

For example, if the plot area width is 200, and there are 3 boxes, it is impossible to set a gap of 0 (no gap). It is because 200 is not divisible by 3, so it is not possible to divide the pixels into 3 bars of equal and integral width. ChartDirector will choose 66 pixels as the width, which means there must be 2 pixels of gap in total in the chart.

Regards
Peter Kwan