2017-04-05 61 views
0

當前使用Angular JS和ChartJS嘗試在我的頁面上放置圖表。數據是通過NodeJS中的路由請求的,然後這些函數通過響應中的線索進行循環,並嘗試計算一個月中每天創建的數量。Chartjs/Javascript - 我的功能沒有正確返回數組,但控制檯日誌沒問題

當我控制檯登錄LeadsPerDay時,它會返回一個數組,其中包含我所期望的所有內容,但圖表似乎並未適當呈現這些點。它們全都落在底部,它告訴我找到我的陣列,因爲如果我把它拿出來,沒有點。如果我手動放入數組,它會正確渲染。

var ctx = document.getElementById("myChart"); 
var myChart = new Chart(ctx, { 
    type: 'line', 
    data: { 
    labels: getDaysInMonth(currentMonth, currentYear), 
    datasets: [{ 
     label: '# new leads created', 
     data: getLeadsForMonth(currentMonth, currentYear), 
     backgroundColor: [ 
     'rgba(255, 99, 132, 0.2)' 
     ], 
     borderColor: [ 
     'rgba(255,99,132,1)' 
     ], 
     borderWidth: 1 
    }] 
    }, 
    options: { 
    scales: { 
     yAxes: [{ 
     ticks: { 
      beginAtZero: true 
     } 
     }] 
    } 
    }, 
    maintainAspectRatio: false 
}); 

function getDaysInMonth(month, year) { 
    var date = new Date(year, month, 1); 
    var dates = []; 
    while (date.getMonth() === month) { 
    var currentDate = new Date(date).toISOString().replace(/T.*/, '').split('-').reverse().join('-'); 
    var catDate = currentDate.replace(/-2017/g, '').replace(/-/g, '/').split('/').reverse().join('/');; 
    dates.push(catDate); 
    date.setDate(date.getDate() + 1); 
    } 
    return dates; 
} 

function getLeadsForMonth(month, year) { 

    // Create empty array to put leadCount in 
    var leadsPerDay = new Array(); 

    /* Use $http.get to fetch contents*/ 
    $http.get('/pipedrive/getLeadsForMonth', function() {}).then(function successCallback(response) { 

    // Loop through each lead and index them based on date 
    var leads = response.data.data[0].deals; 
    // Set date to first of the month 
    var date = new Date(year, month, 1); 
    // Define the month for the loop 
    var currentMonth = date.getMonth(); 

    // Loop through the days in the month 
    while (date.getMonth() === currentMonth) { 
     // Save the date 
     var currentDate = new Date(date).toISOString().replace(/T.*/, ''); 
     date.setDate(date.getDate() + 1); 
     leadCount = 0; 
     // Loop through each lead and search data for date 
     for (i = 0; i < leads.length; i++) { 
     if (leads[i].add_time.includes(currentDate)) { 
      leadCount++ 
     } 
     } 
     leadsPerDay.push(leadCount); 
    } 
    }, function errorCallback(response) { 
    console.log('There was a problem with your GET request.') 
    }); 
    console.log(leadsPerDay); 
    return leadsPerDay; 
} 

回答

0

的這裏的問題是,圖表正在呈現之前的數據實際上是從你的函數返回,因爲您正在爲您的端點的異步調用。

以下是當前流程。

1)您實例化一個新圖表,然後同步調用2個函數以獲取標籤(getDaysInMonth)和數據(getLeadsForMonth)。

2)標籤函數返回標籤數據沒有問題。然後數據功能會對端點進行異步調用以獲取數據。 $http.get返回Promise,並在準備就緒時處理結果並構建數據數組。不幸的是,在這一點上,getLeadsForMonth的初始調用已經返回一個空數組。

您能夠使用console.log看到您的數據的原因可能只是一個計時問題。當瀏覽器執行該語句時,已經返回$http.get(特別是如果您在locahost上運行該語句時),並且數據現在存在於數組中(但是該圖表已經呈現,因此它不會顯示它)。

既然您是異步獲取您的數據,您有幾個選項。

1)等待數據獲取後創建你的圖表。您可以通過在$http.get回調中移動圖表創建代碼來完成此操作。像這樣...

function getDaysInMonth(month, year) { 
    var date = new Date(year, month, 1); 
    var dates = []; 
    while (date.getMonth() === month) { 
    var currentDate = new Date(date).toISOString().replace(/T.*/, '').split('-').reverse().join('-'); 
    var catDate = currentDate.replace(/-2017/g, '').replace(/-/g, '/').split('/').reverse().join('/');; 
    dates.push(catDate); 
    date.setDate(date.getDate() + 1); 
    } 
    return dates; 
}; 

