0

I am trying to generate bar graph using JSON Data which i am getting from Web-services, basically my requirement is to show a "Bar Graph" using "JSON" data.

Basically I am Android Developer and very new to Blackberry 10 Native, so i don't know much about Blackberry, So If any one can guide me regarding generating graph in Blackberry-10.

I have searched a lot in google and every where else where i can, but i didn't come with any conclusion. Still i am searching a solution for it, So basically my "JSON" data is in following format.

{"Ax":"3:41","Ay":"04:41","Bx":"10:47 ","By":"12:47","Cx":"18:30","Cy":"19:30","Az":3,"Bz":2,"Cz":1,"condition":2}

Here "Ax":"3:41","Ay":"04:41" this is parameter is hour of starting and ending work, and at last it calculates the total number of hour like "Az":3,"Bz":2,"Cz":1 and generate graph based on that. So similarly my graph would look something like this

http://postimg.org/image/nb6dnpwax/

Please help me how can i generate graph based on this, some of the link which i have refered to generate graph is

http://elycharts.com/examples
http://g.raphaeljs.com/
How to make charts/graphs (such as line graphs, bar graphs, circle graphs), etc. in C++, Qt, QML, Blackberry 10 Cascades Beta 3 SDK?
http://devblog.blackberry.com/2014/01/conference-app-secrets-part-3-json-vs-xml/

One thing i am clearly mentioning is i want solution using qml and C++ way with Blackberry-10 so please do not suggest any other method like Java and other all.

Thank you in advance for helping me out.

Community
  • 1
  • 1
user3660803
  • 315
  • 1
  • 3
  • 15
  • There are no graphing libraries for bb10 yet as far as I'm aware. The easiest would probably be to build your own graph using containers. Off the top of my head I would recommend having the main container set for absolute layout and then positioning containers for each bar inside it. – hyarion Jul 10 '14 at 16:05
  • I have a solution for you that I will post when I get home and have access to my code base. Have a look at the screen shots for this app: http://appworld.blackberry.com/webstore/content/128442/?lang=en&countrycode=CA The third one shows the bar graphs. The technique is basically drawing on a QImage, which has a fairly good drawing package, then transferring a Cascades ImageView. – Richard Jul 10 '14 at 17:58
  • @Hyarion, Thank you for your suggestion, i will try your solution as well and will get back to you when i finish my task. – user3660803 Jul 11 '14 at 04:37

1 Answers1

3

So there is this article on BlackBerry Support Forums. All the basics are there, but I do so much work with runtime generated images I decided to create a class to encapsulate it. As requested here is a simple sample based on one of the Cascades templates. You should also become familiar with the documentation at:

And the sample files at the BlackBerry GIT Hub.

QML file:

/*
 * Copyright (c) 2011-2014 BlackBerry Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import bb.cascades 1.2

Page {
    Container {
        layout: DockLayout {

        }
        Label {
            // Localized text with the dynamic translation and locale updates support
            text: qsTr("Bar Graph") + Retranslate.onLocaleOrLanguageChanged
            textStyle.base: SystemDefaults.TextStyles.BigText
            horizontalAlignment: HorizontalAlignment.Center
        }
        ImageView {
            objectName: "barGraph"
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Center
        }
    }
}

Here is the header file:

 /*
 * DrawableImage.hpp
 *
 *  Created on: Jul 11, 2014
 *      Author: richard
 */

#ifndef DRAWABLEIMAGE_HPP_
#define DRAWABLEIMAGE_HPP_

#include <bb/ImageData>
#include <QtGui/QImage>
#include <bb/cascades/ImageView>

namespace net
{
    namespace test
    {

        class DrawableImage : public QImage
        {
        public:
            DrawableImage();
            DrawableImage(QSize imageSize, QImage::Format format);
            virtual ~DrawableImage();

            void    emitRenderingBegin();
            void    emitRenderingFinished();

            DrawableImage&  operator = (const QImage &image) { QImage::operator =(image); return *this; }

            QPainter        &painter();

        public:
            void    updateToView(bb::cascades::ImageView *imageView);

        private:
                void    deleteBuffer();

                QPainter        m_painter;
                QSize           m_sizeInPixels;
                unsigned char*  m_buffer; // pixel data in PixelBufferData format
        };

    } /* namespace test */
} /* namespace net */

#endif /* DRAWABLEIMAGE_HPP_ */

And the cpp file:

/*
 * DrawableImage.cpp
 *
 *  Created on: Jul 11, 2014
 *      Author: richard
 */

#include <src/DrawableImage.hpp>

namespace net
{
    namespace test
    {

        DrawableImage::DrawableImage()
            : m_painter(), m_sizeInPixels(0,0), m_buffer(NULL)
        {
            // TODO Auto-generated constructor stub

        }

        DrawableImage::DrawableImage(QSize imageSize, QImage::Format format)
            : QImage(imageSize, format), m_painter(), m_sizeInPixels(0,0), m_buffer(NULL)
        {

        }


        DrawableImage::~DrawableImage() {
            // TODO Auto-generated destructor stub
        }

        /*
        void DrawableImage::emitRenderingBegin() {
            emit renderingBegin();
        }

        void DrawableImage::emitRenderingFinished() {
            emit renderingFinished();
        }
        */

