0
votes

Google chart, I want to write some text at the right side of some points in the graph. How can I do that?

The chart has three different series Low, High, Multiple, A dashed line should be there which starts from "Low" value to "Multiple" value. X axis should have Ticks like PC#1, PC#2, PC#3 etc. Also each point should have its value at the right of it within the graph not as tool-tip. The graph should have three legends as we have three series "Low", "High", "Multiple".

Please click on this image link to understand my requirement

2

2 Answers

3
votes

you can place text next to a point on a chart using annotations

annotations are added using a data column, directly following the series column it should represent

see following working snippet...

google.charts.load('current', {
  callback: function () {
    drawVisualization();
    window.addEventListener('resize', drawVisualization, false);
  },
  packages:['corechart']
});
function drawVisualization() {
  var data = new google.visualization.DataTable();
  data.addColumn('number', 'x');
  data.addColumn('number', 'y');
  data.addColumn({type: 'string', role: 'annotation'});
  data.addRow([{v: 2, f: ''}, 0.8, '0.8x']);
  data.addRow([{v: 2, f: ''}, 7.4, '7.4x']);
  data.addRow([{v: 2, f: ''}, 12.2, '12.2x']);

  var container = document.getElementById('visualization');
  var chart = new google.visualization.ScatterChart(container);

  chart.draw(data, {
    hAxis: {
      ticks: [
        {v: 0, f: ''},
        {v: 1, f: ''},
        {v: 2, f: ''},
        {v: 3, f: ''},
        {v: 4, f: ''}
      ]
    }
  });
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="visualization"></div>

by default, annotations are placed above the point, as seen in the above snippet

and there are no standard options available to move the annotation left or right

only up or down using --> annotations.stem.length

in order to set the text to the right of the point,
the text needs to be moved manually,
when the 'ready' event fires on the chart

see following working snippet...

the annotations will be added as text elements to the svg

when the ready event fires, the annotation text elements are found,
and the 'x' attribute is changed, to move the text to the right

annotations.stem.length is used to bring the text down to the same height as the point

google.charts.load('current', {
  callback: function () {
    drawVisualization();
    window.addEventListener('resize', drawVisualization, false);
  },
  packages:['corechart']
});
function drawVisualization() {
  var data = new google.visualization.DataTable();
  data.addColumn('number', 'x');
  data.addColumn('number', 'y');
  data.addColumn({type: 'string', role: 'annotation'});
  data.addRow([{v: 2, f: ''}, 0.8, '0.8x']);
  data.addRow([{v: 2, f: ''}, 7.4, '7.4x']);
  data.addRow([{v: 2, f: ''}, 12.2, '12.2x']);

  var container = document.getElementById('visualization');
  var chart = new google.visualization.ScatterChart(container);

  google.visualization.events.addOneTimeListener(chart, 'ready', function () {
    Array.prototype.forEach.call(container.getElementsByTagName('text'), function (text, index) {
      if (text.getAttribute('text-anchor') === 'middle') {
        text.setAttribute('x', parseFloat(text.getAttribute('x')) + 20);
      }
    });
  });

  chart.draw(data, {
    annotations: {
      stem: {
        length: -5
      }
    },
    hAxis: {
      ticks: [
        {v: 0, f: ''},
        {v: 1, f: ''},
        {v: 2, f: ''},
        {v: 3, f: ''},
        {v: 4, f: ''}
      ]
    }
  });
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="visualization"></div>

however, you will notice in the above snippet,
when you hover over one of the points,
the chart will set the text back to the original 'x' position

this can be prevented by turning off interactivity using the following option...
enableInteractivity: false

but if you would like to keep interactivity,
you'll need to reset the 'x' position anytime an event occurs

this can be accomplished by using a MutationObserver

see following working snippet...

when the 'ready' event fires, the new 'x' position is calculated for each text element

then the MutationObserver is used to reset the position,
anytime interactivity occurs...

google.charts.load('current', {
  callback: function () {
    drawVisualization();
    window.addEventListener('resize', drawVisualization, false);
  },
  packages:['corechart']
});
function drawVisualization() {
  var data = new google.visualization.DataTable();
  data.addColumn('number', 'x');
  data.addColumn('number', 'y');
  data.addColumn({type: 'string', role: 'annotation'});
  data.addRow([{v: 2, f: ''}, 0.8, '0.8x']);
  data.addRow([{v: 2, f: ''}, 7.4, '7.4x']);
  data.addRow([{v: 2, f: ''}, 12.2, '12.2x']);

  var container = document.getElementById('visualization');
  var chart = new google.visualization.ScatterChart(container);

  var annotations = {};
  google.visualization.events.addOneTimeListener(chart, 'ready', function () {
    Array.prototype.forEach.call(container.getElementsByTagName('text'), function (text, index) {
      if (text.getAttribute('text-anchor') === 'middle') {
        annotations[index] = parseFloat(text.getAttribute('x')) + 20;
      }
    });

    var observer = new MutationObserver(function () {
      Array.prototype.forEach.call(container.getElementsByTagName('text'), function (text, index) {
        if (text.getAttribute('text-anchor') === 'middle') {
          text.setAttribute('x', annotations[index]);
        }
      });
    });
    observer.observe(container, {
      childList: true,
      subtree: true
    });
  });

  chart.draw(data, {
    annotations: {
      stem: {
        length: -5
      }
    },
    hAxis: {
      ticks: [
        {v: 0, f: ''},
        {v: 1, f: ''},
        {v: 2, f: ''},
        {v: 3, f: ''},
        {v: 4, f: ''}
      ]
    }
  });
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="visualization"></div>
0
votes
I am able to draw the chart as per my requirement. Please see below fiddle
for your reference:
[Fiddlle link][1]
[1]: https://jsfiddle.net/sainirohit77/5xb68cfw/

The only problem which I can see would arise when the data points are very 
close to each other than the annotation text eg. 2.0x, 7.0x will overlap each 
other.