javascript - 如何在 Google 图表上定位十字线?

标签 javascript google-visualization

下面的代码适用于 Google 面积图。

当前,当鼠标在图表上移动时,十字准线位于数据点的顶部。如何偏移十字准线的 x 和 y 位置,以便它们可以位于垂直数据点之间的中间位置。

<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {

        var chartData = 
            [
                ['Year', 'Fees', 'Invest', 'Other', 'More'],
            ];

        var year = 2013;
        var col1 = 50;
        var col2 = 100;
        var col3 = 200;
        var col4 = 100;

        var years = 30;

        for (x = 1; x <= years; x++) {

            chartData.push([year.toString(), Number(col1), Number(col2), Number(col3), Number(col4)]);   
            year++;
            col1 = col1 + (col1 * 0.03);
            col2 = col2 + (col2 * 0.02);
            col3 = col3 + (col3 * 0.05);
            col4 = col4 + (col3 * 0.02);

        }

        var data = google.visualization.arrayToDataTable(chartData);

        var options = {
          title: 'Mouseover chart',
          hAxis: {title: 'Year',  titleTextStyle: {color: '#333'}},
          vAxis: {minValue: 0},
          isStacked: true,
          tooltip:{trigger:'selection'}, 


           crosshair: { trigger: 'both' },
          series: {
            0: { color: '#ffffff' },
            1: { color: '#aca789' },
            2: { color: '#627b15' },
            3: { color: '#96ac4b' },
          }

        };

        var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
        chart.draw(data, options);

        google.visualization.events.addListener(chart, 'onmouseover', function (e) {
            var xValue = data.getValue (e.row, 0);
             chart.setSelection([e]);

            console.log("Mouse over = " + xValue);
        });

      }
    </script>
  </head>
  <body>
    <div id="chart_div" style="width: 900px; height: 500px;"></div>
  </body>
</html>

最佳答案

有办法做到这一点,但我确信有更好的方法。

下面的 HTML 代码使用两个一像素宽的 div 作为十字线。十字线在两组数据点之间移动一半。您还可以将鼠标移动到图表区域的任意位置,十字准线水平移动。

