2017-10-30 5 views
1

아래에 설명 된 시스템을 만들었습니다.너무 많은 데이터가 포함 된 amCharts 그래픽을 효과적으로 그리는 방법

Linux에서 실행중인 일부 장치가 있습니다. 이 기기는 몇 가지 정보를 보냅니다. 로드 평균 용량, 사용 가능한 메모리 양, 일련 번호 및 가동 시간을 데이터베이스에 지속적으로 (매 30 초마다) 표시합니다. 그런 다음이 데이터를 가져 와서 웹 페이지에 표시하고 차트를 만듭니다. 그것은 간단한 시스템입니다. 웹 페이지 용 PHP, 데이터베이스 작업용 PDO, 차트 용 amChart를 사용했습니다. 무료 메모리 및 평균 데이터로드를위한 차트를 그립니다. 그러나 성능에 문제가 있습니다. 문제를 예제로 설명하겠습니다. 사용 가능한 메모리 데이터를 살펴 보겠습니다.

30 초마다 데이터를 데이터베이스로 보냅니다. 데이터가 7 일 동안 계속 전송된다고 가정합니다. 즉, (60/30) * 60 * 24 * 7 ~ 20000 행은 7 일 후에 단일 장치의 사용 가능 메모리 차트를 그리기 위해 데이터베이스에서 가져와야 함을 의미합니다. 모든 재로드에서 나는 모두 20000 개의 행을 모두 가져와야했습니다. 10 개 이상의 장치가 있기 때문에 페이지를 다시로드하는 데 너무 많은 시간과 성능이 소요됩니다. chart with 20000 rows

내가 뭐하는 거지 것은 :

이 차트는 20000 행 모습입니다

이 getchartdata.php에 일괄 배열로 데이터베이스에서 모든 사용 가능한 메모리의 데이터를 가져 오기

if (isset($_POST["SerialNumber"]) && isset($_POST["Type"])) { 
    $serialNumber = $_POST["SerialNumber"]; 
    $type = $_POST["Type"]; 
    if ($type == "LoadAverage") { 
     $loadavg =$crud->getLoadAvg($serialNumber); 
     echo json_encode($loadavg); 
    } 
    elseif ($type == "Free") { 
     $freemem =$crud->getFreeMem($serialNumber); 
     echo json_encode($freemem); 
    } 
} 

index.php에서 저는 achart를 사용하여 getchartdata.php에서 자바 스크립트로 데이터를 가져옵니다. 콜백 함수를 사용하여 데이터를 사용합니다. 그리고 나서 나는 각 다이빙을 차트로 채 웁니다.

