1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  *
16  * Author: John Abraham <john.abraham.in@gmail.com>
17  */
18 
19 #include "countertablesscene.h"
20 #include "statisticsconstants.h"
21 #include "animnode.h"
22 #include "animatormode.h"
23 #include "statsview.h"
24 
25 namespace netanim
26 {
27 
28 NS_LOG_COMPONENT_DEFINE ("CounterTablesScene");
29 CounterTablesScene * pCounterTablesScene = 0;
30 
CounterTablesScene()31 CounterTablesScene::CounterTablesScene ():
32   QGraphicsScene (100, 0, STATSSCENE_WIDTH_DEFAULT, 6 * STATSSCENE_HEIGHT_DEFAULT),
33   m_plot (0),
34   m_plotItem (0),
35   m_showChart (true)
36 {
37   m_table = new Table ();
38   m_tableItem = new QGraphicsProxyWidget;
39   m_tableItem->setWidget (m_table);
40   addItem (m_tableItem);
41 
42 }
43 
44 CounterTablesScene *
getInstance()45 CounterTablesScene::getInstance ()
46 {
47   if (!pCounterTablesScene)
48     {
49       pCounterTablesScene = new CounterTablesScene;
50     }
51   return pCounterTablesScene;
52 }
53 
54 
55 void
setCurrentCounterName(QString name)56 CounterTablesScene::setCurrentCounterName (QString name)
57 {
58   m_currentCounterName = name;
59   reloadContent ();
60 }
61 
62 uint32_t
getIndexForNode(uint32_t nodeId)63 CounterTablesScene::getIndexForNode (uint32_t nodeId)
64 {
65   int index = 0;
66   for (int i = 0; i < m_allowedNodes.count (); ++i)
67     {
68       if (i == static_cast <int> (nodeId))
69         return index;
70       ++index;
71     }
72   return index;
73 }
74 
75 bool
isAllowedNode(uint32_t nodeId)76 CounterTablesScene::isAllowedNode (uint32_t nodeId)
77 {
78   for (int i = 0; i < m_allowedNodes.count (); ++i)
79     {
80       if (m_allowedNodes[i] == nodeId)
81         return true;
82     }
83   return false;
84 }
85 
86 void
reloadContent(bool force)87 CounterTablesScene::reloadContent (bool force)
88 {
89   Q_UNUSED (force);
90 
91   if (m_plotItem)
92     {
93       removeItem (m_plotItem);
94       delete m_plot;
95       m_plot = 0;
96       m_plotItem = 0;
97     }
98 
99   typedef QVector<double> valueVector_t;
100   typedef std::map <uint32_t, valueVector_t> nodeValueMap_t;
101   nodeValueMap_t nodeTimes;
102   nodeValueMap_t nodeCounterValues;
103   qreal minCounter = uint32_t(-1);
104   qreal maxCounter = 0;
105   qreal maxTime = 0;
106 
107 
108       m_table->clear ();
109       QStringList headerList;
110       headerList << "Time";
111       for (QVector <uint32_t>::const_iterator i = m_allowedNodes.begin ();
112            i != m_allowedNodes.end ();
113            ++i)
114         {
115           headerList << QString::number (*i);
116         }
117       m_table->setHeaderList (headerList);
118 
119       bool result = false;
120       AnimNode::CounterType_t counterType;
121       uint32_t counterId = AnimNodeMgr::getInstance ()->getCounterIdForName (m_currentCounterName, result, counterType);
122       if (!result)
123         return;
124 
125 
126 
127       TimeValue <AnimEvent *> * events = AnimatorMode::getInstance ()->getEvents ();
128       for (TimeValue<AnimEvent *>::TimeValue_t::const_iterator i = events->Begin ();
129           i != events->End ();
130           ++i)
131         {
132           AnimEvent * ev = i->second;
133           if (ev->m_type == AnimEvent::UPDATE_NODE_COUNTER_EVENT)
134             {
135               AnimNodeCounterUpdateEvent * updateEvent = static_cast<AnimNodeCounterUpdateEvent *> (ev);
136 
137               if (!isAllowedNode (updateEvent->m_nodeId))
138                 continue;
139               if (updateEvent->m_counterId != counterId)
140                 continue;
141               m_table->incrRowCount ();
142 
143               if (nodeTimes.find (updateEvent->m_nodeId) == nodeTimes.end ())
144                 {
145                   valueVector_t newVec;
146                   nodeTimes[updateEvent->m_nodeId] = newVec;
147                   nodeCounterValues[updateEvent->m_nodeId] = newVec;
148                 }
149               valueVector_t & timeVec = nodeTimes[updateEvent->m_nodeId];
150               timeVec.push_back (i->first);
151               maxTime = qMax (maxTime, i->first);
152               //NS_LOG_DEBUG ("TimeVec Count:" << timeVec.count());
153 
154               m_table->addCell (0, QString::number (i->first));
155               //NS_LOG_DEBUG ("T:" << i->first);
156               if (counterType == AnimNode::DOUBLE_COUNTER)
157                 {
158                   qreal value = updateEvent->m_counterValue;
159                   m_table->addCell (getIndexForNode (updateEvent->m_nodeId)+1, QString::number (value));
160                   //NS_LOG_DEBUG ("Val:" << value);
161                   valueVector_t & counterVec = nodeCounterValues[updateEvent->m_nodeId];
162                   counterVec.push_back (value);
163                   minCounter = qMin (minCounter, value);
164                   maxCounter = qMax (maxCounter, value);
165 
166 
167                 }
168               else if (counterType == AnimNode::UINT32_COUNTER)
169                 {
170                   uint32_t value = static_cast <uint32_t> (updateEvent->m_counterValue);
171                   m_table->addCell (getIndexForNode (updateEvent->m_nodeId)+1, QString::number (value));
172                   valueVector_t & counterVec = nodeCounterValues[updateEvent->m_nodeId];
173                   counterVec.push_back (value);
174                   minCounter = qMin (minCounter, (double) value);
175                   maxCounter = qMax (maxCounter, (double) value);
176                 }
177 
178             }
179         }
180       m_tableItem->setMinimumWidth (sceneRect ().width ());
181       m_tableItem->setMinimumHeight (sceneRect ().height ());
182       m_table->adjust ();
183 
184 
185           if (nodeTimes.empty ())
186             return;
187 
188           QVector<QCPScatterStyle::ScatterShape> shapes;
189           shapes << QCPScatterStyle::ssCross;
190           shapes << QCPScatterStyle::ssPlus;
191           shapes << QCPScatterStyle::ssCircle;
192           shapes << QCPScatterStyle::ssDisc;
193           shapes << QCPScatterStyle::ssSquare;
194           shapes << QCPScatterStyle::ssDiamond;
195           shapes << QCPScatterStyle::ssStar;
196           shapes << QCPScatterStyle::ssTriangle;
197           shapes << QCPScatterStyle::ssTriangleInverted;
198           shapes << QCPScatterStyle::ssCrossSquare;
199           shapes << QCPScatterStyle::ssPlusSquare;
200           shapes << QCPScatterStyle::ssCrossCircle;
201           shapes << QCPScatterStyle::ssPlusCircle;
202           shapes << QCPScatterStyle::ssPeace;
203           shapes << QCPScatterStyle::ssCustom;
204 
205 
206 
207           m_plot = new QCustomPlot;
208           m_plotItem = new QGraphicsProxyWidget;
209           m_plotItem->setWidget (m_plot);
210           addItem (m_plotItem);
211 
212           uint32_t chartIndex = 0;
213           QPen pen;
214           for (nodeValueMap_t::const_iterator i = nodeTimes.begin ();
215                i != nodeTimes.end ();
216                ++i)
217             {
218               m_plot->addGraph ()->setName ("Node "+ QString::number (i->first));
219               m_plot->graph (chartIndex)->setPen (pen);
220               m_plot->graph (chartIndex)->setScatterStyle (QCPScatterStyle(shapes.at (chartIndex % shapes.count ()), 10));
221               m_plot->graph (chartIndex)->setData (nodeTimes[i->first], nodeCounterValues[i->first]);
222               pen.setColor(QColor(sin(chartIndex*0.3)*100+100, sin(chartIndex*0.6+0.7)*100+100, sin(chartIndex*0.4+0.6)*100+100));
223 
224               //NS_LOG_DEBUG ("NodeTime Count:" << nodeTimes[0].count());
225               //NS_LOG_DEBUG ("NodeCounter Count:" << nodeCounterValues[0].count());
226               ++chartIndex;
227             }
228           m_plot->xAxis->setLabel("Time");
229           m_plot->yAxis->setLabel(m_currentCounterName);
230           m_plot->xAxis->setRange (0, maxTime);
231           m_plot->yAxis->setRange (minCounter, maxCounter);
232           m_plot->legend->setVisible (true);
233           m_plot->legend->setFont(QFont ("Helvetica",9));
234 
235 
236           //m_plot->setMinimumWidth(500);
237           //m_plot->setMinimumHeight(500);
238           QRectF viewRect = StatsView::getInstance ()->viewport ()->rect ();
239           viewRect.setWidth (viewRect.width () * 0.9);
240           m_plotItem->setMinimumWidth (viewRect.width ());
241           m_plotItem->setMinimumHeight (viewRect.height ());
242           m_tableItem->setVisible (!m_showChart);
243           m_plotItem->setVisible (m_showChart);
244 
245 }
246 
247 void
showChart(bool show)248 CounterTablesScene::showChart (bool show)
249 {
250   m_showChart = show;
251   m_tableItem->setVisible (!m_showChart);
252   m_plotItem->setVisible (m_showChart);
253 }
254 
255 void
setAllowedNodesVector(QVector<uint32_t> allowedNodes)256 CounterTablesScene::setAllowedNodesVector (QVector<uint32_t> allowedNodes)
257 {
258   m_allowedNodes = allowedNodes;
259 }
260 
261 }
262