javascript - 在服务器端保存 Google Chart

标签 javascript php postgresql charts google-visualization

我制作了一个 JS 脚本,它从 Postgres 数据库中提取数据并将它们可视化为一堆漂亮的 Google 图表。这很好用,但速度很慢,有时网页会超时。

为了补救,我正在考虑将图表创建为 PNG/GIF/SVG/Whatever,并使用 cron 作业以特定时间间隔刷新图表。这会为了速度而牺牲交互性(在这种情况下这不是很重要)。然而,谷歌搜索并没有提供使用 PHP 创建谷歌图表的清晰路径。有什么建议么?

这是我的 JS 脚本:

            google.setOnLoadCallback(drawManyCharts); 

        function drawManyCharts()
        //parameters are: timeUnit, target div, abscissa bins, MultiplicationFactor, Graphtype, SensorString
        {drawAllCharts("minutes", "GoogleChart_div", 500, 0.01, "Linechart", "Temperature"); 
        drawAllCharts("hours", "GoogleChart2_div", 400, 0.01, "Linechart", "Temperature");
        drawAllCharts("days", "GoogleChart3_div", 48, 0.01, "Linechart", "Temperature");
        drawAllCharts("weeks", "GoogleChart4_div", 48, 0.01, "Linechart", "Temperature");
        drawAllCharts("hours", "GoogleChartPressure_div", 48, 0.01, "Linechart", "Pressure");
        }

        function drawAllCharts(TimeUnit, containerChart, NoAbscissaBins, MultiplicationFactor, Graphtype, SensorString)
        {

        //    var  SensorString="Temperature"; 
              var  TableType="integer";
        //    var  NoAbscissaBins=12;
              var  DataTableName="dataMasterTable";
        //    var  TimeUnit="days";
              var  TimeStart="test";
        //    var  Graphtype="Linechart";
              var  graphtitle = "Heizungskeller";
              var  OrdinateLabel = "Temperature (Celsius 100x)" 
              var  maxViewWindow= 8000;
              var  minViewWindow= 0;

              var GoogleArray = $.ajax({          
                url: "/php/PrepareGoogleDataTable.php" +"?"+
                            "SensorString="+SensorString + "&"+
                            "TableType=" + TableType +"&"+
                            "NoAbscissaBins=" + NoAbscissaBins + "&"+
                            "MultiplicationFactor=" + MultiplicationFactor + "&"+
                            "DataTableName=" + DataTableName +"&"+
                            "TimeUnit=" + TimeUnit +"&"+
                            "TimeStart=" + TimeStart,          
                //dataType:"json",          
                async: false          
                }).responseText;
                console.log(GoogleArray);
                GoogleArray = JSON.parse(GoogleArray); 
                eval(GoogleArray.GoogleAddColumns);
                eval(GoogleArray.GoogleAddRows);



        //create dynamic dataview for charts
        //columns as specified by TableType
        switch (TableType)
        {
        case "boolean":
            eval(GoogleArray.GoogleVisualizeColumnCount)  ;
        break;

        case "integer" :
            eval(GoogleArray.GoogleVisualizeColumnsMinStdevStdevMax)  ;
            eval(GoogleArray.GoogleVisualizeColumnsAvg)  ;
        break;

        case "float" :
            eval(GoogleArray.GoogleVisualizeColumnsMinStdevStdevMax)  ;
            eval(GoogleArray.GoogleVisualizeColumnsAvg)  ;
        break;

        case "string" :
        break;


        }

        switch (Graphtype)
        {
        case "Candlestick":
         var optionsCandlestick = {
            width: '100%', 
            height: 480,
            bar:{groupWidth: '90%'},
            vAxis: {minValue: 0,
                    baseline: 0,
                    textStyle: {color: 'blue',
                                fontSize: 10},
                    viewWindowMode: 'explicit',
                    viewWindow: {max: maxViewWindow,
                                min: minViewWindow
                                }
                    },
            hAxis: {textStyle: 
                        {color: 'blue',
                        fontSize: 10},
                    },
            pointSize: 5,
            title: graphtitle
            };

        var wrapper = new google.visualization.ChartWrapper(
             {chartType: 'CandlestickChart',
              dataTable: dataViewMinStdevStdevMax,
                options: optionsCandlestick,
                containerId: containerChart});
                wrapper.draw();

        break;

        case "StackedColumn":

        var optionsColumnchart = {
            chartArea: {width: '80%', height: '70%'},
            //legend: {position: 'in'},
            //titlePosition: 'in', 
            axisTitlesPosition: 'in',
            hAxis: {textPosition: 'in'}, 
            vAxis: {textPosition: 'in'},
            width: '100%', 
            height: 520, 
            isStacked: true, 
            pointSize: 3,
            fontSize: 10,
            backgroundColor: 'transparent', 
            bar:{groupWidth: '90%'},
            hAxis:{slantedTextAngle: 90},
            legend:{position: 'in', textStyle: {color: 'blue', fontSize: 12}},
            title: graphtitle
            };    
        var wrapper = new google.visualization.ChartWrapper(
             {chartType: 'ColumnChart',
              dataTable: dataViewCount,
                options: optionsColumnchart,
                containerId: containerChart});
                wrapper.draw();
        break;

        case "Linechart":
            //these are the customizable options from google
            var optionsLinechart = {
                        chartArea: {width: '80%', height: '70%'},
                        //legend: {position: 'in'},
                        width: 1000, 
                        height: 480, 
                        pointSize: 0,
                        title: graphtitle,
                        vAxis: {title: OrdinateLabel}
        };

            var wrapper = new google.visualization.ChartWrapper(
             {chartType: 'LineChart',
              dataTable: dataViewAvg,
                options: optionsLinechart,
                containerId: containerChart});
                wrapper.draw();
        break;

        }

        } 
        </script> 

