Legend follows highlighted points
authorPetr Shevtsov <petr.shevtsov@gmail.com>
Wed, 30 Apr 2014 16:57:48 +0000 (20:57 +0400)
committerPetr Shevtsov <petr.shevtsov@gmail.com>
Wed, 30 Apr 2014 16:57:48 +0000 (20:57 +0400)
dygraph-options-reference.js
dygraph.js
plugins/legend.js
tests/customLabelFollow.html [new file with mode: 0644]

index 3ecc531..05988c4 100644 (file)
@@ -474,6 +474,12 @@ Dygraph.OPTIONS_REFERENCE =  // <JSON>
     "type": "string",
     "description": "When to display the legend. By default, it only appears when a user mouses over the chart. Set it to \"always\" to always display a legend of some sort."
   },
+  "legendFollow": {
+    "default": "false",
+    "labels": ["Legend"],
+    "type": "boolean",
+    "description": "Legend follows highlighted points"
+  },
   "labelsShowZeroValues": {
     "default": "true",
     "labels": ["Legend"],
index 56eea79..d95f9be 100644 (file)
@@ -288,6 +288,7 @@ Dygraph.DEFAULT_ATTRS = {
 
   // TODO(danvk): support 'onmouseover' and 'never', and remove synonyms.
   legend: 'onmouseover',  // the only relevant value at the moment is 'always'.
+  legendFollow: false,
 
   stepPlot: false,
   avoidMinZero: false,
index 2ff9398..b73e939 100644 (file)
@@ -128,11 +128,40 @@ legend.prototype.select = function(e) {
   var xValue = e.selectedX;
   var points = e.selectedPoints;
 
+  if(e.dygraph.getOption("legendFollow")) {
+    // create floating legend div
+    var area = e.dygraph.plotter_.area;
+    var labelsDivWidth = e.dygraph.getOption("labelsDivWidth");
+    var yAxisLabelWidth = e.dygraph.getOption("yAxisLabelWidth");
+    // determine floating [left, top] coordinates of the legend div
+    // within the plotter_ area
+    // offset 20 px to the left and down from the first selection point
+    // 20 px is guess based on mouse cursor size
+    var leftLegend = points[0].x * area.w + 20;
+    var topLegend  = points[0].y * area.h - 20;
+
+    // if legend floats to end of the plotting area, it flips to the other
+    // side of the selection point
+    if((leftLegend + labelsDivWidth + 1) > area.w) {
+      leftLegend = leftLegend - 2*20 - labelsDivWidth - (yAxisLabelWidth - area.x)
+    }
+
+    e.dygraph.graphDiv.appendChild(this.legend_div_);
+    this.legend_div_.style.left = yAxisLabelWidth + leftLegend + "px";
+    this.legend_div_.style.top = topLegend + "px";
+  }
+
   var html = generateLegendHTML(e.dygraph, xValue, points, this.one_em_width_);
   this.legend_div_.innerHTML = html;
 };
 
 legend.prototype.deselect = function(e) {
+
+  if(e.dygraph.getOption("legendFollow")) {
+    // return legend to the default non-floating position
+    this.predraw(e);
+  }
+
   // Have to do this every time, since styles might have changed.
   var oneEmWidth = calculateEmWidthInDiv(this.legend_div_);
   this.one_em_width_ = oneEmWidth;
diff --git a/tests/customLabelFollow.html b/tests/customLabelFollow.html
new file mode 100644 (file)
index 0000000..931e555
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
+    <title>Label styles</title>
+    <!--[if IE]>
+    <script type="text/javascript" src="../excanvas.js"></script>
+    <![endif]-->
+    <!--
+    For production (minified) code, use:
+    <script type="text/javascript" src="dygraph-combined.js"></script>
+    -->
+    <script type="text/javascript" src="../dygraph-dev.js"></script>
+
+    <script type="text/javascript" src="data.js"></script>
+  </head>
+  <body>
+    <p>Legend follows highlighted points:</p>
+    <div id="div_g14" style="width:600px; height:300px;"></div>
+
+    <script type="text/javascript">
+      g14 = new Dygraph(
+            document.getElementById("div_g14"),
+            NoisyData, {
+              rollPeriod: 14,
+              errorBars: true,
+              labelsDivWidth: 100,
+              labelsDivStyles: {
+                'backgroundColor': 'rgba(200, 200, 255, 0.75)',
+                'padding': '4px',
+                'border': '1px solid black',
+                'borderRadius': '10px',
+                'boxShadow': '4px 4px 4px #888',
+                'pointerEvents': 'none' // let mouse events fall through to the chart
+              },
+              labelsSeparateLines: true,
+              legendFollow: true,
+              yAxisLabelWidth: 20
+            }
+          );
+    </script>
+  </body>
+</html>