2017-08-23 32 views
1

我正在嘗試構建類似從Jira等軟件的甘特圖的時間線圖表 - 要做到這一點,我試圖從幫助程序中傳遞參數Google Charts 'Timeline' Module。我爲此使用ChartKick,但它無法平息時間軸模塊允許的任何可選參數。Rails5 - 使用控制器助手構建時間線圖

電流助手

def get_all_tasks 
    tasks = @project.tasks 
    sorted = tasks.order(:task_start_date) 
    sorted_task_array = [] 
    sorted.each do |s| 
     sorted_task_array << [s.product, s.task_name, s.task_start_date, s.task_end_date] 
    end 
    sorted_task_array.to_s.gsub('"', "'") 
    end 

這將輸出陣列如

[[Product, Comment, Thu, 02 Feb 2017 00:00:00 UTC +00:00, Tue, 02 May 2017 00:00:00 UTC +00:00], ...] 

縮小的爲了簡潔,但陣列輸出該滑軌時間格式(我的錯,我知道) 。

所以我修改它爲s.task_start_date.strftime("%F"),我實際上已經嘗試了strftime docs上的很多選項。

奇怪的是我也嘗試硬編碼新的Date()將輸出的格式。

AKA

> new Date(1789, 3, 30) 
1789-04-30T04:00:00.000Z 

我仍然對日期時間字段 '無效號碼'。

硬編碼他們的例子,或任何使用new Date()的例子似乎工作,所以我錯過了什麼?我不確定如何在不加倍JS的工作的情況下處理這個問題 - 當Rails可以轉換它時。

圖JS - 從示例

google.charts.load("current", {packages:["timeline"]}); 
    google.charts.setOnLoadCallback(drawChart); 
    function drawChart() { 
    var container = document.getElementById('example4.2'); 
    var chart = new google.visualization.Timeline(container); 
    var dataTable = new google.visualization.DataTable(); 

    dataTable.addColumn({ type: 'string', id: 'Role' }); 
    dataTable.addColumn({ type: 'string', id: 'Name' }); 
    dataTable.addColumn({ type: 'date', id: 'Start' }); 
    dataTable.addColumn({ type: 'date', id: 'End' }); 
    dataTable.addRows(
     <%= get_all_tasks %> 
     ) 
    var options = { 
     timeline: { groupByRowLabel: false } 
    }; 

    chart.draw(dataTable, options); 
    } 

思想的基本?

更新

我發現讓我在需要的格式的時候,我會用s.task_end_date.iso8601 - 不過,我仍然在時機越來越Uncaught SyntaxError: Invalid or unexpected token

有了這個新的錯誤,我想它可能是由於我的gsub被去掉雙引號,但沒有消除我得到&的錯誤是在JS的&quot;部輸出的報價。

更新2 - 格式

我意識到我的小數被關閉,並比較我看見我可以毫秒的量追加到iso8601的文檔後。

我現在有s.task_start_date.iso8601(3) , s.task_end_date.iso8601(3)它返回相同的確切格式爲新的Date(),但我仍然得到拒絕原因是:

Value 2017-02-02T00:00:00.000Z does not match type date in column index 2

+1

你可以做'tasks.order(:task_start_date).pluck(:產品:TASK_NAME,: task_start_date,:task_end_date).to_json'來代替。 – max

+0

@max哇 - 我甚至沒有想過使用這樣的採摘。將在多個助手中使用它。 – DNorthrup

回答

1

要解決這個問題,我不得不JavaScript的做沉重的舉重。

我用輔助函數返回數組中的數據,並使用strftime將日期時間設置爲我想要的。

def get_all_tasks 
    tasks = @project.tasks 
    sorted = tasks.order(:task_start_date) 
    sorted_task_array = [] 
    sorted.each do |s| 
     sorted_task_array << [s.product, s.task_name, s.task_start_date.strftime("%Y, %m, %d") , s.task_end_date.strftime("%Y, %m, %d") ] 
    end 
    sorted_task_array 
    end 

然後我有JavaScript處理包裝。

var data = <%= raw get_all_tasks %>; 
    var result = []; 
    for(var i = 0; i < data.length; i++){ 
     var row = [] 
     for (var j = 0; j < 2; j++){ 
      row.push(data[i][j]); 
     } 
     for (j=2; j < 4; j++){ 
      row.push(new Date(data[i][j])); 
     } 
     result.push(row); 
    } 
    google.charts.load("current", {packages:["timeline"]}); 
    google.charts.setOnLoadCallback(drawChart); 
    function drawChart() { 
    var container = document.getElementById('example4.2'); 
    var chart = new google.visualization.Timeline(container); 
    var dataTable = new google.visualization.DataTable(); 

    dataTable.addColumn({ type: 'string', id: 'Role' }); 
    dataTable.addColumn({ type: 'string', id: 'Name' }); 
    dataTable.addColumn({ type: 'date', id: 'Start' }); 
    dataTable.addColumn({ type: 'date', id: 'End' }); 
    dataTable.addRows(
     result 
     ) 
    var options = { 
     timeline: { groupByRowLabel: false } 
    }; 

    chart.draw(dataTable, options); 
    } 
</script> 

魔法發生在頂部,但它現在工作完美。

感謝@在這個問題max's評論我已經修改了幫手要簡單得多:

def get_all_tasks 
    @project.tasks.order(:product, :task_start_date).pluck(:product, :task_name, :task_start_date, :task_end_date).to_json 
    end 
+0

你應該在頂部聲明'var i,j;'。正如目前所寫,它們都是隱含的全局變量。 – max

+0

@max良好的捕獲 - 修正。謝謝。 – DNorthrup