运行代码时,原始 Google 十字线显示为绿色,使用此程序创建的十字线显示为红色。

  google.load("visualization", "1", {
    packages: ["corechart"]
  });
  google.setOnLoadCallback(drawChart);

  var mouseX, mouseY; // Screen mouse position
  var chart; // Google chart object
  var period; // Number or years (horizontal axis divisions)
  var chartData; // Data plotted on chart
  var highestValue; // Highest value displayed on chart

  $(document).mousemove(function(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;

    var divisionSize = 0; // Size of space between horizontal tick marks

    // Get position of whole chart (Includes axis and labels)
    var p = $("#chart_div");
    var offset = p.offset();

    var chartPositionLeft = Number(offset.left);
    var chartPositionTop = Number(offset.top);
    var chartPositionHeight = Number(offset.height);
    var chartPositionWidth = Number(offset.width);

    var cli = chart.getChartLayoutInterface();

    // Get chart dwawing area (Without axis and labels);
    var drawAreaLeft = Number(cli.getChartAreaBoundingBox().left);
    var drawAreaTop = Number(cli.getChartAreaBoundingBox().top);
    var drawAreaHeight = Number(cli.getChartAreaBoundingBox().height);
    var drawAreaWidth = Number(cli.getChartAreaBoundingBox().width);

    var left = chartPositionLeft + drawAreaLeft;
    var right = chartPositionLeft + drawAreaLeft + drawAreaWidth;
    var top = chartPositionTop + drawAreaTop;
    var bottom = chartPositionTop + drawAreaTop + drawAreaHeight;
    var height = bottom - top;

    if (period > 0) {
      divisionSize = (right - left) / period;
    }

    // Is mouse pointer inside chart area 
    if (mouseX >= left & mouseX <= right & mouseY >= top & mouseY <= bottom) {

      // Mouse position releated to tick marks on chart and data in array
      var chartPosX = Math.round((mouseX - left) / divisionSize);
      var dataAtX = chartData[chartPosX][1] + chartData[chartPosX][2] +
        chartData[chartPosX][3] + chartData[chartPosX][4];

      console.log("Position on chart = " + chartPosX);

      console.log("Chart data at position 0 = " + chartData[chartPosX][0]);
      console.log("Chart data at position 1 = " + chartData[chartPosX][1]);
      console.log("Chart data at position 2 = " + chartData[chartPosX][2]);
      console.log("Chart data at position 3 = " + chartData[chartPosX][3]);
      console.log("Chart data at position 4 = " + chartData[chartPosX][4]);

      var total = chartData[chartPosX][1] + chartData[chartPosX][2] + Math.round(chartData[chartPosX][3] / 2);

      console.log("Chart total = " + total);


      console.log("Highest value = " + highestValue);
      var horizontalCrosshair = top + height - ((total / highestValue) * height);

      console.log("Draw area top = " + drawAreaTop);
      console.log("Horizontal crosshair = " + horizontalCrosshair);
      console.log("Draw area height = " + drawAreaHeight);
      console.log("Draw area bottom = " + bottom);

      // Move horizontal crosshairs
      $('#crosshairDivHorizontal')
        .css('visibility', 'visible')
        .offset({
          'top': top,
          'left': mouseX
        })
        .height(drawAreaHeight);

      $('#crosshairDivVertical')
        .css('visibility', 'visible')
        .offset({
          'top': horizontalCrosshair,
          'left': left
        })
        .width(right - left);


    }

  }).mouseover(); // call the handler immediately


  function drawChart() {

    highestValue = 1;

    chartData = [
      ['Year', 'Fees', 'Invest', 'Other', 'More'],
    ];

    var year = 2013;
    var col1 = 50;
    var col2 = 100;
    var col3 = 200;
    var col4 = 100;

    period = 30;
    var years = 30;


    for (x = 1; x <= years; x++) {

      chartData.push([year.toString(), Number(col1), Number(col2), Number(col3), Number(col4)]);
      year++;
      col1 = col1 + (col1 * 0.03);
      col2 = col2 + (col2 * 0.02);
      col3 = col3 + (col3 * 0.05);
      col4 = col4 + (col3 * 0.02);

      var total = col1 + col2 + col3 + col4;
      if (total > highestValue) {
        highestValue = total;
      }

    }

    // Custom tick marks on chart (Replace if you find a way to read defaults marks)
    var tick = Math.round(highestValue / 5);
    var ticks = [0, tick, tick * 1, tick * 2, tick * 3, tick * 4, tick * 5];

    var data = google.visualization.arrayToDataTable(chartData);

    var options = {
      title: 'Mouseover chart',
      hAxis: {
        title: 'Year',
        titleTextStyle: {
          color: '#333'
        }
      },
      vAxis: {
        minValue: 0,
        ticks: ticks
      },
      isStacked: true,
      tooltip: {
        trigger: 'selection'
      },

      crosshair: {
        trigger: 'both'
      },
      series: {
        0: {
          color: '#ffffff'
        },
        1: {
          color: '#aca789'
        },
        2: {
          color: '#627b15'
        },
        3: {
          color: '#96ac4b'
        },
      }
    };

    chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
    chart.draw(data, options);

    google.visualization.events.addListener(chart, 'onmouseover', function(e) {
      // Not used					
    });

  }
/* Div is moved in the horizontal direction across the screen */

#crosshairDivHorizontal {
  border-left: 1px solid red;
  width: 1px;
  height: 1px;
  z-index: 999;
  visibility: hidden;
}
/* Div is moveded in the vertical direction across the screen */

#crosshairDivVertical {
  border-bottom: 1px solid red;
  height: 1px;
  width: 1px;
  z-index: 998;
  visibility: hidden;
}
#chart_div {
  z-index: 0;
}
<html>

<head>


  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/themes/smoothness/jquery-ui.css" />
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>

  <script type="text/javascript" src="https://www.google.com/jsapi"></script>

  <link rel="stylesheet" type="text/css" href="chart.css">
  <script src="chart.js"></script>

</head>


<body>


  <div id="crosshairDivVertical"></div>
  <div id="crosshairDivHorizontal"></div>
  <div id="chart_div" style="width: 900px; height: 500px;"></div>


</body>

</html>

关于javascript - 如何在 Google 图表上定位十字线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26069829/

相关文章:

javascript - 考虑到提供的 JSON,ColumnChart 将月份移动到 x 轴

javascript - 谷歌图表 : points on line graph not showing

javascript - OpenLayers 2 : Unexpected results from Point. 距离()

javascript - 我可以使用串联的 var+array_value 作为 jquery 中的选择器,即 $ ("#var+array_value")

javascript - 禁用回车键 Chrome 扩展程序

java - 谷歌图表和 Java

javascript - 如何使用javascript创建不允许空格的文本框

javascript - 返回之前等待子函数执行

pdf - 如何以pdf格式导出谷歌图表?

javascript - 如何更改 Google Charts API 中堆叠条形图的部分颜色?