Page 1 of 1

2D realtime graph

Posted: Thu Apr 02, 2009 10:43 am
by Katsankat
Here is a class to display a graph (here 5 at once) :

Image

Irrlicht users are encouraged to try it!

Example of use :

Code: Select all

#include "GraphKat.h"

int main()
{
  IrrlichtDevice* device = createDevice(EDT_OPENGL, dimension2d<s32>(280,300));
  if (!device) return 1;

  device->setWindowCaption(L"Graph class");
  IVideoDriver* driver = device->getVideoDriver();
  ISceneManager* smgr  = device->getSceneManager();
  IGUIEnvironment* guienv = device->getGUIEnvironment();

  GraphKat* graph = new GraphKat(L"random values", device, rect<s32>(10,10 , 140,80));

  u32 now=0, then=0, NextGraph=0;

  while(device->run()) if (device->isWindowActive()) 
  {
    now = device->getTimer()->getTime();

    if (then < now)
    {
      driver->beginScene(true, true, 0);

      // draw the graph
      graph->draw();

      //feed it artificially every 240 ms
      if (NextGraph < now)
      {
        graph->addValue(rand()% graph->getMax());
        NextGraph = now + 240;
      }

      //smgr->drawAll(); // not needed
      guienv->drawAll(); // not needed if draw text is removed
      driver->endScene();

      then = now + 30;
    }
  }
  else device->yield();

  //end of main loop
  delete graph;
  device->closeDevice();

  return 0;
}
... everything is based on the driver::draw2DLine() method :

Code: Select all

void GraphKat::draw()
{
  //values
  for (u8 x=1; x<t.size(); x++)
    driver->draw2DLine (position2d<s32>(L+x, H-t[x-1]),
                        position2d<s32>(L+x, H-t[x]  ),   white);
}
My suggestion to use it in a project: inside the class remove all the draw() methods, except the draw() itself because it is the simplest and the fatest method. It does not even handle the caption, this means all the guienv code can be removed too ... and the code becomes very short and open.

Compiled example and sources (1.85Mb)

If you have ideas please let them here.

yaaaaa

Posted: Thu Apr 02, 2009 4:06 pm
by netpipe
thanks for this great peice of code, much appreciated!!

best wishes and plenty of women

Posted: Thu Apr 02, 2009 5:01 pm
by Linaxys
Awesome dude !
I really needed that code a long time ago !

Thanks !! :D

cool

Posted: Thu Apr 02, 2009 5:07 pm
by netpipe
same project with a cb file, and a couple modifications to the main loop.
http://www.mediafire.com/?jck3vut1jgw

thanks again!

Posted: Tue Jun 23, 2009 3:33 am
by Midnight
That is a fine looking graph sir.

And thanks for cb project files.

Posted: Tue Jun 23, 2009 11:52 pm
by sudi
nice graph class but a little hard to use...
i made a guiElement with almost the same features. its still missing sme of your stuff.
But it supports scaling of the graph so it works with any value u push in even negative values.

Download

Posted: Wed Jun 24, 2009 7:33 am
by FuzzYspo0N
hey guys these are cool additions, nice work. Maybe try making it possible to skin the graph using graphics and ill make some cool graphics ;)

Posted: Wed Jun 24, 2009 12:48 pm
by Katsankat
Nice Sudi. Put your name in CGraph.cpp and CGraph.h so that we know who did what.

Posted: Thu Jun 25, 2009 5:23 am
by Midnight
Sudi wrote:nice graph class but a little hard to use...
i made a guiElement with almost the same features. its still missing sme of your stuff.
But it supports scaling of the graph so it works with any value u push in even negative values.

Download
ooh pretty.

Re: 2D realtime graph

Posted: Sat Dec 17, 2011 5:55 pm
by Katsankat
Update.
Image

Compiled with irrlicht 1.7.2
Class constructor is looking for a font called "Lucida8.bmp" you can find it in the media folder.

main.cpp

Code: Select all

 
#include "GraphKat.h"
 
void loadTerrain(IrrlichtDevice* device);
 
 
int main()
{
        dimension2d<u32> Res (800,600);
        IrrlichtDevice* device = createDevice(EDT_OPENGL, Res);
        if (!device) return 1;
 
        device->setWindowCaption(L"Graph");
        device->getCursorControl()->setVisible(false);
 
        IVideoDriver* driver = device->getVideoDriver();
        ISceneManager* smgr  = device->getSceneManager();
        IGUIEnvironment* guienv = device->getGUIEnvironment();
 
        loadTerrain(device);
 
        ICameraSceneNode *cam;
                                        cam = smgr->addCameraSceneNodeFPS(0, 80.0f, 5.f);
                                        cam->setPosition(core::vector3df(0,6000,0));
                                        cam->setTarget(core::vector3df(3000,200,3000));
                                        cam->setFarValue(90000.f);
 
        GraphKat *graphPri = new GraphKat(L"Primitives", device, rect<s32>(10,Res.Height-60, 100,Res.Height-25));
        GraphKat *graphFPS = new GraphKat(L"FPS", device,        rect<s32>(10,Res.Height-100, 100,Res.Height-65));
 
        u32 now=0, then=0;
 
        while(device->run())
        {
                if (device->isWindowActive()) 
                {
                        driver->beginScene(true, true, 0xff222222);
                        smgr->drawAll();
                        graphPri->draw();
                        graphFPS->draw();
                        guienv->drawAll();
                        driver->endScene();
 
                        now = device->getTimer()->getTime();
                        if (then < now)
                        {
                                graphPri->addValue( driver->getPrimitiveCountDrawn() );
                                graphFPS->addValue( driver->getFPS() );
                                then = now + 50;
                        }
                }
                else device->yield();
        }
        
    delete graphPri;
    delete graphFPS;
 
        device->closeDevice();
 
        return 0;
}
 
 
 
 
 