这里是获取 Postgres 数据并将其转换为 Google Chart 可消化格式的 PHP 脚本:

    <?php
    if(isset($_GET['SensorString']) && 
        (!empty($_GET['SensorString'])) && 
        (!empty($_GET['TableType'])) && 
        (!empty($_GET['TimeUnit'])) && 
        (!empty($_GET['NoAbscissaBins'])) && 
        (!empty($_GET['DataTableName'])) && 
        (!empty($_GET['MultiplicationFactor'])) && 
        (!empty($_GET['TimeStart'])))

        {$SensorString = str_replace ( "*", "%", $_GET['SensorString']); // string to fill "WHERE" condition
         $TableType = $_GET['TableType']; // boolean/integer/float/string
         $TimeUnit = $_GET['TimeUnit']; //hours/days/weeks/months/years
         $NoAbscissaBins = $_GET['NoAbscissaBins']; //number of time units to be displayed on the abscissa
         $DataTableName = $_GET['DataTableName']; //number of time units to be displayed on the abscissa
         $TimeStart = $_GET['TimeStart']; //should not necessarily be used

         }
    else 
        {// assume Bewegungsmelder, boolean, hours, 12 bins
        $SensorString = "OutsideTemp";
        $TableType = "float";
        $TimeUnit = "days";
        $TimeStart = -12;   
        $NoAbscissaBins = 30;
        $DataTableName = "dataMasterTable";
        }

    $RedirectEchoToFile = false;



    $DataCollectionArray = DataCollectionCrossTab($SensorString, $TableType, $TimeUnit, $NoAbscissaBins, $TimeStart, $DataTableName);
    //echo  "GoogleDataRow:  ". $DataCollectionArray['GoogleDataRow'] ;
    $GoogleArray = PrepareGoogleChart($DataCollectionArray);


    /*  $GoogleArray has the following keys:
    /   [0] => GoogleAddColumns 
    /   [1] => GoogleAddRows 
    /   [2] => GoogleVisualizeColumnCount 
    /   [3] => GoogleVisualizeColumnsAvg 
    /   [4] => GoogleVisualizeColumnsMinStdevStdevMax 
    /   [5] => MainCrosstabSelectQuery 
    */


    echo json_encode($GoogleArray);



    //---------------------------------------------------

    Function PrepareGoogleChart($DataCollectionArray)
    {
    // var GoogleAddColumns adds columns to DataTable

    $TimeUnit = "hours"; // (can be "hours", "days", "months", "years" )
    $GoogleAddColumns = ""; 

    // var GoogleVisualizeColumnsAll renders DataView1 view of DataTable
    // var VisualizeFirstColumn sets the first column, and renders "hours" (can be changed to days etc.)
    $VisualizeFirstColumn = ".setColumns([
                            {calc: function(data, row) 
                            {return data.getFormattedValue(row, " 
                            . ColumnLabel($TimeUnit). "); }, 
                            type:'string'}";

    //set up dataView1, which is essentially useless
    $GoogleVisualizeColumnsAll = 
        "var dataView1 = new google.visualization.DataView(".$DataCollectionArray['DataTableName'].");".chr(13)
        ."dataView1".$VisualizeFirstColumn;

    //set up dataViewCount, which is good to count events from IpsLoggingBoolean and feed a column chart
    $GoogleVisualizeColumnCount = 
        "var dataViewCount = new google.visualization.DataView(".$DataCollectionArray['DataTableName'].");"
        .chr(13)."dataViewCount".$VisualizeFirstColumn;

    //set up dataViewAvg, which visualizes only the averages and is good for line charts
    $GoogleVisualizeAvg = 
        "var dataViewAvg = 
            new google.visualization.DataView(".$DataCollectionArray['DataTableName'].");".chr(13).
            "dataViewAvg"
            .".setColumns([ {calc: function(data, row) 
                            {return data.getFormattedValue(row, " 
                            . ColumnLabel($TimeUnit). "); }, 
                            type:'string'}";

    //set up dataViewMinStdevStdevMax, which can feed a candlestick chart 
    $GoogleVisualizeColumnsMinStdevStdevMax = 
        "var dataViewMinStdevStdevMax = 
            new google.visualization.DataView(".$DataCollectionArray['DataTableName'].");".chr(13)
            ."dataViewMinStdevStdevMax"
            .".setColumns([ {calc: function(data, row) 
                            {return data.getFormattedValue(row, " 
                            . ColumnLabel($TimeUnit). "); }, 
                            type:'string'}";

    $GoogleVisualizeScattergram = 
        "var dataViewScattergram = new google.visualization.DataView(".$DataCollectionArray['DataTableName'].");"
        .chr(13)."dataViewScattergram.setColumns([";


    //create strings for Google DataTable/DataView1 columns definition
    $GoogleAddColumns = 
          "var ". $DataCollectionArray['DataTableName']. "= new google.visualization.DataTable();".chr(13). 
          $DataCollectionArray['DataTableName'].".addColumn('string', 'hoursIndex');".chr(13).
          $DataCollectionArray['DataTableName'].".addColumn('string', 'hours');".chr(13).
          $DataCollectionArray['DataTableName'].".addColumn('string', 'PlaceHolder1');".chr(13).
          $DataCollectionArray['DataTableName'].".addColumn('string', 'PlaceHolder2');".chr(13).
          $DataCollectionArray['DataTableName'].".addColumn('string', 'PlaceHolder3'); ";

    for ($varIndex=0; $varIndex < ($DataCollectionArray['NumberOfColumns']-5); $varIndex++)
      {

      Switch ($DataCollectionArray['TableType'])
        {
        case "boolean":
          $GoogleAddColumns .=  
          $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. ", 'count$varIndex'); ";
        break;

        case "integer":
            $GoogleAddColumns .= 
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'avg'); ".chr(13).
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'stddev+'); ".chr(13).
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'stddev-');  ".   chr(13).
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'max');  " .chr(13).
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'min'); " .chr(13);
        break;

        case "float":
            $GoogleAddColumns .= 
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'avg'); ".chr(13).
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'stddev+'); ".chr(13).
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'stddev-');  ".   chr(13).
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'max');  " .chr(13).
        $DataCollectionArray['DataTableName'].".addColumn('number', ".$DataCollectionArray['CategoryArray'][$varIndex]. " +'min'); " .chr(13);
        break;

        case "string":
        //no visualization in case of strings, but a "tableChart" could be generated if need be.
        break;
        }

    $GoogleVisualizeColumnsAll .= 
        ", ". strval(($varIndex+1)*4+1).", ". 
        strval(($varIndex+1)*4+2).", ". 
        strval(($varIndex+1)*4+3).", ". 
        strval(($varIndex+1)*4+4);  

    $GoogleVisualizeColumnCount .= 
        ", ". strval(($varIndex+1)+4);  

    $GoogleVisualizeAvg .= 
        ", ". strval(($varIndex+1)*5+0);  

    $GoogleVisualizeColumnsMinStdevStdevMax .= 
        ", ". strval(($varIndex+1)*5+1).
        ", ". strval(($varIndex+1)*5+2).
        ", ". strval(($varIndex+1)*5+3).
        ", ". strval(($varIndex+1)*5+4);  

    $GoogleVisualizeScattergram .=  strval(($varIndex+1)*4+2).", ";
      }

    //echo "Tabletype: ". $DataCollectionArray['TableType'].chr(13)."<br>"."<br>";
    //echo "GoogleAddColumns:   ". $GoogleAddColumns.chr(13)."<br>"."<br>";

      $GoogleVisualizeColumnsAll .=             "]);".chr(13);
      $GoogleVisualizeColumnCount .=            "]);".chr(13);
      $GoogleVisualizeAvg .=                    "]);".chr(13);
      $GoogleVisualizeColumnsMinStdevStdevMax.= "]);".chr(13);
      $GoogleVisualizeScattergram = substr($GoogleVisualizeScattergram, 0, -2) . "]);".chr(13);

    VerboseEcho($GoogleAddColumns. "<br><br><br>".$GoogleVisualizeColumnsAll);


    //create dataset rows to be processed into google datatable
    $DataForGoogleChart = $DataCollectionArray['GoogleDataRow'];



    //echo "<br><font color='green'>DataForGoogleChart: $DataForGoogleChart</font><br>";


    $GoogleFormattedDataArray = array(
                'GoogleAddColumns' =>    $GoogleAddColumns,
                'GoogleAddRows' =>  $DataCollectionArray['DataTableName'].'.addRows('.$DataCollectionArray['GoogleDataRow'].'); '.chr(13),
                'GoogleVisualizeColumnCount' => $GoogleVisualizeColumnCount,
                'GoogleVisualizeColumnsAvg' => $GoogleVisualizeAvg,
                'GoogleVisualizeColumnsMinStdevStdevMax' => $GoogleVisualizeColumnsMinStdevStdevMax,
                'MainCrosstabSelectQuery' => $DataCollectionArray['MainCrosstabSelectQuery']            
    );

    return $GoogleFormattedDataArray;
    }




    //-----------------------------------------------------

    Function DataCollectionCrossTab($SensorString, $TableType, $TimeUnit, $NoAbscissaBins, $TimeStart, $DataTableName) //sensorstring: e.g. DigitalInput 2
    {
    $dbconn = pg_connect("host=10.10.10.8  port=5432 dbname=IpsLogging user=*** password=***") 
        or die ('connection aborted: ' . pg_last_error().chr(13));

    switch ($TableType)
        {
        case "boolean":
            $IpsTable = "loggingdb_ips_boolean";
            $AggregateFunctions = "COUNT(*) As value ";
            $SensorColumn = 2;
            $WhereClause=" AND (log.ipsvalue = true) "; //only movement triggers
        break;
        case "integer":
            $IpsTable = "loggingdb_ips_integer";
            $AggregateFunctions = "(AVG(ipsvalue)::NUMERIC(8,2)) 
                                  ||'', '' || 
                                  (MIN(ipsvalue)::NUMERIC(8,2)) 
                                  ||'', '' || 
                                  ((AVG(ipsvalue)::NUMERIC(8,2)) - (coalesce(STDDEV(ipsvalue), 0)::NUMERIC(8,2)))  
                                  ||'', '' || 
                                  ((AVG(ipsvalue)::NUMERIC(8,2)) + (coalesce(STDDEV(ipsvalue), 0)::NUMERIC(8,2)))  
                                  ||'', '' || 
                                  (MAX(ipsvalue)::NUMERIC(8,2))  
                                  As value ";
            $WhereClause="";
            $SensorColumn = 4;
        break;
        case "float":
            $IpsTable = "loggingdb_ips_float";
            $AggregateFunctions = "(AVG(ipsvalue)::NUMERIC(8,2)) 
                                  ||'', '' || 
                                  (MIN(ipsvalue)::NUMERIC(8,2)) 
                                  ||'', '' || 
                                  ((AVG(ipsvalue)::NUMERIC(8,2)) - (coalesce(STDDEV(ipsvalue), 0)::NUMERIC(8,2)))  
                                  ||'', '' || 
                                  ((AVG(ipsvalue)::NUMERIC(8,2)) + (coalesce(STDDEV(ipsvalue), 0)::NUMERIC(8,2)))  
                                  ||'', '' || 
                                  (MAX(ipsvalue)::NUMERIC(8,2))  
                                  As value ";
            $SensorColumn = 4;
            $WhereClause="";
        break;
        case "string":
            $IpsTable = "loggingdb_ips_string";
            $WhereClause="";
        break;
        }

    Switch ($TimeUnit)
        {case "minutes":
          $SelectRowNames = 
            "to_char(ipstimestamp, ''YYYYMMDDHH24MI'') As row_name, 
            to_char(ipstimestamp, ''FMHH24h:MI'') As labelled_row_name,     
            ''PlaceHolder1'' As PlaceHolder1,
            ''PlaceHolder2'' As PlaceHolder2,
            ''PlaceHolder3'' As PlaceHolder3,";
          $GroupOrder = "   
            GROUP BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category  
            ORDER BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category', ";
        break;

        case "hours":
          $SelectRowNames = 
            "to_char(ipstimestamp, ''YYYYMMDDHH24'') As row_name, 
            to_char(ipstimestamp, ''FMDD mon FMHH24h'') As labelled_row_name,   
            ''PlaceHolder1'' As PlaceHolder1,
            ''PlaceHolder2'' As PlaceHolder2,
            ''PlaceHolder3'' As PlaceHolder3,";
          $GroupOrder = "   
            GROUP BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category  
            ORDER BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category', ";
        break;

        case "days":
          $SelectRowNames = 
            "to_char(ipstimestamp, ''YYYYMMDD'') As row_name, 
            to_char(ipstimestamp, ''FMDD mon YYYY'') As labelled_row_name,  
            ''PlaceHolder1'' As PlaceHolder1,
            ''PlaceHolder2'' As PlaceHolder2,
            ''PlaceHolder3'' As PlaceHolder3,";
          $GroupOrder = "   
            GROUP BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category  
            ORDER BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category', "; 
        break;

        case "weeks":
          $SelectRowNames = 
            "to_char(ipstimestamp, ''YYYYWW'') As row_name, 
            ''wk'' || to_char(ipstimestamp, ''FMWW YYYY'') As labelled_row_name,    
            ''PlaceHolder1'' As PlaceHolder1,
            ''PlaceHolder2'' As PlaceHolder2,
            ''PlaceHolder3'' As PlaceHolder3,";
          $GroupOrder = "   
            GROUP BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category  
            ORDER BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category', "; 
        break;

        case "months":
          $SelectRowNames = 
            "to_char(ipstimestamp, ''YYYYMM'') As row_name, 
            to_char(ipstimestamp, ''mon YYYY'') As labelled_row_name,   
            ''PlaceHolder1'' As PlaceHolder1,
            ''PlaceHolder2'' As PlaceHolder2,
            ''PlaceHolder3'' As PlaceHolder3,";
          $GroupOrder = "   
            GROUP BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category  
            ORDER BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category', "; 
        break;

        case "years":
          $SelectRowNames = 
            "to_char(ipstimestamp, ''YYYY'') As row_name, 
            to_char(ipstimestamp, ''YYYY'') As labelled_row_name,   
            ''PlaceHolder1'' As PlaceHolder1,
            ''PlaceHolder2'' As PlaceHolder2,
            ''PlaceHolder3'' As PlaceHolder3,";
          $GroupOrder = "   
            GROUP BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category  
            ORDER BY row_name, labelled_row_name, PlaceHolder1, PlaceHolder2, PlaceHolder3, objectid, category', "; 
        break;
        }   



    // echo "type ".$IpsTable." <br>";
    $SensorResult = GetSensorNames($SensorString, $TableType, "", "",0, 1);
    // echo "SensorResult: ".$SensorResult.chr(13);
    $CategoryString = implode(", ", pg_fetch_all_columns($SensorResult,$SensorColumn));
    $CategoryArray = pg_fetch_all_columns(GetSensorNames($SensorString, $TableType, "", "",0, 0),5); //array containing the name of each sensor

    // echo "<strong>CategoryString: </strong>". $CategoryString.chr(13)."<br><br><br><br>";
    //Print_r ($CategoryArray);


    //primary query (non-crosstabbed yet)
    $PrimaryQuery ="'SELECT ". $SelectRowNames. 
            "varid As category, " 
            .$AggregateFunctions
            ." FROM $IpsTable As log 
            JOIN ipsobjects_with_parent ips 
            ON log.varid = ips.objectid
            WHERE (ips.objectname LIKE ''".$SensorString."'') "
            . $WhereClause . "      
            AND (ipstimestamp > (now()- ''". $NoAbscissaBins . " " . $TimeUnit. "''::interval)) ". $GroupOrder ;

    // echo "<strong>PrimaryQuery: $PrimaryQuery</strong>";

    //main crosstab query which pulls all the content data:
    $MainCrosstabSelectQuery = 
        "SELECT * FROM crosstab
                    (" .$PrimaryQuery .
        "'SELECT DISTINCT varid 
        FROM $IpsTable As log 
        JOIN ipsobjects_with_parent ips 
        ON log.varid = ips.objectid
        WHERE (ips.objectname LIKE ''".$SensorString."'')
        ORDER BY 1;' 
        )

    As CountsPerHour(row_name text, 
                    label_row_name text, 
                    PlaceHolder1 text, 
                    PlaceHolder2 text, 
                    PlaceHolder3 text, "  
                    .$CategoryString.")";

    //echo "<br><font color='red'>$MainCrosstabSelectQuery</font><br>";

    $QueryResult=pg_query ($dbconn, $MainCrosstabSelectQuery);
    $CrosstabArray = pg_fetch_all($QueryResult);
    //echo "CrosstabArray: " . $CrosstabArray ;
    //$table = good_query_table($CrosstabArray, $QueryResult, 0);
    //BetterTable($QueryResult); //this functions outputs a nicely formatted crosstab!

    if (!$QueryResult) 
            echo "PG Error: ". pg_last_error().chr(13);

    // create bracketed Array of Arrays GoogleDataRow
    $GoogleDataRow ="["; //opening bracket inserted
    while ($field = pg_fetch_row($QueryResult)) 
    {

    $GoogleDataRow .="["; 
    $index =0;

    switch ($TableType)
    {
    case "boolean":
    foreach ($field as $col_value) {
            $index++;
            if ($index<6)
                    //the first five columns are strings (date headers)
                    {$GoogleDataRow .= "'".$col_value."', ";} 
                else{
                    //anythign above 5 is data
                    //substitute NULL with zeroes, else GoogleChart doesnt work
                    if($col_value == NULL) $col_value = "null";  
                    $GoogleDataRow .= $col_value.",    ";
                    }
                }
    break;

    case "integer":
    foreach ($field as $col_value) {
            ++$index;
            if ($index<6)
                    {//the first give columns are strings (date headers)
                    $GoogleDataRow .= "'".$col_value."', ";} 
                else{
                    //anythign above 5 is data
                    //substitute NULL with 5x zeroes, else GoogleChart doesnt work
                    if($col_value == NULL) $col_value = "null,null,null,null,null";  
                    $GoogleDataRow .= $col_value.",    ";
                    }
                }
    break;

    case "float":
    foreach ($field as $col_value) {
            ++$index;
            if ($index<6)
                    {//the first give columns are strings (date headers)
                    $GoogleDataRow .= "'".$col_value."', ";} 
                else{
                    //anythign above 5 is data
                    //substitute NULL with 5x zeroes, else GoogleChart doesnt work
                    if($col_value == NULL) $col_value = "null,null,null,null,null";  
                    $GoogleDataRow .= $col_value.",    ";
                    }
                }
    break;

    case "string":
    foreach ($field as $col_value) {
            ++$index;
            if ($index<5)
                    //the first give columns are strings (date headers)
                    {$GoogleDataRow .= "'".$col_value."', ";} 
                else{
                    //anythign above 5 is data
                    //substitute NULL with zeroes, else GoogleChart doesnt work
                    if($col_value == NULL) $col_value = 0;  
                    $GoogleDataRow .= $col_value." ";
                    }
                }
    break;
    }

    $GoogleDataRow = substr($GoogleDataRow,0,-5)."], ";

    //echo "<br><font color='blue'>$GoogleDataRow </font><br>"; 
    }


    $GoogleDataRow = substr($GoogleDataRow,0,-2)."]";

    $DataCollectionArray = array(
                        "GoogleDataRow"=>$GoogleDataRow,
                        "NumberOfColumns"=>pg_num_fields($QueryResult), // total number of columns, including all row headers
                        "CategoryArray"=>$CategoryArray,
                        "TableType"=>$TableType,
                        "DataTableName" => $DataTableName, 
                        "MainCrosstabSelectQuery" => $MainCrosstabSelectQuery 
                        );
    return $DataCollectionArray;
    }



    //---------------------------------------

    function BetterTable($result)
    {
    $i = 0;
    echo "<html>
            <body>
            <table>
            <table class='BetterTable' border='1'>";

    echo "<tr>";
    echo '<td>Line #
    </td>';
    while ($i < pg_num_fields($result))
    {
        $fieldName = pg_field_name($result, $i);
        echo '<td>' . $fieldName . '</td>';
        $i = $i + 1;
    }
    echo '</tr>';
    $i = 0;

    while ($field = pg_fetch_row($result)) 
    {
            if ($i%2 == 0) 
                Echo "<tr bgcolor=\"#d0d0d0\" >";
            else 
                Echo "<tr bgcolor=\"#eeeeee\">";
        $fields = count($field);
        $y = 0;
        echo '<td>'.$i. '</td>';
        while ($y < $fields)
        {
            $c_row = current($field);
            echo '<td>'.$c_row . '</td>';
            next($field);
            $y = $y + 1;
        }
        echo '</tr>';
        $i = $i + 1;
    }


    echo '</table><br><br></body></html>';

    }

    //----------------------------------------------------

    Function GetSensorNames($SensorType, $TableType, $prefix, $postfix, $QueryType, $column)
    {//TableType specifies the type of variable, and redirectes to the correct table.
    //prefix and postfix are adapters returned for each row
    //
    //retrieve full names of DataCollection variables, including parent names
    //QueryColumns specifies which query columns (see below)

    $dbconn = pg_connect("host=10.10.10.8  port=5432 dbname=IpsLogging user=*** password=***") 
        or die ('connection aborted: ' . pg_last_error().chr(13));


    switch ($TableType)
        {
        case "boolean":
            $IpsTable = "loggingdb_ips_boolean";
        break;
        case "integer":
            $IpsTable = "loggingdb_ips_integer";
        break;
        case "float":
            $IpsTable = "loggingdb_ips_float";
        break;
        case "string":
            $IpsTable = "loggingdb_ips_string";
        break;
        }
    // echo "type ".$IpsTable." <br>";


    if ($prefix!="") $prefix = $prefix." || ";
    if ($postfix!="")$postfix = " || ". $postfix;

    $GetSensorNamesString = 
    "SELECT 
    DISTINCT '\"' || varid ||'\"' || ' integer ' as integername,
    varid as NakedVariable, 
    '\"' || ips.parentname || ' - ' || ips.objectname || ' (' || ips.objectid || ')\"' || ' integer '  AS fullname,
    '\"' || ips.parentname || ' - ' || ips.objectname || ' (' || ips.objectid || ')\"' || ' numeric(8,2) '  AS fullnamenumeric,
    '\"' || ips.parentname || ' - ' || ips.objectname || ' (' || ips.objectid || ')\"' || ' text '  AS fullnamestring,
    '\"' || ips.parentname || ' - ' || ips.objectname || ' (' || ips.objectid || ')\"'  AS fullnamestring,
    ips.parentname || ' - ' || ips.objectname || ' (' || ips.objectid || ')' || ' text '  AS fullnamestringwithoutquotes,
    $prefix varid $postfix as DecoratedVariable

    FROM $IpsTable As log 
    JOIN ipsobjects_with_parent ips 
    ON log.varid = ips.objectid
    WHERE (ips.objectname LIKE '$SensorType')
    ORDER BY 1;
    ";
    //echo "<strong>$GetSensorNamesString</strong>"; 

    $QueryResult=pg_query ($dbconn, $GetSensorNamesString);
    if (!$QueryResult) 
            echo "PG Error: ". pg_last_error().chr(13);
        else
            {return $QueryResult;}
    }
    //-----------------------------
    Function ColumnLabel($TimeUnit)
    {
    switch ($TimeUnit)
    {
    case "minutes": $ColumnLabel= "0"; break;
    case "hours":   $ColumnLabel= "1"; break;
    case "days":    $ColumnLabel= "2"; break;
    case "months":  $ColumnLabel= "3"; break;
    case "years":   $ColumnLabel= "4"; break;}
    return($ColumnLabel);
    }
    //--------------------------------------------
    function VerboseEcho($Anything)
        {global $Verbose;
        if ($Verbose == true) Echo $Anything;}
    ?>

最佳答案

有一些工具可以在虚拟浏览器中呈现网页,然后可以截取屏幕截图或将网页导出为图像文件。这里最好的格式是 PNG,只是为了不降低图表中细节的可读性。

我在这里看到了类似的文章:How to screenshot website in JavaScript client-side / how Google did it? (no need to access HDD)

关于javascript - 在服务器端保存 Google Chart,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36292010/

相关文章:

php - jquery 点击隐藏和显示另一个按钮

php - 内爆特定的关联数组键值

php - 如何使用 KNPPaginatorBundle 对使用 Doctrine Repository 的结果进行分页?

postgresql - 将具有 DEFAULT 值的 COLUMN 添加到一个巨大的表中

javascript - Javascript 中的分数

javascript - jQuery 适用于多个按钮和 div

javascript - 导航下拉有圆 Angular 问题

postgresql - 建议使用 postgres 工具来查找模式和数据之间的差异

json - Postgres 函数返回一行作为 JSON 值

javascript - 选择下拉值显示一个div