Как создать данные Dynami c из Google Chart API с использованием PHP и MySQL? - PullRequest
0 голосов
/ 28 января 2020

У меня проблема, и мне нужна помощь. Я могу показать горизонтальную столбцовую диаграмму из Google API с динамическими данными c из таблицы MySQL при загрузке страницы. Но , когда я нажимаю кнопку и данные публикуются на странице, диаграмма не печатается на HTML, даже если я вижу на вкладке ответа в консоли, что скрипт был сгенерирован правильно. Однако, когда я смотрю на HTML в инспекторе, я вижу, что JavaScript выглядит серым на странице, как если бы оно было закомментировано. Я часами чесал голову. Сервер я использую PHP. На стороне клиента я использую Javascript / jQuery + HTML. Как я могу это исправить? Если у вас есть лучший способ создать график от PHP до HTML, я открыт для предложений.

graph. html

<div id="chart_div1"></div>

jquery

$(document).on('click', '.view_sales_year_btn', function () {

    //collect variables
    var sales_year = $("#sales_year").find(":selected").val();

    var valuesf = "user_id=" + encodeURIComponent(user_id)
        + "&sales_year=" + encodeURIComponent(sales_year);

    if (sales_year !== '' || sales_year !== null && valuesf !== '') {

        $.ajax({
            type: "POST",
            url: "graph.php",
            dataType: 'json',
            data: valuesf,
            success: function (data) {

                //DISPLAY SALES GRAPH'
                $('#chart_div1').html(data.sales_graph);

            }
        });
    }
});

график. php

//collect variables         
$user_id = mysqli_real_escape_string($conn,$_POST['user_id']);

if(isset($_POST['sales_year'])){
    //post year    
    $sales_year=mysqli_real_escape_string($conn,$_POST['sales_year']);
}else{
    $sales_year = date('Y');
}

//set title for graph 
$graph_title ='My Sales '.$sales_year;

//cleaning status 
$c_status = 'Booked';

