Tuesday, October 2, 2012

Tracking mouse position on your vertical, annotatable, jqPlot line chart

In my last post i showed you how to create a dynamically updating line chart using jqPlot library and how make the chart flip its orientation. This time i wanted to track the mouse position on the chart so i can put some annotations to the chart. It was possible to display annotations on the chart using the pointLabels plugin and some CSS tricks as the previous one. All i had to do was to add the annotations to the data array and make the pointLabels plugin display the content in the 3rd index of the data array as the point label.

   1: pointLabels: { 
   2:     show: true,
   3:     seriesLabelIndex: 2 
   4: }

This was working fine when the chart was in horizontal position. However when the chart was in vertical position the position of the mouse was not detected and as a result it was not possible to know which position in the chart should be annotated. I tried different methods, but was unable to find a solution. So i had to change the code in the library it self. I had to change the jquery.jqplot.js file, which is the core library file in order to achieve the result i expected. Here's what i did. First i had to insert the following code into the jqPlot class of the jquery.jqplot.js file.

   1: function jqPlot() {
   2:     //add the following code segment
   3:     var verticallyOriented = false;
   4:     this.setVertical = function(state){
   5:         verticallyOriented = state;
   6:     }
   7:     //don't change other code that isn't mentioned here
   9:     //now you have to change the logic in the getEventPosition function
  10:     //to make sure the new orientation is detected
  11:     function getEventPosition(ev) {
  12:         //change the line starting with var gridPos = ...
  13:         //to the following code segment
  14:         //depending on the orientation the event position calculating algorithm is changed
  15:         if(verticallyOriented){
  16:             var gridPos = {x:ev.pageY - go.top , y:plot.eventCanvas._elem.height() - ev.pageX + go.left};
  17:         } else {
  18:             var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top};
  19:         }
  20:         //no change to other code is needed
  21:     }
  22: }


Then when the chart was flipped i could simply call the setVertical() method so the library detects that it has been flipped.

   1: $("#flipbutton").click(function() {
   2:     if ($('#chart1').hasClass('vertical')) {
   3:         $("#chart1").removeClass("vertical");
   4:         plot1.setVertical(false);
   5:     } else {
   6:         $("#chart1").addClass("vertical");
   7:         plot1.setVertical(true);
   8:     }
   9:     plot1.replot();
  10: });


You can find a working example of the above work here. You can click on a point on the chart to add an annotation to that point. (try it out in both orientations)



If you have any problems/questions regarding this, please let me know in the comments.