        QPainter& DrawableImage::painter() {
            if (!m_painter.isActive()) {
                m_painter.begin(this);
            }

            return m_painter;
        }

        void DrawableImage::deleteBuffer()
        {
            if (m_buffer != 0)
            {
                delete [] m_buffer;
                m_buffer = 0;
            }
        }

        void    DrawableImage::updateToView(bb::cascades::ImageView *imageView) {
            if (m_painter.isActive()) {
                m_painter.end();
            }

            Q_ASSERT(imageView != NULL);

            QImage swapped     = rgbSwapped();
            QSize  swappedSize = swapped.size();

            int w = swappedSize.width();
            int h = swappedSize.height();

            int numBytes  = w * h * 4;
            if (swappedSize != m_sizeInPixels)
            {
                deleteBuffer();
                m_sizeInPixels = QSize(w, h);
                m_buffer = new uchar[numBytes];
            }

            // Copy the memory over.
            // We'll add defensive code in case rgbSwapped has a different size
            const uchar* from = swapped.constBits();
            int numFromBytes = swapped.numBytes();
            int numToCopy = std::min(numFromBytes, numBytes);

            memcpy(m_buffer, from, numToCopy);
            if (numToCopy < numBytes)
            {
                memset(m_buffer + numToCopy, 0x00, numBytes - numToCopy);
            }

            bb::ImageData imageData = bb::ImageData::fromPixels(m_buffer, bb::PixelFormat::RGBA_Premultiplied,
                                   m_sizeInPixels.width(),
                                   m_sizeInPixels.height(),
                                   m_sizeInPixels.width() * 4);

            imageView->setImage(imageData);
        }


    } /* namespace test */
} /* namespace net */

And here is the applicationui.cpp (applicationui.hpp is not modified):

/*
 * Copyright (c) 2011-2014 BlackBerry Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "applicationui.hpp"

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/LocaleHandler>

#include <src/DrawableImage.hpp>

using namespace bb::cascades;
using namespace net::test;

ApplicationUI::ApplicationUI() :
        QObject()
{
    // prepare the localization
    m_pTranslator = new QTranslator(this);
    m_pLocaleHandler = new LocaleHandler(this);

    bool res = QObject::connect(m_pLocaleHandler, SIGNAL(systemLanguageChanged()), this, SLOT(onSystemLanguageChanged()));
    // This is only available in Debug builds
    Q_ASSERT(res);
    // Since the variable is not used in the app, this is added to avoid a
    // compiler warning
    Q_UNUSED(res);

    // initial load
    onSystemLanguageChanged();

    // Create scene document from main.qml asset, the parent is set
    // to ensure the document gets destroyed properly at shut down.
    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);

    // Create root object for the UI
    AbstractPane *root = qml->createRootObject<AbstractPane>();

    /*
     * This code exercises the DrawableImage
     */
    QSize   graphImageSize(700, 700);
    DrawableImage    graph;
    ImageView* graphImageView = root->findChild<ImageView*>("barGraph");

    // Initialise graph and fill with transparent black.
        graph = QImage(graphImageSize, QImage::Format_ARGB32_Premultiplied);
        graph.fill(Qt::black);

        // Set the background mode
        graph.painter().setBackgroundMode(Qt::TransparentMode);

        // Set rendering hints
        graph.painter().setRenderHint(QPainter::Antialiasing, true);

        for (int i = 0; i < 10; i++) {

            int x = i * (graphImageSize.width()/10);
            int h = i * (graphImageSize.height()/10) + graphImageSize.height()/20;
            int w = graphImageSize.width()/10 - 20;

            graph.painter().fillRect( x + 10, graphImageSize.height()-h, w, h, Qt::darkGreen);
        }

    // Once the image is drawn transfer it to the Cascades ImageView
    graph.updateToView(graphImageView);

    // Set created root object as the application scene
    Application::instance()->setScene(root);
}

void ApplicationUI::onSystemLanguageChanged()
{
    QCoreApplication::instance()->removeTranslator(m_pTranslator);
    // Initiate, load and install the application translation files.
    QString locale_string = QLocale().name();
    QString file_name = QString("BarGraph_%1").arg(locale_string);
    if (m_pTranslator->load(file_name, "app/native/qm")) {
        QCoreApplication::instance()->installTranslator(m_pTranslator);
    }
}

You will also need to add a LIBS line to the .pro file:

APP_NAME = BarGraph

CONFIG += qt warn_on cascades10
LIBS += -lbb

include(config.pri)

This is the result:

enter image description here

Richard
  • 8,920
  • 2
  • 18
  • 24
  • Hey Richard, Thank you for your answer, let me implement this in to my code and i will get back to you, but Thank you for your quick answer. Thanks a ton... – user3660803 Jul 11 '14 at 04:36
  • Hello Richard, Can you tell me how can i implement this complete example. Or else can you provide full example with "qml" and all "C++" as i am very new to Blackberry-10 i don't know how can i implement this example. Thank you for your support. – user3660803 Jul 11 '14 at 06:42
  • I don't know how specific I can be not knowing your use case, but this should get you going. – Richard Jul 11 '14 at 14:07
  • Hey Richard, i don't have enough word to thank you, you are awesome man, Really a great help. Thanks a ton. You are genius man. – user3660803 Jul 12 '14 at 05:01
  • 1
    Just write greate native BB10 applications ;) – Richard Jul 12 '14 at 13:22