The Google Chart is failing to show up on the screen

I'm having trouble implementing a feature that involves selecting a region from a dropdown list and requesting rainfall data to display in a Google Chart.
Unfortunately, I've encountered some issues with it.
Could you please help me identify what the problem might be?
Apologies for the messy code - I'm still new to JavaScript. I've added comments to make it easier to understand.
Thank you :)

You can find the demo here.

Here is the HTML -

<!-- Some text -->
<div class="text">
    Pick a region from the list below to view its annual rainfall.
</div>

<!-- Dropdown list of regions -->
<div>
    <select class="region">
        <option selected="selected" disabled>Select a region</option>
        <option>Andaman &amp; Nicobar Islands</option>
        <option>Arunachal Pradesh</option>
        <option>Assam, Meghalaya</option>
        ...
    </select>
</div>

<!-- Button to request data -->
<div>
    <button type="button">Get data!</button>
</div>

<!-- Container for the chart -->
<div id="chart">
</div>

Here is the JavaScript -

// Get the selected region
var region = jQuery(".region").find(":selected").text();

// Create button variable
var button = jQuery("button");

// Detect changes in selected region
jQuery(".region").change(function() {
    region = jQuery(".region").find(":selected").text();
});

// Handle button click to load Google Charts
button.click(function() {
    google.charts.load('current', {
        'packages': ['corechart']
    });

    google.charts.setOnLoadCallback(drawChart);

    // Function to draw the chart
    function drawChart() {
        var query;

        // Check which region is selected and define the corresponding query
        if (region == "Andaman & Nicobar Islands") {
            query = new google.visualization.Query("query-url");
        } else if (region == "Arunachal Pradesh") {
            query = new google.visualization.Query("query-url");
        } else if (region == "Assam, Meghalaya") {
            query = new google.visualization.Query("query-url");
        ...

        // Send the query and handle response
        query.send(handleQueryResponse);
    }

    // Function to handle query response and render the chart
    function handleQueryResponse(response) {
        var data = response.getDataTable();
        var options = {...};
        
        ...

        var chart = new google.visualization.BarChart(document.getElementById("chart"));
        chart.draw(view, options);
        
        window.addEventListener('resize', function() {
            chart.draw(view, options);
        }, false);
    }
});

Answer №1

After making some alterations...

  1. google.load and setOnLoadCallback should be only invoked once per page load
  2. Added a value attribute to the option tag to eliminate lengthy if statements
  3. Modified the query to utilize the tq= parameter, enabling the use of an SQL statement and fetching only required columns instead of the entire range
  4. Eliminated the 'get data' button

UPDATE

  1. The chart overlapping the dropdown list was caused by the CSS property float: left; on .region, which has now been changed to text-align: left;
  2. Increase the height of bars by utilizing the chart option bar.groupWidth
  3. Set x-axis intervals at every 1000 units using the chart option hAxis.ticks and specifying custom labels in an array
  4. Show all years on the y-axis rather than just a few similar to the above steps but with vAxis.ticks
  5. Comments have been added for reference, feel free to provide feedback...

Check out the functioning snippet below...

// Loading Google Charts version '45'. The 'current' version throws errors upon loading DataView
google.charts.load('45', {
  // Callback function when Google charts finish loading
  'callback': function() {
    jQuery(".region").change(drawChart);
    // Removed 'drawChart()', seems like you prefer a selection before drawing the chart
  },
  // Packages used on this page
  'packages': ['corechart']
});

function drawChart() {
  // Obtain the selected option value
  var region = jQuery(".region").find(":selected").val();

  // Construct a query with select statement based on the region value
  var query = new google.visualization.Query("https://docs.google.com/spreadsheets/d/1wLbWMwwu_bXcpxm8TlkNtkR4gbeqz_o8CuRzdDQMUaM/gviz/tq?gid=799372846&tq=select A," + region);

  // Execute the query
  query.send(handleQueryResponse);
};

function handleQueryResponse(response) {
  // Retrieve the data table
  var data = response.getDataTable();

  // Create a number formatter for formatting
  var formatter = new google.visualization.NumberFormat({
    pattern: '0'
  });
  // Formatting for first column
  formatter.format(data, 0);

  // Create another number formatter
  var formatter = new google.visualization.NumberFormat({
    pattern: '#,##0.0'
  });
  // Format the second column
  formatter.format(data, 1);

  // Set the chart area height
  var chartAreaHeight = data.getNumberOfRows() * 12;

  // Determine the chart's height
  var chartHeight = chartAreaHeight + 70;

  // Set x-axis labels or 'ticks'
  var xTicks = [];

  // Find the maximum amount for ticks
  var dataMax = google.visualization.data.group(
    data,
    // Modifier column to find max value across the entire table
    [{column: 0, type: 'string', modifier: function () {return '';}}],
    // Max column
    [{column: 1, type: 'number', aggregation: google.visualization.data.max}]
  );

  // 'Round up' to the nearest 1000
  var maxTick = Math.ceil(dataMax.getValue(0, 1) / 1000) * 1000;

  // Load the ticks array
  for (var i = 0; i <= maxTick; i = i + 1000) {
    xTicks.push(i);
  }

  // Build y-axis ticks, adding every year, potential font reduction or increased height may be necessary
  var yTicks = [];
  for (var i = 0; i < data.getNumberOfRows(); i++) {
    yTicks.push(data.getValue(i, 0));
  }

  // Chart options
  var options = {
    animation: {
      startup: true,
      easing: 'linear',
      duration: 750
    },
    annotations: {
      textStyle: {
        fontSize: 7
      }
    },
    title: jQuery(".region").find(":selected").text(),
    legend: "none",
    vAxis: {
      title: "Year",
      format: "0"
    },
    hAxis: {
      title: "Rainfall (in mm)"
    },
    height: chartHeight,
    chartArea: {
      height: chartAreaHeight,
      // Use number for exact height, string for percentage "100%"
      top: 70,
      right: 100,
      bottom: 100,
      left: 100
    },
    // Define bar height
    bar: {
      groupWidth: 7
    },
    // Specify x-axis ticks
    hAxis: {
      ticks: xTicks
    },
    // Configure y-axis settings
    vAxis: {
      // Year format
      format: '0',
      // Adjust text style for font size
      textStyle: {
        fontSize: 8
      },
      // Include tick marks
      ticks: yTicks
    }
  };

  // Generate data view from data table
  var view = new google.visualization.DataView(data);
  // Add calculated column for annotations - 'current' version may encounter issues here
  view.setColumns([0, 1, {
    calc: "stringify",
    sourceColumn: 1,
    type: "string",
    role: "annotation"
  }]);

  // Create and render the chart
  var chart = new google.visualization.BarChart(document.getElementById("chart"));
  chart.draw(view, options);

  // Re-render the chart upon window resizing
  // Removed 'window.addEventListener' as compatibility may vary across browsers
  $(window).resize(function() {
    chart.draw(view, options);
  });
};
.text {
  margin-bottom: 10px;
}

.region {
  text-align: left;
}

button {
  text-align: left;
  margin-left: 10px;
}

#chart {
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="text">
    Select a region below to know the annual rainfall in that region.
</div>

<div>
    <select class="region">
        <!-- Prefer this over 'optgroup' if a selection is required before drawing -->
        <option selected="selected" disabled>Please select a region...</option>
        <option value="B">Andaman &amp; Nicobar Islands</option>
        <option value="C">Arunachal Pradesh</option>
        <option value="D">Assam, Meghalaya</option>
        <option value="E">Bihar</option>
        <option value="F">Chattisgarh</option>
        <option value="G">Coastal Karnataka</option>
        <option value="H">Coastal Andhra Pradesh</option>
        <option value="I">East Rajasthan</option>
        <option value="J">East Madhya Pradesh</option>
        <option value="K">East Uttar Pradesh</option>
        <option value="L">Gangetic West Bengal</option>
        <option value="M">Gujarat Region, Dadra &amp; Nagar Haveli</option>
        <option value="N">Haryana, Delhi, Chandigarh</option>
        <option value="O">Himachal Pradesh</option>
        <option value="P">Jammu, Kashmir</option>
        ...
        
    </select>
</div>

<div id="chart">
</div>

Answer №2

Give this a shot

https://jsfiddle.net/15rdener/

You're using the incorrect format for a javascript object

 options = {
             title = "East Madhya Pradesh"
           }

Instead, you should use

options = {
             title : "East Madhya Pradesh"
          }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using JQuery to handle various input fields, forms, and submission actions

I have multiple forms displayed as rows within a table. At the end of each row, there is a submit button. Upon clicking this button, my JQuery function generates two text boxes and another submit button dynamically. My goal is to capture POST variables fro ...

What is the best way to upload a file to a server while working with Vue.js in the Filemanager plugin, or how can I access a global function

How can I upload a file to the server using Vue.js in the Filemanager plugin? I have tried multiple methods and the console log shows that the upload was successful, but I am not able to see any files on the server. Does anyone know what could be wrong? & ...

Converting Rich Text Format (RTF) Data to HTML: A Step-by

I have information stored in RTF Format within an MS Access Database. The format is as follows: {\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\f ...

Tips for scrolling a div that has too much content within a webpage

Is there a method to manipulate the scrollbar within a div on a webpage? Specifically, I am attempting to automate scrolling up and down on an Instagram post like . However, since the scrollbar may be hidden using CSS properties, detecting it can be challe ...

No matter which file URL is provided, Ajax consistently returns error 500

I am encountering a server 500 error when trying to execute the following code. Even after testing it with a sample file, the error persists. The file permissions are set to 644. Below is the Ajax snippet: function paynlSubmitPayment(userid ,credits ,pro ...

Employing getters in the toObject() method

As I delve into the code of a Node.js Express application for learning purposes, I came across the following line that sparked my curiosity regarding the inclusion of getters and virtuals. var pgmsDbObj = chnnlList[chnnlIndex] var pgmsObj = pgmsDbObj.to ...

Encountering a CORS issue while attempting to make a GET request to an API in an

Looking to retrieve HTML data from a website using an API. The target URL is: https://www.linkedin.com/ Trying to fetch the HTML page as text from this specific URL. Here's what I attempted: getData() { const api = "https://www.linkedin. ...

Choosing JavaScript

<select> <script type="text/javascript"> $.get( 'http://www.ufilme.ro/api/load/maron_online/470', function(data){ var mydata = new Array(); var i = 0; // индекс масси ...

What is the most effective method for retrieving a PHP return value using Ajax?

As I work on creating a validation form in Ajax and PHP, I find myself unsure of how to fetch values from PHP. Can anyone guide me through this process? For instance: The validation form exists in index.php while the page containing the function is check ...

Using a JavaScript function, transmit information through an Express response

I am working on sending an application/javascript response from my Express server, utilizing data retrieved from MongoDB. This response is intended for loading content on a third party website. All components of the process have been developed, and now I ...

Exploring the JSON structure

Struggling to come up with a solution as I am limited by certain restrictions. I need to create a mobile navigation system using a JSON object provided by the proprietary server. The only allowed framework is jQuery 1.12.4, no other frameworks or updated v ...

How can you create a personalized sorting order using odata?

Within my AngularApp, I retrieve data from a WebAPI using OData queries. All the retrieved results contain both a date and an integer status code. The status codes range from 1 to 4. I am aiming to organize my results in such a way that all items with a ...

featherlight.js - Execute code when modal is triggered

Situation with HTML <div id="form-lightbox"> <div class="form"> <div id="ajaxreplace"> <script type="text/javascript"> jQuery(function() { jQuery.ajaxReplace({ //parame ...

Tips for implementing a jQuery script within an Angular directive

I recently attempted to incorporate a jQuery code into an Angular component, but I encountered some issues. The jQuery code was originally placed in the HTML, which is considered bad practice. So, I tried creating a new function and adding my jQuery code t ...

Using AJAX to populate a dropdown menu in a CodeIgniter application

I'm having an issue with using AJAX to populate a dropdown option. Here is the JavaScript code I am using: <script type="text/javascript"> $(document).ready(function(){ $("#sepatu").click(function(e){ e.preventDefault() ...

jQuery function fails to work on a list that has been dynamically generated

Can someone please assist me? I have encountered an issue where the dynamic list on the second page is not functioning properly. When I click any "li" element to trigger an alert for the respective "id" (which works fine for a hardcoded list), nothing happ ...

Updating new objects in Angular using JavaScript Object-Oriented Programming may not be working

Recently delving into OOP in JavaScript while working on an AngularJS website, I encountered a situation where my object methods were only altering the properties within the class, but not affecting the new object itself. //Class Var Item = function() { ...

What is the best way to hide only the rows in a table when it is clicked using JavaScript?

Is there a way to hide rows in these tables by clicking on the table head? I'm currently using bootstrap 5 so JQuery is not an option. <table class="table table-info table-bordered"> <thead id="tablea"> ...

Issues have been encountered with Angular 5 when trying to make required form fields work properly

Just created my first Angular app using Angular 5! Currently following the documentation at: https://angular.io/guide/form-validation. Below is the form I have set up: <form class="form-container"> <mat-form-field> <input matInput pl ...

What is the best way to override @include within a CSS class?

Our team's application utilizes Bootstrap SASS for styling, but we have made certain customizations to the framework. The Bootstrap files are included in our project through a build process, making direct modifications impossible. When it comes to dr ...