Требуется руководство по использованию .map, .group, .pluck и т. д., чтобы сделать линейную диаграмму с несколькими сериями в приложении ruby ​​on rails.

Я пытаюсь отобразить линейную диаграмму с несколькими сериями, используя chartkick в приложении Ruby on Rails.

Диаграмма должна отображать paper_types и weightдля каждого типа в течение определенного периода времени.

СКРИНШОТ ДОБАВЛЕН

введите здесь описание изображения

Это моя последняя попытка:

<%= line_chart [                            
  {name: @pappi.map{|p| [p.paper_type]}, data: @pappi.map{|t| [t.date, t.paper_weight] }, 'interpolateNulls':true}
 ] %>

Где @pappi = Paper.all

Приведенный выше код выводится как на картинке ниже, где каждое paper_type округляется в одну строку, вместо того, чтобы показывать отдельные строки для каждого paper_type. введите здесь описание изображения

Я ищу диаграмму, похожую на скриншот ниже, где каждый тип бумаги имеет свою линию.

введите здесь описание изображения

Может ли кто-нибудь помочь мне с этим, чтобы я мог получить результат, который хочу?


person codegirl    schedule 09.08.2017    source источник
comment
Можете ли вы удалить большую часть содержимого этого ответа и определить: что вы хотите (может быть, скриншот в качестве примера?), контекст, который у вас есть (записи и их атрибуты, относящиеся к проблеме ) и что вы сделали (последние 2 попытки, которые были наиболее близки к ответу)   -  person MrYoshiji    schedule 10.08.2017
comment
да, я буду, дайте мне несколько минут :)   -  person codegirl    schedule 10.08.2017
comment
Поскольку сегодня я закрыл ваш повторяющийся вопрос, а у вас недостаточно репутации, чтобы назначить награду, я сделаю все возможное, чтобы помочь вам решить эту проблему.   -  person MrYoshiji    schedule 10.08.2017
comment
Спасибо, @MrYoshiji, вы очень любезны, я отредактировал вопрос и добавил образец изображения из документации по чартам.   -  person codegirl    schedule 10.08.2017
comment
следуя примеру line_chart, вам необходимо предоставить массив хэшей, каждый хеш определяет пару ключ/значение name (значение будет отображаться в легенде) и пару ключ/значение data (значение содержит хэш пар ключ/значение , где ключ — дата, значение — число).   -  person MrYoshiji    schedule 10.08.2017
comment
спасибо @MrYoshiji, не могли бы вы привести мне пример, я чувствую себя потерянным здесь :)   -  person codegirl    schedule 10.08.2017


Ответы (2)


Я не проверял это, только прочитал документ и пришел к следующему выводу:

line_chart ожидает, что вы предоставите аргумент, структурированный следующим образом: (из документации Javascript)

line_chart [
  { name: 'Line1', data: { '2017-01-01' => 2, '2017-01-08' => 3 } },
  { name: 'Line2', data: { '2017-01-01' => 1, '2017-01-08' => 7 } },
]
# try it in your view to make sure it works as described below

Это создаст диаграмму с двумя линиями (Line1 и Line2), горизонтальная ось будет содержать 2 значения 2017-01-01 и 2017-01-08, а вертикальная ось будет шкалой, вероятно, от 1 до 7 (мин. от данных до максимум из данных).


Следуя этой структуре данных в вашем контексте:

Технические характеристики (поправьте меня, если я ошибаюсь):

  • одна строка для каждого отдельного paper_type
  • weight значение для данного paper_type и данной даты

Сопоставление объектов в соответствии с желаемой структурой данных:

# controller
all_paper_type_values = Paper.all.pluck(:paper_type).uniq
@data_for_chart = all_paper_type_values.map do |paper_type|
  { name: paper_type, data: Paper.where(paper_type: paper_type).group_by_month(:created_at).sum(:weight) }
end

# view
<%= line_chart(@data_for_chart) %>

Это не относится к какому-либо пользователю/дате (периоду). Вам нужно будет включить это в код выше.

Попробуйте это и дайте мне знать, если это не удастся.