function createChart(month, year) { 
    // generate the labels 
    var labels = getDaysInMonth(month, year), 

    // Create empty array to put leadCount in 
    var leadsPerDay = new Array(); 

    /* Use $http.get to fetch contents*/ 
    $http.get('/pipedrive/getLeadsForMonth', function() {}).then(function successCallback(response) { 

    // Loop through each lead and index them based on date 
    var leads = response.data.data[0].deals; 
    // Set date to first of the month 
    var date = new Date(year, month, 1); 
    // Define the month for the loop 
    var currentMonth = date.getMonth(); 

    // Loop through the days in the month 
    while (date.getMonth() === currentMonth) { 
     // Save the date 
     var currentDate = new Date(date).toISOString().replace(/T.*/, ''); 
     date.setDate(date.getDate() + 1); 
     leadCount = 0; 
     // Loop through each lead and search data for date 
     for (i = 0; i < leads.length; i++) { 
     if (leads[i].add_time.includes(currentDate)) { 
      leadCount++ 
     } 
     } 
     leadsPerDay.push(leadCount); 
    } 

    var ctx = document.getElementById("myChart"); 
    var myChart = new Chart(ctx, { 
     type: 'line', 
     data: { 
     labels: labels, 
     datasets: [{ 
      label: '# new leads created', 
      data: leadsPerDay, 
      backgroundColor: [ 
      'rgba(255, 99, 132, 0.2)' 
      ], 
      borderColor: [ 
      'rgba(255,99,132,1)' 
      ], 
      borderWidth: 1 
     }] 
     }, 
     options: { 
     scales: { 
      yAxes: [{ 
      ticks: { 
       beginAtZero: true 
      } 
      }] 
     } 
     }, 
     maintainAspectRatio: false 
    }); 
    }, function errorCallback(response) { 
    console.log('There was a problem with your GET request.') 
    }); 
}; 

createChart(currentMonth, currentYear); 

2)創建一個空的圖表,然後使用.update()原型方法時所獲得的數據來重新呈現圖表。事情是這樣的......

var ctx = document.getElementById("myChart"); 
var myChart = new Chart(ctx, { 
    type: 'line', 
    data: { 
    labels: getDaysInMonth(currentMonth, currentYear), 
    datasets: [{ 
     label: '# new leads created', 
     data: [], 
     backgroundColor: [ 
     'rgba(255, 99, 132, 0.2)' 
     ], 
     borderColor: [ 
     'rgba(255,99,132,1)' 
     ], 
     borderWidth: 1 
    }] 
    }, 
    options: { 
    scales: { 
     yAxes: [{ 
     ticks: { 
      beginAtZero: true 
     } 
     }] 
    } 
    }, 
    maintainAspectRatio: false 
}); 

getLeadsForMonthAndUpdateChart(myChart, currentMonth, currentYear); 

function getLeadsForMonthAndUpdateChart(chart, month, year) { 
    // Create empty array to put leadCount in 
    var leadsPerDay = new Array(); 

    /* Use $http.get to fetch contents*/ 
    $http.get('/pipedrive/getLeadsForMonth', function() {}).then(function successCallback(response) { 

    // Loop through each lead and index them based on date 
    var leads = response.data.data[0].deals; 
    // Set date to first of the month 
    var date = new Date(year, month, 1); 
    // Define the month for the loop 
    var currentMonth = date.getMonth(); 

    // Loop through the days in the month 
    while (date.getMonth() === currentMonth) { 
     // Save the date 
     var currentDate = new Date(date).toISOString().replace(/T.*/, ''); 
     date.setDate(date.getDate() + 1); 
     leadCount = 0; 
     // Loop through each lead and search data for date 
     for (i = 0; i < leads.length; i++) { 
     if (leads[i].add_time.includes(currentDate)) { 
      leadCount++ 
     } 
     } 
     leadsPerDay.push(leadCount); 
    } 

    // add the data to the chart and re-render 
    chart.data.datasets[0].data = leadsPerDay; 
    chart.update(); 
    }, function errorCallback(response) { 
    console.log('There was a problem with your GET request.') 
    }); 
}; 

這裏是一個codepen example演示給你看還有第二個選項(用新數據更新圖表)。

+0

Bravo!謝謝你這麼徹底的解釋。 – Dadsquatch