diff options
-rw-r--r-- | grapher/Graph.cxx | 18 | ||||
-rw-r--r-- | grapher/Graph.hxx | 2 | ||||
-rw-r--r-- | grapher/GraphData.hxx | 1 | ||||
-rw-r--r-- | grapher/GraphStyle.cxx | 26 | ||||
-rw-r--r-- | grapher/GraphStyle.hxx | 23 | ||||
-rw-r--r-- | grapher/GraphWidget.cxx | 27 | ||||
-rw-r--r-- | grapher/StapParser.cxx | 2 |
7 files changed, 73 insertions, 26 deletions
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<double>(_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<double> 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))); } } diff --git a/grapher/Graph.hxx b/grapher/Graph.hxx index e0e864d6..b9efb2a2 100644 --- a/grapher/Graph.hxx +++ b/grapher/Graph.hxx @@ -36,6 +36,8 @@ namespace systemtap bool _autoScaling; bool _autoScrolling; double _zoomFactor; + double _xOffset; + double _yOffset; std::tr1::shared_ptr<CairoPlayButton> _playButton; DatasetList& getDatasets() { return _datasets; } int64_t getTimeAtPoint(double x); diff --git a/grapher/GraphData.hxx b/grapher/GraphData.hxx index 9a267fc5..04f415f3 100644 --- a/grapher/GraphData.hxx +++ b/grapher/GraphData.hxx @@ -27,6 +27,7 @@ namespace systemtap } virtual std::string elementAsString(size_t element) = 0; // size of grid square at "normal" viewing + std::string name; double scale; double color[3]; GraphStyle* style; diff --git a/grapher/GraphStyle.cxx b/grapher/GraphStyle.cxx index 887ed55f..55fc73f4 100644 --- a/grapher/GraphStyle.cxx +++ b/grapher/GraphStyle.cxx @@ -8,6 +8,9 @@ namespace systemtap using namespace std; using namespace tr1; + typedef pair<GraphDataBase::TimeList::iterator, + GraphDataBase::TimeList::iterator> TimeListPair; + GraphStyleBar GraphStyleBar::instance; void GraphStyleBar::draw(std::tr1::shared_ptr<GraphDataBase> graphData, @@ -41,6 +44,29 @@ namespace systemtap } } + ssize_t GraphStyleBar::dataIndexAtPoint(double x, double y, + shared_ptr<GraphDataBase> graphData, + shared_ptr<Graph> graph) + { + shared_ptr<GraphData<double> > realData + = dynamic_pointer_cast<GraphData<double> >(graphData); + if (!realData) + return -1; + int64_t left, right; + double top, bottom; + graph->getExtents(left, right, top, bottom); + double t = graph->getTimeAtPoint(x); + TimeListPair range + = equal_range(graphData->times.begin(), graphData->times.end(), t); + size_t dataIndex = distance(graphData->times.begin(), range.first); + double val = realData->data[dataIndex]; + double ycoord = val * graph->_graphHeight / graphData->scale; + if (y >= graph->_yOffset + graph->_graphHeight - ycoord) + return static_cast<ssize_t>(dataIndex); + else + return -1; + } + GraphStyleDot GraphStyleDot::instance; void GraphStyleDot::draw(std::tr1::shared_ptr<GraphDataBase> graphData, diff --git a/grapher/GraphStyle.hxx b/grapher/GraphStyle.hxx index 4a0cd955..9625f451 100644 --- a/grapher/GraphStyle.hxx +++ b/grapher/GraphStyle.hxx @@ -14,29 +14,40 @@ namespace systemtap public: virtual void draw(std::tr1::shared_ptr<GraphDataBase> graphData, Graph* graph, Cairo::RefPtr<Cairo::Context> cr) = 0; + virtual ssize_t dataIndexAtPoint(double x, double y, + std::tr1::shared_ptr<GraphDataBase> + graphData, + std::tr1::shared_ptr<Graph> graph) + { + return -1; + } }; class GraphStyleBar : public GraphStyle { public: - virtual void draw(std::tr1::shared_ptr<GraphDataBase> graphData, - Graph* graph, Cairo::RefPtr<Cairo::Context> cr); + void draw(std::tr1::shared_ptr<GraphDataBase> graphData, + Graph* graph, Cairo::RefPtr<Cairo::Context> cr); + static GraphStyleBar instance; + ssize_t dataIndexAtPoint(double x, double y, + std::tr1::shared_ptr<GraphDataBase> graphData, + std::tr1::shared_ptr<Graph> graph); }; class GraphStyleDot : public GraphStyle { public: - virtual void draw(std::tr1::shared_ptr<GraphDataBase> graphData, - Graph* graph, Cairo::RefPtr<Cairo::Context> cr); + void draw(std::tr1::shared_ptr<GraphDataBase> graphData, + Graph* graph, Cairo::RefPtr<Cairo::Context> cr); static GraphStyleDot instance; }; class GraphStyleEvent : public GraphStyle { public: - virtual void draw(std::tr1::shared_ptr<GraphDataBase> graphData, - Graph* graph, Cairo::RefPtr<Cairo::Context> cr); + void draw(std::tr1::shared_ptr<GraphDataBase> graphData, + Graph* graph, Cairo::RefPtr<Cairo::Context> cr); static GraphStyleEvent instance; }; } diff --git a/grapher/GraphWidget.cxx b/grapher/GraphWidget.cxx index 9a203d87..9067988a 100644 --- a/grapher/GraphWidget.cxx +++ b/grapher/GraphWidget.cxx @@ -276,20 +276,23 @@ namespace systemtap if (!_hoverText) _hoverText = shared_ptr<CairoTextBox>(new CairoTextBox()); _hoverText->setOrigin(_mouseX + 5, _mouseY - 5); - int64_t t = g->getTimeAtPoint(_mouseX); Graph::DatasetList& dataSets = g->getDatasets(); - if (!dataSets.empty()) - { - shared_ptr<GraphDataBase> gdbase = dataSets[0]; - GraphDataBase::TimeList::iterator itime - = std::lower_bound(gdbase->times.begin(), gdbase->times.end(), t); - if (itime != gdbase->times.end()) { - size_t index = distance(gdbase->times.begin(), itime); - _hoverText->contents = gdbase->elementAsString(index); - _hoverText->setVisible(true); - queue_draw(); + for (Graph::DatasetList::reverse_iterator ritr = dataSets.rbegin(), + end = dataSets.rend(); + ritr != end; + ++ritr) + { + ssize_t index + = (*ritr)->style->dataIndexAtPoint(_mouseX, _mouseY, *ritr, g); + if (index >= 0) + { + _hoverText->contents = (*ritr)->name + + ": " + (*ritr)->elementAsString(index); + _hoverText->setVisible(true); + queue_draw(); + break; } - } + } } return false; } diff --git a/grapher/StapParser.cxx b/grapher/StapParser.cxx index af5f2d7d..6218e229 100644 --- a/grapher/StapParser.cxx +++ b/grapher/StapParser.cxx @@ -101,6 +101,7 @@ vector<string> commaSplit(const boost::sub_range<Glib::ustring>& range) { std::tr1::shared_ptr<GraphData<double> > dataSet(new GraphData<double>); + dataSet->name = setName; if (style == "dot") dataSet->style = &GraphStyleDot::instance; dataSet->color[0] = (hexColor >> 16) / 255.0; @@ -114,6 +115,7 @@ vector<string> commaSplit(const boost::sub_range<Glib::ustring>& range) { std::tr1::shared_ptr<GraphData<string> > dataSet(new GraphData<string>); + dataSet->name = setName; dataSet->style = &GraphStyleEvent::instance; dataSet->color[0] = (hexColor >> 16) / 255.0; dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; |