Создание Google Chart на лету с помощью JSP - PullRequest
0 голосов
/ 08 июля 2011

Я использую линейную диаграмму Google для отображения значений, извлеченных из базы данных с использованием JSP.У меня в настоящее время это работает.Операторы data.addColumn генерируются из запроса к базе данных при загрузке страницы.

Моя проблема заключается в том, что я также хочу иметь несколько комбинированных списков, которые можно использовать для выбора минимальных и максимальных значений для оси Xа затем обновить график.В настоящее время я могу думать только о том, чтобы добиться этого, обновив страницу новыми параметрами get.

Я бы предпочел как-то обновить только сам график без перезагрузки всей страницы.Это возможно?Есть ли способ перезаписать тег сценария и затем перезагрузить диаграмму?Или есть какой-то другой способ?

РЕДАКТИРОВАТЬ: У меня проблемы с выяснением, как передать данные из базы данных на страницу загрузки.Вот мой код:

loader.html (страница содержит поля диаграммы и даты):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
        google.load('visualization', '1', {packages: ['corechart']});
    </script>
    <script type="text/javascript">
        function loadChart()
        {
            var xmlhttp;            
            var minDate = document.getElementById('startDate').value;
            var maxDate = document.getElementById('endDate').value;

            if (!minDate)
                minDate = 'none';
            if (!maxDate)
                maxDate = 'none';

            if (window.XMLHttpRequest)
            {// code for IE7+, Firefox, Chrome, Opera, Safari
                xmlhttp = new XMLHttpRequest();
            }
            else
            {// code for IE6, IE5
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=function()
            {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
                {
                    document.getElementById('lineChart').innerHTML = xmlhttp.responseText;
                }
            }
            xmlhttp.open("GET", "chart-loader.jsp?min=" + minDate + '&max=' + maxDate, true);
            xmlhttp.send();
        }
    </script>
</head>

<body>
    <div id="container">

        <div id="lineChart"></div>

        <div id="startDateBox">
            <label for="startDate">Min Date:</label>
            <input id="startDate" type="text" />
        </div>
        <div id="endDateBox">
            <label for="endDate">Max Date:</label>
            <input id="endDate" type="text" />
        </div>
        <input type="button" value="Update" id="updateBtn" onclick="loadChart()" />

    </div> <!-- End container -->
</body>
</html>

chart-loader.jsp (предполагается)получить данные и загрузить график)

<%@ page import="java.sql.*, java.util.ArrayList" %>
<%      
    Connection conn;

    try {
        Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
        conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://...", "user", "pass");
    }
    catch(SQLException e) 
    {
        out.println("SQLException: " + e.getMessage() + "<br/>");
        while((e = e.getNextException()) != null)
            out.println(e.getMessage() + "<br/>");
        throw new UnavailableException(this, "Cannot connect with the specified database.");
    }

    String data = "";
    String minDate = (String)request.getParameter("min");
    String maxDate = (String)request.getParameter("max");
    try
    {
        ResultSet rs;
        Statement stmt = conn.createStatement();
        if (minDate.equals("none") || maxDate.equals("none")) // First load, use whole table
        {
            rs = stmt.executeQuery("SELECT ...");
        }
        // ... more possible queries

        ArrayList<String> ptVals = new ArrayList<String>();
        ArrayList<String> colDates = new ArrayList<String>();

        while (rs.next())
        {
            ptVals.add(rs.getString("avgvalue"));
            colDates.add(rs.getString("collectiondate"));
        }           
        // ptVals.size()
        for (int i = 0; i < 5; i++)
            data += "\t\t\tdata.addRow(['" + colDates.get(i) + "'," + ptVals.get(i) + "]);\n";  

        // ... Use out.print to spit out script. 
    }
    catch(SQLException e)
    {
        data = "SQLException: " + e.getMessage() + "<br/>";
        while((e = e.getNextException()) != null)
            data += e.getMessage() + "<br/>";           
    }       
    finally
    {   // Clean up resources, close the connection.
        if(conn != null)
        {
            try { conn.close(); }
            catch (Exception ignored) {}
        }
    }
%>

