javascriptcsschartsgoogle-visualization

How to make the Google column chart tool tip to appear right above the column where mouse is pointed


In the Google column chart the tooltip appears towards the right of the column where mouse is pointed. How can this be changed so that it appears right above the column.

In the code, options are

var options = {
        title: "Spending - Last 7 days",
        backgroundColor: "#FFFAF5",
        width: width,
        height: height,
        chartArea: { left: "5%", right: "5%", top: "25%", bottom: "10%" },
        bar: { groupWidth: "68%" },
        titleTextStyle: {
          color: "#382314",
          fontName: "DM Sans",
          fontSize: 24,
        },
        tooltip: { isHtml: true },
        allowHtml: true,
        vAxis: {
          textPosition: "none",
          baselineColor: "none",
          gridlines: { count: 0 },
        },
        hAxis: {
          textStyle: { color: "#93867B", fontName: "DM Sans" },
        },
        legend: { position: "none" },
        colors: [chartColor],
      };

CSS for tooltip is:

.google-visualization-tooltip {
        color: white !important;
        background-color: rgb(11, 11, 11) !important;
        font-family: "DM Sans", sans-serif !important;
        border-radius: 18% !important;
        padding: 0.3% 0.3% 0.3% 0.3% !important;
        align-content: center !important;

        border: none !important;

        z-index: +1;
      }

I tried implmenting the solution suggested in How does google-visualization-tooltip calculate the left and top values?. But it didn't work. The chart didn't come up. I didn't try debussing it since I was not sure if that solution works in my case.

Now it shows like this

Current Result

and this is what is expected.

Expected Result


