Rails5 - 使用Controller Helper构建时间表图表

时间:2017-08-23 00:45:41

标签: ruby-on-rails ruby charts

我正在尝试使用Jira等软件构建类似于甘特图的时间线图表 - 为此,我尝试从帮助程序传递Google Charts 'Timeline' Module 4个参数。我正在使用ChartKick,但它无法使时间轴模块允许的任何可选参数变得柔和。

当前助手

  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], ...] 

为简洁而缩小,但数组正在输出Rails时间格式(我的错,我知道)。

所以我将其修改为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删除了双引号,但是如果不删除引号,我会在&上收到&quot;的错误JS的一部分{1}}。

更新2 - 格式

我意识到我的小数已经关闭,在比较了我看到的文档之后,我可以将{mm}加到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 个答案:

答案 0 :(得分: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