Search code examples
javascripthtmlchartsgoogle-visualizationjinja2

overlapping bubbles with the same size and color in scatter google visualization


I'm drawing a google scatter(ScatterChart) plot and I have many bubbles with the same size , color , position which overlap. In google bubble chart , the overlapping bubbles automatically change color in order to notify user. But in scatter chart the top bubble's color is shown.

Note: I cant use bubble chart since I need customized tooltip.

Note: I cant use google scatter(Scatter) chart since I want to size the bubbles dynamically.

Any Idea how to solve this?

here is my code:

function drawChart() {

        var data = new google.visualization.DataTable();
            data.addColumn('number', 'Probabilità');
            data.addColumn('number', 'Impact Rate');
            data.addColumn({'type': 'string', 'role': 'style'} );
            data.addColumn({type:'string', role:'annotation'});
            data.addColumn({type: 'string', role: 'tooltip'});

            data.addRows([
            [3, 2, 'point {size: 10;fill-color:blue}', 'a','c'],[3,2,'point {size: 10;fill-color:blue}','b','d']
            ]);

        var options = {
            title: 'Rischio Finanziario',
            hAxis: {title: 'Probabilità', ticks: [0.5,1,1.5,2,2.5,3,3.5], textStyle:{color:'#999',bold:'1'}},
            vAxis: {title: 'Impact Rate', ticks: [0.5,1,1.5,2,2.5,3,3.5],textStyle:{color:'#999',bold:'1'}},

            height: 500,
            chartArea:{left:"10%",top:"10%",width:"80%",height:"80%"},
            legend: {position: 'none'},
            colorAxis: {legend: {position: 'none'}},
            bubble: {textStyle: {fontSize: 11}},
            animation:{easing:'in'},
        };

        if (data.getNumberOfRows() > 0) {
            var chart = new google.visualization.ScatterChart(document.getElementById('drawChart'));

            chart.draw(data, options);
        } else {
            document.getElementById('drawChart').innerHTML = '<div><h4 style="color: black;margin-top: 2rem;">Hello World</h4></div>No Data'
        }
    }

This is a simplified version. In reality I get data dynamically with jinja with a for loop


Solution

  • With scatter chart, you can change size of point with style role.

    you already have it defined correctly in the posted example.

    point {size: 10; fill-color:blue}
    

    if you want the points to be a different size,
    just change the size attribute.

    point {size: 20; fill-color:blue}
    

    see following working snippet...

    google.charts.load('current', {
      packages: ['corechart']
    }).then(drawChart);
    
    function drawChart() {
      var data = new google.visualization.DataTable();
      data.addColumn('number', 'Probabilità');
      data.addColumn('number', 'Impact Rate');
      data.addColumn({'type': 'string', 'role': 'style'} );
      data.addColumn({type:'string', role:'annotation'});
      data.addColumn({type: 'string', role: 'tooltip'});
    
      data.addRows([
        [3, 2, 'point {size: 20; fill-color: red}', 'a', 'c'],
        [3, 2, 'point {size: 10; fill-color: blue}', 'b', 'd']
      ]);
    
      var options = {
        title: 'Rischio Finanziario',
        hAxis: {title: 'Probabilità', ticks: [0.5,1,1.5,2,2.5,3,3.5], textStyle:{color:'#999',bold:'1'}},
        vAxis: {title: 'Impact Rate', ticks: [0.5,1,1.5,2,2.5,3,3.5],textStyle:{color:'#999',bold:'1'}},
        height: 500,
        chartArea:{left:"10%",top:"10%",width:"80%",height:"80%"},
        legend: {position: 'none'},
        colorAxis: {legend: {position: 'none'}},
        bubble: {textStyle: {fontSize: 11}},
        animation:{easing:'in'},
      };
    
      if (data.getNumberOfRows() > 0) {
        var chart = new google.visualization.ScatterChart(document.getElementById('drawChart'));
        chart.draw(data, options);
      } else {
        document.getElementById('drawChart').innerHTML = '<div><h4 style="color: black;margin-top: 2rem;">Hello World</h4></div>No Data'
      }
    }
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="drawChart"></div>


    if you want to deal with the overlapping annotations,
    you can use multiple series' or data table columns,
    then change the length of the annotation stem for each series.

    series: {
      0: {
        annotations: {
          stem: {
            length: 26
          }
        }
      },
      1: {
        annotations: {
          stem: {
            length: 12
          }
        }
      }
    },
    

    see following working snippet...

    google.charts.load('current', {
      packages: ['corechart']
    }).then(drawChart);
    
    function drawChart() {
      var data = new google.visualization.DataTable();
      data.addColumn('number', 'Probabilità');
      data.addColumn('number', 'Impact Rate');
      data.addColumn({'type': 'string', 'role': 'style'} );
      data.addColumn({type:'string', role:'annotation'});
      data.addColumn({type: 'string', role: 'tooltip'});
      data.addColumn('number', 'Impact Rate');
      data.addColumn({'type': 'string', 'role': 'style'} );
      data.addColumn({type:'string', role:'annotation'});
      data.addColumn({type: 'string', role: 'tooltip'});
    
      data.addRows([
        [3, 2, 'point {size: 20; fill-color: red}', 'a', 'c', null, null, null, null],
        [3, null, null, null, null, 2, 'point {size: 10; fill-color: blue}', 'b', 'd']
      ]);
    
      var options = {
        series: {
          0: {
            annotations: {
              stem: {
                length: 26
              }
            }
          },
          1: {
            annotations: {
              stem: {
                length: 12
              }
            }
          }
        },
        title: 'Rischio Finanziario',
        hAxis: {title: 'Probabilità', ticks: [0.5,1,1.5,2,2.5,3,3.5], textStyle:{color:'#999',bold:'1'}},
        vAxis: {title: 'Impact Rate', ticks: [0.5,1,1.5,2,2.5,3,3.5],textStyle:{color:'#999',bold:'1'}},
        height: 500,
        chartArea:{left:"10%",top:"10%",width:"80%",height:"80%"},
        legend: {position: 'none'},
        colorAxis: {legend: {position: 'none'}},
        bubble: {textStyle: {fontSize: 11}},
        animation:{easing:'in'},
      };
    
      if (data.getNumberOfRows() > 0) {
        var chart = new google.visualization.ScatterChart(document.getElementById('drawChart'));
        chart.draw(data, options);
      } else {
        document.getElementById('drawChart').innerHTML = '<div><h4 style="color: black;margin-top: 2rem;">Hello World</h4></div>No Data'
      }
    }
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="drawChart"></div>