Solution

  • The answer you reference draws a line chart, whereas you are working with a column chart.

    as such, you need to change the following line, from "point#" to "bar#"

          var pointBounds = chartLayout.getBoundingBox(
            "bar#" + (sender.column - 1) + "#" + sender.row
          );
    

    see following working snippet...

    google.charts.load('current', {
      packages: ['corechart']
    }).then(fetchJSONData);
    
    function fetchJSONData() {
          var datavis = google.visualization.arrayToDataTable([
           ["Country", "Mhl", { role: "tooltip", p: { html: true } }],
           ["Italy", 54.8, "54.8T"],
           ["France", 48.6, "54.8T"],
           ["Spain", 44.4, "54.8T"],
           ["USA", 23.9, "54.8T"],
           ["Argentina", 14.5, "54.8T"],
          ]);
    
          // Set Options
          var width = 0.3 * window.innerWidth;
          var height = 0.4 * window.innerHeight;
          var chartColor = "#ec775f";
          var options = {
            title: "Spending - Last 7 days",
            backgroundColor: "#FFFAF5",
            width: width,
            height: height,
            chartArea: { left: "5%", right: "5%", top: "25%", bottom: "10%" },
            bar: { groupWidth: "68%" },
            titleTextStyle: {
              color: "#382314",
              fontName: "DM Sans",
              fontSize: 24,
            },
            tooltip: { isHtml: true },
            allowHtml: true,
            vAxis: {
              textPosition: "none",
              baselineColor: "none",
              gridlines: { count: 0 },
            },
            hAxis: {
              textStyle: { color: "#93867B", fontName: "DM Sans" },
            },
            legend: { position: "none" },
            colors: [chartColor],
          };
    
          // Draw
    
          var container = document.getElementById("columnchart_material");
          var chart = new google.visualization.ColumnChart(container);
    
          google.visualization.events.addListener(
            chart,
            "ready",
            changeBorderRadius
          );
    
          google.visualization.events.addListener(
            chart,
            "select",
            changeBorderRadius
          );
          google.visualization.events.addListener(
            chart,
            "onmouseover",
            chartMouseOver
          );
          google.visualization.events.addListener(
            chart,
            "onmouseout",
            chartMouseOut
          );
          chart.clearChart();
          chart.draw(datavis, options);
    
          //window.addEventListener("resize", fetchJSONData, false);
    
          function changeBorderRadius() {
            chartColumns = container.getElementsByTagName("rect");
            //console.log("chart column" + chartColumns);
            Array.prototype.forEach.call(chartColumns, function (column) {
              column.setAttribute("rx", 6);
              column.setAttribute("ry", 6);
              column.setAttribute("stroke", "none");
              column.setAttribute("stroke-width", 0);
            });
          }
    
          function setBarOpacity(index, opacity) {
            var chart1 = new google.visualization.ColumnChart(
              document.getElementById("columnchart_material")
            );
            // filter bars by fill color
            var chartBars = chart1
              .getContainer()
              .querySelectorAll(
                'rect[fill="' + "#ec775f" + '"],rect[fill="' + "#76b5bc" + '"]'
              );
    
            // console.log("chartBars" + chartBars[index]);
            // chartBars[index].setAttribute("stroke", "none");
            //chartBars[index].setAttribute("stroke-width", 0);
            // set opacity on index provided
            chartBars[index].setAttribute("opacity", opacity);
          }
    
          function chartMouseOver(sender) {
            changeBorderRadius();
            // set opacity to 0.5
    
            setBarOpacity(sender.row, 0.8);
    
            // ensure point is hovered
            if (sender.row !== null) {
              var padding = 16;
              var chartLayout = chart.getChartLayoutInterface();
              var pointBounds = chartLayout.getBoundingBox(
                "bar#" + (sender.column - 1) + "#" + sender.row
              );
              var tooltip = chart
                .getContainer()
                .getElementsByClassName("google-visualization-tooltip");
              if (tooltip.length > 0) {
                var tooltipBounds = tooltip[0].getBoundingClientRect();
                tooltip[0].style.top =
                  pointBounds.top - tooltipBounds.height - padding + "px";
                tooltip[0].style.left =
                  pointBounds.left +
                  pointBounds.width / 2 -
                  tooltipBounds.width / 2 +
                  "px";
              }
            }
          }
    
          // chart mouseout event
          function chartMouseOut(sender) {
            // set opacity to 1
    
            changeBorderRadius();
            setBarOpacity(sender.row, 1);
          }
        }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <!-- displays site properly based on user's device -->
    
        <link
          rel="icon"
          type="image/png"
          sizes="32x32"
          href="./images/favicon-32x32.png"
        />
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
        <link
          href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&family=Sedan:ital@0;1&display=swap"
          rel="stylesheet"
        />
    
        <title>Frontend Mentor | Expenses chart component</title>
    
        <!-- Feel free to remove these styles or customise in your own stylesheet 👍 -->
        <style>
          .attribution {
            font-size: 11px;
            text-align: center;
          }
          .attribution a {
            color: hsl(228, 45%, 44%);
          }
    
          .main {
            display: block;
            width: fit-content;
            font-family: "DM Sans", sans-serif;
            height: 100vh;
          }
    
          .main .chart {
            display: block;
          }
    
          .main .topbox {
            display: flex;
            flex-direction: row;
          }
    
          .main #total {
            display: flex;
            flex-direction: row;
            font-family: "DM Sans", sans-serif;
          }
    
          .google-visualization-tooltip {
            color: white !important;
            background-color: rgb(11, 11, 11) !important;
            font-family: "DM Sans", sans-serif !important;
            border-radius: 18% !important;
            padding: 0.3% 0.3% 0.3% 0.3% !important;
            align-content: center !important;
    
            border: none !important;
    
            z-index: +1;
          }
    
          @media screen and ((min-width: 320px) and (max-width:768px)) {
            .main {
              padding-left: 15%;
              padding-right: 15%;
            }
          }
        </style>
        <script src="https://www.gstatic.com/charts/loader.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="./expensechart.js"></script>
      </head>
      <body>
        <div
          class="main"
          style="
            background-color: #f8e9dd;
            align-items: center;
            padding-top: 8%;
            padding-bottom: 8%;
            padding-left: 35%;
            padding-right: 35%;
          "
        >
          <div
            class="topbox"
            style="
              background-color: #ec775f;
              border-radius: 10px;
              padding-top: 4%;
              padding-bottom: 3%;
            "
          >
            <div
              id="top1"
              style="
                margin-left: 5%;
                color: #fffaf5;
                font-family: 'DM Sans', sans-serif;
                line-height: 1.5;
              "
            >
              <span
                style="
                  font-size: 13px;
                  font-weight: 200;
                  font-stretch: extra-expanded;
                "
                >My balance</span
              >
              <div>
                <span style="font-size: 22px; font-weight: 500">$921.48 </span>
              </div>
            </div>
            <div style="margin-left: auto; padding-right: 5%">
              <img
                src="./images/logo.svg"
                alt=""
                style="width: 80%; margin-top: 10%"
              />
            </div>
          </div>
          <br />
          <div class="chart" style="background-color: #fffaf5; border-radius: 10px">
            <div id="columnchart_material"></div>
            <hr / style="color:#93867B ;width: 85%; opacity: 0.2;height:
            1px;background-color: #93867B;">
            <br />
            <div id="total">
              <div id="totcol1" style="padding-left: 5%">
                <span style="font-size: 13px; color: #93867b"
                  >Total this month</span
                >
                <div>
                  <span
                    style="color: #382314; font-weight: bold; font-size: xx-large"
                    >$478.33</span
                  >
                </div>
              </div>
              <div id="totcol2" style="margin-left: auto; padding-right: 5%">
                <br />
                <span style="color: #382314; font-weight: bold; font-size: 14px"
                  >+2.4%</span
                >
                <div>
                  <span style="font-size: 13px; color: #93867b"
                    >from last month</span
                  >
                </div>
              </div>
            </div>
            <br />
          </div>
          <br />
    
          <div class="attribution">
            Challenge by
            <a href="https://www.frontendmentor.io?ref=challenge" target="_blank"
              >Frontend Mentor</a
            >. Coded by <a href="#">Aparna Gopalakrishnan</a>.
          </div>
        </div>
      </body>
    </html>