//select all completed cleanings from user_schedule 
$user_schedule = $conn->prepare('SELECT cleaner_id, 
                                MONTH(cleaning_date) AS sales_month,
                                YEAR(cleaning_date) AS sales_year,
                                SUM(cleaning_price) AS total_sales
                    FROM user_schedule 
                    WHERE YEAR(cleaning_date)=?
                    AND cleaner_id=?
                    AND cleaning_status=?
                    GROUP BY DATE_FORMAT(cleaning_date, "%m-%Y")');
$user_schedule->bind_param('sss',$sales_year,$user_id,$c_status);
$user_schedule->execute();
$user_result = $user_schedule->get_result();

//iteration
if($user_result->num_rows>0){
    //declare variable 
    $my_sales = '';
    $my_sales .='<script type="text/javascript">';
    $my_sales .=" google.load('visualization', '1', {packages:['corechart']});
        google.setOnLoadCallback(drawChart1);
        function drawChart1(){
        var data = google.visualization.arrayToDataTable([
            ['Month', 'Sales'],";
    while($sales = $user_result->fetch_assoc()){
        //get month number
        $monthNum =$sales['sales_month'];

        //convert monh number to month name 
        $dateObj   = DateTime::createFromFormat('!m', $monthNum);
        $month = $dateObj->format('F'); // March

        //get first 3 characters from month 
        $this_month = substr($month, 0, 3);

        //select all completed cleanings from user_schedule 
        $total_month_sales = (int)$sales['total_sales']*0.35;

        //echo month with total sales 
        $my_sales .="['".$this_month."',  ".$total_month_sales."],";
    }
    $my_sales .= "]);

        var options = {
            title: '".$graph_title."',
            hAxis: {title: 'Amounts may differ from Stripe', titleTextStyle: {color: 'blue'}}
        };

        var chart = new google.visualization.ColumnChart(document.getElementById('chart_div1'));
        chart.draw(data, options);
        }

        $(window).resize(function(){
            drawChart1();
        });
    </script>";

}else{
    $my_sales = '<h4 class="text-center alert alert-warning">You Have No Sales For '.$sales_year.' Yet.</h4>';
}

//return answer to json
$result = array('message' => 'success','sales_graph'=>$my_sales);
header('Content-Type: application/json');
echo json_encode($result);

1 Ответ

1 голос
/ 28 января 2020

Простое добавление кода Javascript на вашу страницу на самом деле не выполнит этот код. По сути, ваш AJAX вызов возвращает что-то, а ваш JS затем вставляет это в div, и ... и все. Браузер не будет пытаться запустить этот материал. Даже если вы обновите JS, чтобы попытаться запустить только что вставленный материал, он не будет работать, потому что браузер даже не знает, что существует новый код - его не было при загрузке страницы, когда браузер разбирает страницу. Вы должны сначала eval() этот новый код, который вводит новый набор проблем. Этот вопрос является хорошим справочником и описывает некоторые из них.

Отступив, тем не менее, есть лучший подход.

Судя по вашему JS, вашему клиенту На странице есть селектор года, поэтому вы можете выбрать, например, 2019 и нажать кнопку «график», и увидеть график ваших продаж в 2019 году. Итак, что вы действительно ищете из AJAX - это график data . Если вы измените год и снова нажмете кнопку, вам понадобится набор данных sh - вам не нужно снова загружать Google Charts JS и инициализировать новый график.

Ваша страница переднего плана может включать все настройки и инициализации вашей диаграммы Google, но без каких-либо данных. Без данных вы, конечно, не сможете их нарисовать, поэтому вам нужно запустить фактическое рисование другим способом, как только вы загрузите свои данные.

PHP

Итак, сначала обновите PHP и удалите все Javascript. Вам нужен только массив значений месяца / продаж:

$my_sales = [];
while ($sales = $user_result->fetch_assoc()) {
    // ... your code to set these variables up
    $my_sales[$this_month] = $total_month_sales;
}

Удалите теги <script>, все связанные с Google Charts JS, drawChart1, et c - единственное, что AJAX должен вернуть JSON данные. Используя ваш существующий подход PHP:

$result = array('message' => 'success', 'sales_graph' => $my_sales);
header('Content-Type: application/json');
echo json_encode($result);

HTML

Далее, добавьте материал Charts JS, который вы только что удалили из PHP, в ваш интерфейс в graph.html:

google.load('visualization', '1', {packages: ['corechart']});

// Don't want to draw the chart on load any more, you will manually
// draw it once you have some data - so remove this line entirely
// google.setOnLoadCallback(drawChart1);

function drawChart1() {
    // ...
}

$(window).resize(function() {
   // ...
}

Теперь, для функции, которая фактически рисует aws диаграмму, вы должны быть в состоянии дать ей набор данных для рисования - ie она должна принять параметр:

// values will be the JSON data we got back from the AJAX call
function drawChart1(values) {

Есть еще несколько обручей, через которые нужно перейти, чтобы получить JSON данные, которые мы получаем от AJAX в правильном формате:

// Convert the JSON values to an array, as Google's DataTable
// requires that.
array = [];
for (var i in values) {
    array.push([i, values[i]]);
}

var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('number', 'Sales');
data.addRows(array);

Итак, теперь вы подготовьте и запустите свою диаграмму Google. Чтобы нарисовать диаграмму, вам нужно получить некоторые данные и передать их drawChart1() в качестве параметра. Вы можете сделать это с помощью обработчика AJAX success:

success: function(response) {
    // response is the JSON data your PHP sends us.  Pass the 
    // 'sales_graph' element of it it to the function and have it
    // drawn!  You can also test that response.message is 'success'
    drawChart1(values.sales_graph);
}

Здесь есть несколько движущихся частей, и я немного подскочил, но гораздо яснее увидеть все это вместе, работает, в действии - вот рабочий JSFiddle . Обратите внимание, что он использует JSFiddles echo для имитации вашего AJAX вызова - в основном я подделываю ваш запрос AJAX и предоставляю некоторые фиктивные данные для возврата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...