From 572a176d481c329b370ce52e7bec1a49ed76c225 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 1 Dec 2009 12:02:24 +0100 Subject: change time type from double to int64_t * grapher/Graph.hxx (Graph): Change variables holding the time limits of the displayed graph from double to int64_t. * grapher/Graph.cxx (Graph::draw): Do calculations of time differences using int64_t. (Graph::getExtents, Graph::setExtents): Change left and right arguments to int64_t. * grapher/GraphData.hxx (GraphDataBase): Change time type to int64_t. (GraphDataBase::elementAsString): New function. (GraphData::elementAsString): Implementation of that function. * grapher/StapParser.cxx (parseData): Parse time values from the stap script as 64 bit values. --- grapher/Graph.cxx | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'grapher/Graph.cxx') diff --git a/grapher/Graph.cxx b/grapher/Graph.cxx index a7fe6fcf..e9aacd55 100644 --- a/grapher/Graph.cxx +++ b/grapher/Graph.cxx @@ -30,7 +30,7 @@ namespace systemtap // line separation int linesPossible = (int)(_graphWidth / (_lineWidth + 2.0)); // Find latest time. - double latestTime = 0.0; + int64_t latestTime = 0; for (DatasetList::iterator ditr = _datasets.begin(), de = _datasets.end(); ditr != de; @@ -38,13 +38,13 @@ namespace systemtap { if (!(*ditr)->times.empty()) { - double lastDataTime = (*ditr)->times.back(); + int64_t lastDataTime = (*ditr)->times.back(); if (lastDataTime > latestTime) latestTime = lastDataTime; } } - double minDiff = 0.0; - double maxTotal = 0.0; + int64_t minDiff = 0; + int64_t maxTotal = 0; for (DatasetList::iterator ditr = _datasets.begin(), de = _datasets.end(); ditr != de; @@ -59,11 +59,11 @@ namespace systemtap ritr + 1 != gtimes.rend(); ritr++) { - double timeDiff = *ritr - *(ritr + 1); + int64_t timeDiff = *ritr - *(ritr + 1); if (timeDiff < minDiff || (timeDiff != 0 && minDiff == 0)) minDiff = timeDiff; if (minDiff != 0 - && (totalDiff + timeDiff) / minDiff > linesPossible) + && ((totalDiff + timeDiff) / minDiff + 1) > linesPossible) break; totalDiff += timeDiff; } @@ -75,10 +75,11 @@ namespace systemtap if (maxTotal != 0) _left = latestTime - maxTotal; else - _left = _right - 1.0; + _left = _right - 1; } cr->save(); - double horizScale = _zoomFactor * _graphWidth / ( _right - _left); + double horizScale + = _zoomFactor * _graphWidth / static_cast(_right - _left); cr->translate(20.0, 0.0); cr->set_line_width(_lineWidth); @@ -186,9 +187,10 @@ namespace systemtap } cr->restore(); // Draw axes - double diff = _right - _left; - double majorUnit = pow(10.0, floor(log(diff) / log(10.0))); - double startTime = ceil(_left / majorUnit) * majorUnit; + double diff = static_cast(_right - _left); + int64_t majorUnit + = static_cast(pow(10.0, floor(log(diff) / log(10.0)))); + int64_t startTime = (_left / majorUnit) * majorUnit; cr->save(); cr->set_source_rgba(1.0, 1.0, 1.0, .9); cr->set_line_cap(Cairo::LINE_CAP_BUTT); @@ -205,14 +207,14 @@ namespace systemtap dash[0] = _graphHeight / 10; cr->set_dash(dash, 0); double prevTextAdvance = 0; - for (double tickVal = startTime; tickVal <= _right; tickVal += majorUnit) + for (int64_t tickVal = startTime; tickVal <= _right; tickVal += majorUnit) { double x = (tickVal - _left) * horizScale + 20.0; cr->move_to(x, 0.0); cr->line_to(x, _graphHeight); cr->move_to(x, _graphHeight - 5); std::ostringstream stream; - stream << std::fixed << std::setprecision(0) << tickVal; + stream << tickVal; Cairo::TextExtents extents; cr->get_text_extents(stream.str(), extents); // Room for this label? @@ -239,7 +241,7 @@ namespace systemtap _datasets.push_back(data); } - void Graph::getExtents(double& left, double& right, double& top, + void Graph::getExtents(int64_t& left, int64_t& right, double& top, double& bottom) const { left = _left; @@ -248,7 +250,7 @@ namespace systemtap bottom = _bottom; } - void Graph::setExtents(double left, double right, double top, double bottom) + void Graph::setExtents(int64_t left, int64_t right, double top, double bottom) { _left = left; _right = right; @@ -260,4 +262,9 @@ namespace systemtap { return x >= _x0 && x < _x0 + _width && y >= _y0 && y < _y0 + _height; } + + int64_t Graph::getTimeAtPoint(double x) + { + return _left + (_right - _left) * ((x - 20.0)/_graphWidth); + } } -- cgit From d293d53136fa7e6e7eda510847145edf4d3d7f55 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 1 Dec 2009 12:26:59 +0100 Subject: Add hover text to the graph. When the graph display is paused, leaving the mouse stationary over the graph will display the data point under the pointer. * grapher/CairoWidget.hxx (CairoTextBox): new class (CairoWidget, CairoPlayButton): refector some play button-specific things from CairoWidget to CairoPlayButton. * grapher/CairoWidget.cxx (CairoTextBox::draw): new function. * grapher/GraphWidget.hxx (GraphWidget): new members for supporting hover text. * grapher/GraphWidget.cxx (on_motion_notify_event): Set up hover text box. (establishHoverTimeout, onHoverTimeout, getGraphUnderPoint): new functions. --- grapher/Graph.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'grapher/Graph.cxx') diff --git a/grapher/Graph.cxx b/grapher/Graph.cxx index e9aacd55..61b7e55c 100644 --- a/grapher/Graph.cxx +++ b/grapher/Graph.cxx @@ -14,7 +14,7 @@ namespace systemtap _graphWidth(580), _graphHeight(180), _lineWidth(2), _autoScaling(true), _autoScrolling(true), _zoomFactor(1.0), _playButton(new CairoPlayButton), - _left(0.0), _right(1.0), _top(5.0), _bottom(0.0) + _left(0), _right(1), _top(5.0), _bottom(0.0) { setOrigin(x, y); _graphX = x; -- cgit From 0e8394b016a039931a338fd59e103346a50f5329 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 1 Dec 2009 12:54:25 +0100 Subject: some aesthetic tweaks to the grapher * grapher/Graph.cxx (draw): Draw tick labels (times) below the graph. * grapher/grapher.cxx (main): Open main window with a size big enough to display an entire graph. --- grapher/Graph.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'grapher/Graph.cxx') diff --git a/grapher/Graph.cxx b/grapher/Graph.cxx index 61b7e55c..1d478790 100644 --- a/grapher/Graph.cxx +++ b/grapher/Graph.cxx @@ -212,7 +212,6 @@ namespace systemtap double x = (tickVal - _left) * horizScale + 20.0; cr->move_to(x, 0.0); cr->line_to(x, _graphHeight); - cr->move_to(x, _graphHeight - 5); std::ostringstream stream; stream << tickVal; Cairo::TextExtents extents; @@ -220,6 +219,7 @@ namespace systemtap // Room for this label? if (x + extents.x_bearing > prevTextAdvance) { + cr->move_to(x, _graphHeight + 5 + extents.height); cr->show_text(stream.str()); prevTextAdvance = x + extents.x_advance; } -- cgit From 06e217d9990635be43a59233d75c504385d1e243 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 1 Dec 2009 13:34:12 +0100 Subject: Account for zoom factor when choosing hover text * grapher/Graph.cxx (getTimeAtPoint): Divide by _zoomFactor too. --- grapher/Graph.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'grapher/Graph.cxx') diff --git a/grapher/Graph.cxx b/grapher/Graph.cxx index 1d478790..e7c03bd1 100644 --- a/grapher/Graph.cxx +++ b/grapher/Graph.cxx @@ -96,11 +96,11 @@ namespace systemtap cr->translate(0.0, _graphHeight); cr->scale(1.0, -1.0); GraphDataBase::TimeList::iterator lower - = std::lower_bound(graphData->times.begin(), graphData->times.end(), - _left); + = lower_bound(graphData->times.begin(), graphData->times.end(), + _left); GraphDataBase::TimeList::iterator upper - = std::upper_bound(graphData->times.begin(), graphData->times.end(), - _right); + = upper_bound(graphData->times.begin(), graphData->times.end(), + _right); // event bar if (graphData->style == GraphDataBase::EVENT) { @@ -265,6 +265,6 @@ namespace systemtap int64_t Graph::getTimeAtPoint(double x) { - return _left + (_right - _left) * ((x - 20.0)/_graphWidth); + return _left + (_right - _left) * ((x - 20.0)/(_zoomFactor * _graphWidth)); } } -- cgit From 6197b0dc80c4f87000d26213293fe2cb72fbe081 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 1 Dec 2009 19:05:09 +0100 Subject: Refactor drawing of different styles of graph into classes * grapher/GraphStyle.cxx: New file * grapher/GraphStyle.hxx: New file * grapher/Graph(draw): Move much drawing code to GraphStyle::draw --- grapher/Graph.cxx | 66 +------------------------------------------------------ 1 file changed, 1 insertion(+), 65 deletions(-) (limited to 'grapher/Graph.cxx') diff --git a/grapher/Graph.cxx b/grapher/Graph.cxx index e7c03bd1..4b5b8eb6 100644 --- a/grapher/Graph.cxx +++ b/grapher/Graph.cxx @@ -88,74 +88,10 @@ namespace systemtap ++itr) { shared_ptr graphData = *itr; - shared_ptr > realData - = dynamic_pointer_cast >(*itr); - shared_ptr > stringData - = dynamic_pointer_cast >(*itr); cr->save(); cr->translate(0.0, _graphHeight); cr->scale(1.0, -1.0); - GraphDataBase::TimeList::iterator lower - = lower_bound(graphData->times.begin(), graphData->times.end(), - _left); - GraphDataBase::TimeList::iterator upper - = upper_bound(graphData->times.begin(), graphData->times.end(), - _right); - // event bar - if (graphData->style == GraphDataBase::EVENT) - { - double eventHeight = _graphHeight * (graphData->scale / 100.0); - cr->save(); - cr->set_line_width(3 * _lineWidth); - cr->set_source_rgba(graphData->color[0], graphData->color[1], - graphData->color[2], .33); - cr->move_to(0, eventHeight); - cr->line_to(_graphWidth, eventHeight); - cr->stroke(); - cr->restore(); - } - for (GraphDataBase::TimeList::iterator ditr = lower, de = upper; - ditr != de; - ++ditr) - { - size_t dataIndex = ditr - graphData->times.begin(); - cr->set_source_rgba(graphData->color[0], graphData->color[1], - graphData->color[2], 1.0); - if (graphData->style == GraphDataBase::BAR && realData) - { - cr->move_to((*ditr - _left) * horizScale, 0); - cr->line_to((*ditr - _left) * horizScale, - realData->data[dataIndex] * _graphHeight - / graphData->scale); - cr->stroke(); - } - else if (graphData->style == GraphDataBase::DOT && realData) - { - cr->arc((*ditr - _left) * horizScale, - realData->data[dataIndex] * _graphHeight / graphData->scale, - _lineWidth / 2.0, 0.0, M_PI * 2.0); - cr->fill(); - } - else if (graphData->style == GraphDataBase::EVENT && stringData) - { - double eventHeight = _graphHeight * (graphData->scale / 100.0); - cr->save(); - cr->select_font_face("Sans", Cairo::FONT_SLANT_NORMAL, - Cairo::FONT_WEIGHT_NORMAL); - cr->set_font_size(12.0); - cr->save(); - cr->scale(1.0, -1.0); - cr->move_to((*ditr - _left) * horizScale, - -eventHeight -3.0 * _lineWidth - 2.0); - cr->show_text(stringData->data[dataIndex]); - cr->restore(); - cr->rectangle((*ditr - _left) * horizScale - 1.5 * _lineWidth, - eventHeight - 1.5 * _lineWidth, - 3.0 * _lineWidth, 3.0 * _lineWidth); - cr->fill(); - cr->restore(); - } - } + graphData->style->draw(graphData, this, cr); cr->restore(); cr->save(); cr->select_font_face("Sans", Cairo::FONT_SLANT_NORMAL, -- cgit From c10fce7d6aaa57a4f94f9d7aeea906597456f7ce Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 2 Dec 2009 19:27:07 +0100 Subject: Make the hover text conform to data displayed. Start of code to be more selective about the association between the hover text and the underling graph. Also, show the data set name in hover text. * grapher/GraphStyle.hxx (dataIndexAtPoint): New virtual function. * grapher/GraphStyle.cxx (dataIndexAtPoint): Implementation for bar graphs * grapher/GraphWidget.cxx (onHoverTimeout): Use dataIndexAtPoint. --- grapher/Graph.cxx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'grapher/Graph.cxx') diff --git a/grapher/Graph.cxx b/grapher/Graph.cxx index 4b5b8eb6..55ffcdf2 100644 --- a/grapher/Graph.cxx +++ b/grapher/Graph.cxx @@ -13,7 +13,8 @@ namespace systemtap : _width(600), _height(200), _graphX(0), _graphY(0), _graphWidth(580), _graphHeight(180), _lineWidth(2), _autoScaling(true), _autoScrolling(true), - _zoomFactor(1.0), _playButton(new CairoPlayButton), + _zoomFactor(1.0), _xOffset(20.0), _yOffset(0.0), + _playButton(new CairoPlayButton), _left(0), _right(1), _top(5.0), _bottom(0.0) { setOrigin(x, y); @@ -80,7 +81,7 @@ namespace systemtap cr->save(); double horizScale = _zoomFactor * _graphWidth / static_cast(_right - _left); - cr->translate(20.0, 0.0); + cr->translate(_xOffset, _yOffset); cr->set_line_width(_lineWidth); for (DatasetList::iterator itr = _datasets.begin(), e = _datasets.end(); @@ -134,9 +135,9 @@ namespace systemtap cr->select_font_face("Sans", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL); cr->set_font_size(10.0); - cr->move_to(20.0, 0.0); - cr->line_to(20.0, _height); - cr->move_to(20.0, _graphHeight); + cr->move_to(_xOffset, _yOffset); + cr->line_to(_xOffset, _height); + cr->move_to(_xOffset, _graphHeight); cr->line_to(_graphWidth, _graphHeight); cr->stroke(); std::valarray dash(1); @@ -145,8 +146,8 @@ namespace systemtap double prevTextAdvance = 0; for (int64_t tickVal = startTime; tickVal <= _right; tickVal += majorUnit) { - double x = (tickVal - _left) * horizScale + 20.0; - cr->move_to(x, 0.0); + double x = (tickVal - _left) * horizScale + _xOffset; + cr->move_to(x, _yOffset); cr->line_to(x, _graphHeight); std::ostringstream stream; stream << tickVal; @@ -201,6 +202,7 @@ namespace systemtap int64_t Graph::getTimeAtPoint(double x) { - return _left + (_right - _left) * ((x - 20.0)/(_zoomFactor * _graphWidth)); + return (_left + + (_right - _left) * ((x - _xOffset)/(_zoomFactor * _graphWidth))); } } -- cgit