person MrYoshiji    schedule 10.08.2017
comment
спасибо @MrYoshiji, это работает, но меня беспокоит, как я могу показать разные типы paper_types и paper_weights с помощью этого метода. У одного пользователя может быть 4 типа бумаги (газета, журналы, офисная бумага и другая бумага), а у другого пользователя может быть только два типа бумаги для отображения (газета и офисная бумага). Для этого пользователя у меня был бы график, показывающий только эти два типа, но не все четыре. - person codegirl; 10.08.2017
comment
не видел вашу правку перед комментом, посмотрю - person codegirl; 10.08.2017
comment
Я получаю undefined local variable or method data_for_chart' для #‹#‹Class:0x007fc7694aea60›:0x007fc768448c70›` - person codegirl; 10.08.2017
comment
Да, это работает на 95%, теперь у меня есть отдельные строки для каждого типа бумаги, но вес не отображается. Добавил скриншот к вопросу как это выглядит сейчас - person codegirl; 10.08.2017
comment
Итак, как видно на скриншоте, который я добавил, легенда показывает количество записей для каждого типа бумаги. Я могу понять, что это потому, что код не показывает никакого paper_weight, теперь меня беспокоит, как добавить paper_weight в код, чтобы он отображался в легенде? - person codegirl; 10.08.2017
comment
Каков результат и/или SQL, сгенерированный для Paper.grouped_by_month(:created_at)? Инструкция .count подсчитывает записи вместо суммирования значения weight всех этих записей. - person MrYoshiji; 10.08.2017
comment
вот что я понимаю, я не совсем понимаю irb(main):005:0> Paper.group_by_month(:created_at) Paper Load (5.1ms) SELECT "papers".* FROM "papers" WHERE (created_at IS NOT NULL) GROUP BY (DATE_TRUNC('month', (created_at::timestamptz - INTERVAL '0 hour') AT TIME ZONE 'Etc/UTC') + INTERVAL '0 hour') AT TIME ZONE 'Etc/UTC' ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "papers.id" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: SELECT "papers".* FROM "papers" WHERE (created_at IS NOT NUL... - person codegirl; 10.08.2017
comment
Можешь попробовать Paper.grouped_by_month(:created_at).sum(:weight)? И наконец Paper.grouped_by_month(:created_at).select('SUM(weight) as total_weight') - person MrYoshiji; 10.08.2017
comment
Я получаю irb(main):007:0> Paper.group_by_month(:created_at).sum(:paper_weight) (9.9ms) SELECT SUM("papers"."paper_weight") AS sum_paper_weight, (DATE_TRUNC('month', (created_at::timestamptz - INTERVAL '0 hour') AT TIME ZONE 'Etc/UTC') + INTERVAL '0 hour') AT TIME ZONE 'Etc/UTC' AS month FROM "papers" WHERE (created_at IS NOT NULL) GROUP BY (DATE_TRUNC('month', (created_at::timestamptz - INTERVAL '0 hour') AT TIME ZONE 'Etc/UTC') + INTERVAL '0 hour') AT TIME ZONE 'Etc/UTC' => {Sat, 01 Apr 2017 00:00:00 UTC +00:00=>#<BigDecimal:7f8887a17680,'0.621E3',9(18)>, Mon, 01 May 2017 слишком много времени - person codegirl; 10.08.2017
comment
Это идеально. Используйте этот .sum(:weight) вместо .count в своем коде (см. обновленный ответ) - person MrYoshiji; 10.08.2017
comment
Фантастика!!!! @MrYoshiji, ты просто сделал мой день!!!! Большое спасибо за вашу помощь - person codegirl; 10.08.2017
comment
Я рад помочь. Я предполагаю, что вы сможете фильтровать Paper на основе желаемого пользователя и/или периода времени. - person MrYoshiji; 10.08.2017
comment
Да точно, теперь вроде работает как надо - person codegirl; 10.08.2017

Что произойдет, если вы поместите любую из этих опций в консоль рельсов? Вы получаете несколько серий данных?

Ты пытался?

<%= line_chart [ name: paper.paper_type, data: current_user.papers.group(:paper_type).group_by_week(:created_at).count ] %>

person Stuart    schedule 09.08.2017
comment
Спасибо @Stuart, да, я пробовал это, это дает просто пустой график - person codegirl; 09.08.2017
comment
Я не уверен, как мне поместить эти параметры в консоль, поскольку я новичок в этом и во всем :) - person codegirl; 10.08.2017
comment
В терминале введите rails c. Вы сделали это? Если нет, вы можете прочитать об этом здесь: guides.rubyonrails.org/command_line.html. Оказавшись там, вы можете сделать current_user.papers.group(:paper_type).group_by_week(:created_at).count, чтобы увидеть, каковы результаты. Я бы тратил на это время. Когда вы получите данные, которые выглядят правильно, попробуйте диаграмму. - person Stuart; 10.08.2017