/*==============================================================================
  LOAD TERRAIN
==============================================================================*/
void loadTerrain(IrrlichtDevice* device)
{
        ISceneManager* smgr  = device->getSceneManager();
        IVideoDriver* driver = device->getVideoDriver();
 
        ITerrainSceneNode *terrain = smgr->addTerrainSceneNode("terrain/hmap257.png");
        terrain->setScale(core::vector3df(128, 16, 128));
        terrain->setMaterialType(video::EMT_DETAIL_MAP);
 
        terrain->setMaterialTexture(0, driver->getTexture("terrain/finaltexture.png"));
        terrain->setMaterialTexture(1, driver->getTexture("terrain/detailmap3.jpg"));
        terrain->scaleTexture(1.f, 32.f);
        terrain->setMaterialFlag(video::EMF_LIGHTING,false);
}
 
GraphKat.h

Code: Select all

 
#ifndef BX_GraphKat_H
#define BX_GraphKat_H
 
#include "irrlicht.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;
 
class GraphKat
{
 IVideoDriver* driver;
 
 //caption
 const wchar_t* caption;
 IGUIEnvironment* guienv;
 IGUIFont* font;
 
 // The array of points to be drawn
 core::array<u32> t;
 
 //physical properties
 u16 L,T,W,H;
 u32 Max; // max Y value (real value, not pixels)
 f32 rate;
 u32 lastinsertedvalue;
 
 SColor white, orange;
 
public:
 GraphKat(const wchar_t* _caption, IrrlichtDevice* device, core::rect<s32> rect);
 void setMax(int _max);
 void setText(wchar_t* text);
 void addValue(u32 val);
 void draw();
 ~GraphKat();
};
 
#endif
 
GraphKat.cpp

Code: Select all

 
#include "GraphKat.h"
 
/*==============================================================================
  Constructor
==============================================================================*/
GraphKat::GraphKat(const wchar_t* _caption, IrrlichtDevice* device, core::rect<s32> Rect)
{
  driver = device->getVideoDriver();
 
  L = Rect.UpperLeftCorner.X;
  T = Rect.UpperLeftCorner.Y;
  W = Rect.LowerRightCorner.X;
  H = Rect.LowerRightCorner.Y;
 
  setMax(1);
 
  u8 nbVals = W - L;
 
  // init with zero values
  for (u8 x=0; x<nbVals; x++)
    t.push_back(0);
 
  white = SColor(0xffffffff);
  orange = SColor(0xffffa500);
 
  // draw text
  caption = _caption;
  IGUIEnvironment* guienv = device->getGUIEnvironment();
  font = guienv->getFont("Lucida8.bmp");
  guienv->getSkin()->setFont(font);
}
/*==============================================================================
  set Maximum value (example 500000)
==============================================================================*/
void GraphKat::setMax(int _max)
{
  Max = _max;
  u8 height = H - T - 10;
  rate = (f32)height / (f32)Max;
}
/*==============================================================================
  Adding a value will put it at the end of the list, and erase the first element
==============================================================================*/
void GraphKat::addValue(u32 val)
{
  if (val > Max) setMax(val);
 
  lastinsertedvalue = val;
 
  t.push_back(ceil(val*rate));
  t.erase(0);
}
/*==============================================================================
 
==============================================================================*/
void GraphKat::draw()
{
        //drawBorder();
        driver->draw2DLine (position2d<s32>(L,T), position2d<s32>(W,T), white);
        driver->draw2DLine (position2d<s32>(L,T), position2d<s32>(L,H), white);
        driver->draw2DLine (position2d<s32>(L,H), position2d<s32>(W,H), white);
        driver->draw2DLine (position2d<s32>(W,T), position2d<s32>(W,H), white);
 
        u8 nb = t.size();
        for (u8 x=1; x<nb; x++)
                driver->draw2DLine (position2d<s32>(L+x-1, H-t[x-1]),
                                                        position2d<s32>(L+x, H-t[x]  ),   white);
 
        core::stringw s(caption); s+=L"\n\n"; s+= lastinsertedvalue;
        font->draw (s.c_str(), core::rect<s32>(L+2,T+1,W,20), orange);
}
/*==============================================================================
 
==============================================================================*/
void GraphKat::setText(wchar_t* text)
{
  caption = text;
}
/*==============================================================================
  Destructor
==============================================================================*/
GraphKat::~GraphKat()
{
 
}