Оригинальный скрипт для загрузки графика

<script type="text/javascript">
    function drawVisualization() 
    {
        // Create and populate the data table.
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Date');
        data.addColumn('number', 'Temperature');
        data.addRow(["01/01/11", 70.2]);
        data.addRow(["01/02/11", 70.0]);
        data.addRow(["01/03/11", 69.8]);
        data.addRow(["01/04/11", 70.1]);
        // Create and draw the visualization.
        new google.visualization.LineChart(document.getElementById('lineChart')).
            draw(data, {backgroundColor: 'transparent',
                        width: 700, height: 400,
                        legend: 'none',
                        hAxis: {title: 'Dates', titleTextStyle: {color: 'black', fontSize: 12, fontName: 'Verdana, Arial'}},
                        vAxis: {title: 'Temperature', titleTextStyle: {color: 'black', fontSize: 12, fontName: 'Verdana, Arial'}},
                        chartArea: {left: 80, top: 20}
                    }
                );
    }

    google.setOnLoadCallback(drawVisualization);
</script> 

Спасибо, Райан

Ответы [ 2 ]

1 голос
/ 08 июля 2011

Мы делаем именно то, где я работаю (я имею в виду обновление диаграммы Google). Мы загружаем страницу без диаграммы и просто загружаем ее в Ajax в любой контейнер, в котором она должна быть. Затем, когда вы что-то изменяете, ajax перезагружает ее, отправляя все необходимые параметры. в JSP (который получает новый график).

РЕДАКТИРОВАТЬ: В случае, если это не имело смысла, сама диаграмма фактически находится на своем собственном JSP, который вводится в страницу (и обновляется) независимо.

Итак, наш процесс таков:

Визуализация главной страницы (графики еще не отображаются). На этой странице мы добавили что-то вроде этого:

<div id="chartForData1"></div>

<script>Ajax_inject('chartForData1', 'pageThatGeneratesData1');</script>

Где Ajax_inject - это наша оболочка для вызова Ajax, который загружает данные в элемент. Теперь, когда страница отображается на компьютере пользователя, этот Ajax_inject (и все остальные) будет выполняться, тем самым загружая в соответствующий div соответствующий обработанный JSP. Единственная цель этих JSP - взять пару параметров (или ни одного из них и использовать значения по умолчанию) и сделать нам симпатичный и симпатичный гугл-график.

Это имеет больше смысла?

0 голосов
/ 23 июля 2011

Мне удалось заставить это работать с Google Visualization API.Вот как:

У меня есть HTML-страница с контейнером div для графика.<div id="lineChart"></div>

Далее у меня есть две функции JavaScript на странице HTML.Функция getChartData() - это функция AJAX, которая получает диапазон дат из двух полей ввода и отправляет их на страницу JSP.Страница JSP использует даты для запроса к базе данных записей в этом диапазоне, форматирует их как объект JavaScript и отправляет их обратно на страницу HTML, используя out.print().

Как только страница HTML получает данные,он использует eval(), чтобы установить полученный текст как объект JavaScript.Наконец, объект данных отправляется во вторую функцию JavaScript, loadChart(), которая использует данные для вызова функций Google и загрузки диаграммы в div.

Примечание: использование eval() для установкиresponseText к объекту JavaScript - это то, что действительно заставляет все это работать.Это позволяет вам передавать много данных обратно.Вы просто вытаскиваете их из объекта JS, как только вернетесь на страницу HTML.Вы даже можете передавать несколько объектов JS друг в друга.

var paramsObj;
var dataObj;
eval('paramsObj = ' + xmlhttp.responseText + ";");
eval('dataObj = paramsObj.data;');
loadChart(dataObj, paramsObj.title, paramsObj.xLabel);

В этом случае я передаю три параметра в один объект JS.paramsObj.data - это данные диаграммы, которые представляют собой вложенный объект, отформатированный в соответствии с API визуализации Google.Мне пришлось снова использовать eval(), чтобы установить вложенный объект JS как отдельную переменную, иначе он не будет правильно передан функции loadChart().paramsObj.title и paramsObj.xLabel - просто строки.

...