$(document).ready(function(){ 
    $(".device").each(function() { 
     //In index.php, I use other php functions to get serial numbers and fill divs with each device's serial number. 
     serialNumber = $(this).text().trim(); 

     //I use local storage to keep "active" tab info. This way when I click the related div, it will get active and this code block will be executed. 
     if (localStorage.getItem("active") == serialNumber) { 
      $(this).addClass('active'); 
      $("#" + serialNumber).addClass("active"); 
      getChartInfo(serialNumber, "LoadAverage", createChart); 
      getChartInfo(serialNumber, "Free", createChart); 
     } 
     else if (localStorage.getItem("active") == null || localStorage.getItem("active") == "") { 
      $('.nav-tabs li:first').addClass('active'); 
      $('.tab-pane:first-child').addClass('active'); 
      serialNumber = $('.nav-tabs li:first').text().trim(); 
      getChartInfo(serialNumber, "LoadAverage", createChart); 
      getChartInfo(serialNumber, "Free", createChart); 
     }  
    }); 

    $(".device a").click(function() { 
     getChartInfo($(this).text(), createChart); 
     if ($(".device").hasClass('active')) { 
      localStorage.setItem("active", $(this).text()) 
      $("#status-" + $(this).text()).addClass("active"); 
     } 
    }); 

function getChartInfo(SerialNumber, Type) { 
    //Types: LoadAverage, Free 

    var postData = 'SerialNumber='+SerialNumber+'&Type='+Type; 
    divId = Type + "-" + SerialNumber 

    $.ajax({ 
     type:'POST', 
     url:'getchartdata.php', 
     data:postData, 
     success:function(ajaxResponse){ 
      ///console.log(ajaxResponse); 
      createChart(ajaxResponse, Type, SerialNumber); 
     }, 
     dataType:"json" 
    }); 
} 

function createChart(ajaxResponse, Type, SerialNumber) { 
    //console.log(ajaxResponse); 
    var chartData = []; 

    for(var a in ajaxResponse) { 
     date1 = new Date(a); 

     chartData.push({ 
      date: date1, 
      loadavg: ajaxResponse[a] 
     }); 
    } 
    console.log(chartData); 
    console.log(divId+"-first"); 

    if (Type == "LoadAverage") { 
     console.log("loadaverage"); 
     divId = Type + "-" + SerialNumber 
     console.log(divId+"-load"); 
     var chart = AmCharts.makeChart(divId, { 
      "type": "serial", 
      "theme": "light", 
      "marginRight": 80, 
      "dataProvider": chartData, 
      "valueAxes": [{ 
       "position": "left", 
       "title": "Load Average" 
      }], 
      "graphs": [{ 
       "id": "g1", 
       "fillAlphas": 0.4, 
       "valueField": "loadavg", 
       "balloonText": "<div style='margin:5px; font-size:19px;'><b>[[value]]</b></div>" 
      }], 
      "chartScrollbar": { 
       "graph": "g1", 
       "scrollbarHeight": 80, 
       "backgroundAlpha": 0, 
       "selectedBackgroundAlpha": 0.1, 
       "selectedBackgroundColor": "#888888", 
       "graphFillAlpha": 0, 
       "graphLineAlpha": 0.5, 
       "selectedGraphFillAlpha": 0, 
       "selectedGraphLineAlpha": 1, 
       "autoGridCount": true, 
       "color": "#AAAAAA" 
      }, 
      "chartCursor": { 
       "categoryBalloonDateFormat": "JJ:NN, DD MMMM", 
       "cursorPosition": "mouse" 
      }, 
      "categoryField": "date", 
      "categoryAxis": { 
       "minPeriod": "mm", 
       "parseDates": true 
      }, 
      "export": { 
       "enabled": true, 
       "dateFormat": "YYYY-MM-DD HH:NN:SS" 
      } 
     }); 
    chart.addListener("dataUpdated", zoomChart); 
    chart.zoomToIndexes(chartData.length - 1000, chartData.length); 

    } 

    if (Type == "Free") { 
     console.log("free"); 
     divId = Type + "-" + SerialNumber 
     console.log(divId+"-free") 
     var chart1 = AmCharts.makeChart(divId, { 
      "type": "serial", 
      "theme": "light", 
      "marginRight": 80, 
      "dataProvider": chartData, 
      "valueAxes": [{ 
       "position": "left", 
       "title": "Free Memory" 
      }], 
      "graphs": [{ 
       "id": "g1", 
       "fillAlphas": 0.4, 
       "valueField": "loadavg", 
       "balloonText": "<div style='margin:5px; font-size:19px;'><b>[[value]]</b></div>" 
      }], 
      "chartScrollbar": { 
       "graph": "g1", 
       "scrollbarHeight": 80, 
       "backgroundAlpha": 0, 
       "selectedBackgroundAlpha": 0.1, 
       "selectedBackgroundColor": "#888888", 
       "graphFillAlpha": 0, 
       "graphLineAlpha": 0.5, 
       "selectedGraphFillAlpha": 0, 
       "selectedGraphLineAlpha": 1, 
       "autoGridCount": true, 
       "color": "#AAAAAA" 
      }, 
      "chartCursor": { 
       "categoryBalloonDateFormat": "JJ:NN, DD MMMM", 
       "cursorPosition": "mouse" 
      }, 
      "categoryField": "date", 
      "categoryAxis": { 
       "minPeriod": "mm", 
       "parseDates": true 
      }, 
      "export": { 
       "enabled": true, 
       "dateFormat": "YYYY-MM-DD HH:NN:SS" 
      } 
     }); 

    chart1.addListener("dataUpdated", zoomChart); 
    chart1.zoomToIndexes(chartData.length - 1000, chartData.length); 

    } 
    // when we apply theme, the dataUpdated event is fired even before we add listener, so 
    // we need to call zoomChart here 
    zoomChart(); 
    // this method is called when chart is first inited as we listen for "dataUpdated" event 
    function zoomChart() { 
     // different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues 
    } 
} 

이렇게 많이 지속적으로 증가하는 데이터로 차트를 효과적으로 그리려면 어떻게해야합니까? 설명을 놓친 부분이있을 수 있습니다. 제게 부탁하면 더 설명 할 수 있습니다.

감사합니다.

답변

1

큰 날짜 기반 데이터 세트의 경우 AmCharts의 주가 차트를 사용하는 것이 좋습니다. 이 기능은 데이터 그룹화 기능과 함께 사용 사례에 맞게 설계되어 표시되는 포인트의 양을 최소화하여 성능을 향상시킵니다. 일반적인 AmCharts JavaScript 라이브러리의 직렬 차트는 해당 데이터 포인트 수의 극히 일부만 처리 할 수 ​​있습니다.

한 번에 여러 차트를로드하는 경우 일반적으로 권장되는 몇 가지 방법은 각 차트를 스크롤하여보기로 스크롤하거나 초기화/업데이트를 데이지 체인 방식으로 연결하는 것입니다. 이러한 기술에 대한 자세한 설명은 in this answer에서 확인할 수 있습니다.

+0

감사합니다. 주식 차트가이 경우에 필요한 것 같습니다. 주식 차트와 데이지 체이닝 초기화를 시도하고 결과를 되돌아 보겠습니다. – Ryuga

1

직접적인 대답은 드릴 수 없습니다. 한 번에 모든 20.000 기록을 얻을 수없는 경우

  1. , 당신이 당신의 차트를 단순화하거나 만들 수 있습니다 : 나는 때문에 나의 현재의 명성 댓글을 추가 할 수는 없지만, 나는 여기에이 제안을 줄 것이다 예를 들어 1000 개의 레코드 만 보여주는 더 단순화 된 amChart.

  2. 이러한 레코드를 모두 amChart로 가져와야하는 경우 "비동기"레코드 가져 오기를 사용하는 것이 좋습니다. 이렇게하면 "하나의"데이터베이스 쿼리를 다양한 비동기 쿼리로 나눌 수 있습니다.

@xorspark에서 언급했듯이 차트를 여러 차트로 나눌 수 있고 지연로드를 사용할 수 있습니다.

그러나 여러 차트를 지연로드 및 비동기 레코드 가져 오기와 병합하는 것이 좋습니다.