I'm trying to sort/order my records to display them in Chart.js
I want to display meal orders from Monday to Sunday with ascending order, there are 3 different meals every day. It's kinda working if every meal if present on each day, but if one kind of meal isn't ordered, for example, the order of the days gets weird.
Here is an example where it isn't working as I intended:
So as you see (don't mind the german language :D) the starting is right Monday, ... Thursday, ... Saturday, that's fine, but the order on Friday (the green one) is another meal as on the other days and so Friday is shown after Saturday, but I want it to be shown between Thursday and Saturday.
Here are my queries for ActiveRecord:
def self.weeklyVollkostOverview
where(day: Date.today.beginning_of_week..Date.today.end_of_week).where(dish_type: 0).group(:day).order("day ASC").count
end
def self.weeklySchonkostOverview
where(day: Date.today.beginning_of_week .. Date.today.end_of_week).where(dish_type: 1).group(:day).order("day ASC").count
end
def self.weeklyVegetarischOverview
where(day: Date.today.beginning_of_week .. Date.today.end_of_week).where(dish_type: 2).group(:day).order("day ASC").count
end
In my controller, I'm mapping the results:
#weeklyVoll = OrderCard.weeklyVollkostOverview.map { |key, value| [I18n.l(key, format: "%A", locale: :'de'), value]}
#weeklySchon = OrderCard.weeklySchonkostOverview.map { |key, value| [I18n.l(key, format: "%A", locale: :'de'), value]}
#weeklyVegetarisch = OrderCard.weeklyVegetarischOverview.map { |key, value| [I18n.l(key, format: "%A", locale: :'de'), value]}
Finally, I display the results in my chart.
Is there anything I could do different or that's easier?
I know I could use Groupdate-Gem, but there's an issue for date objects and time zone conversion, so I'm trying to do it manually.
EDIT:
The variables #weeklyVoll, #weeklySchon, and #weeklyVegetarisch are for display purposes in my view where the charts are:
<%= column_chart [
{ name: "# Bestellungen Vollkost", data: #weeklyVoll },
{ name: "# Bestellungen Schonkost", data: #weeklySchon },
{ name: "# Bestellungen Vegetarisch", data: #weeklyVegetarisch }
],
colors: ["red", "yellow", "green"],
xtitle: "Wochentag",
ytitle: "# Bestellungen",
legend: true,
legend: "bottom",
messages: { empty: "Noch keine Daten vorhanden!" },
library: { scales: { yAxes: [{ gridLines: { display: true }, ticks: { precision: 0 } } ] }, animation: {easing: 'easeOutQuad', duration: 2500} }
%>
Any help is appreciated! Thanks!
I think the issue is having the three different arrays. If you were to group on day/dish_type and then call count at the end it should give a results like ['Day', 'Dish Type'] => 3. You would then have to iterate through and format again as needed. I tend to use each_with_object.
OrderCard.where(day: Date.today.all_week)
.group(:day, :dish_type).count
# => ['Day', 'Dish Type'] => 3
Related
I am building an Rails 5 app with an Angular 7 frontent.
In this app I am using Searchkick (an Elasticsearch gem) and I have indexed a model called Event that got attributes title (string) and starts_at (datetime).
I want to be able to build a query in the search controller where I am able to do the following:
Search the title with a fuzzy search meaning it do not have to match 100% (which it now require).
Search with a date range matching starts_at for the indexed Events.
This is my controller index method
def index
args = {}
args[:eventable_id] = params[:id]
args[:eventable_type] = params[:type]
args[:title] = params[:title] if params[:title].present?
if params[:starts_at].present?
args[:starts_at] = {}
args[:starts_at][:gte] = params[:starts_at].to_date.beginning_of_day
args[:starts_at][:lte] = params[:ends_at].to_date.end_of_day
end
#events = Event.search where: args, page: params[:page], per_page: params[:per_page]
end
I have added this line to my Event model
searchkick text_middle: [:title]
This is the actual query that is run
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": [{
"term": {
"eventable_id": "2"
}
}, {
"term": {
"eventable_type": "Space"
}
}, {
"term": {
"title": "nice event"
}
}, {
"range": {
"starts_at": {
"from": "2020-02-01T00:00:00.000Z",
"include_lower": true,
"to": "2020-02-29T23:59:59.999Z",
"include_upper": true
}
}
}]
}
},
"timeout": "11s",
"_source": false,
"size": 10000
}
The date search does not work (but I get no errors) and the title search must match 100% (even the case).
Thankful for all help!
Rather than using Fuzzy queries, I would recommend an ngram analyzer.
Here is an example of an ngram analyzer:
analyzer: {
ngram_analyzer: {
type: "custom",
tokenizer: "standard",
filter: ["lowercase", "ngram_filter"],
char_filter: [
"replace_dots"
]
}
},
filter: {
ngram_filter: {
type: "ngram",
min_gram: "3",
max_gram: "20",
}
}
You will also have to add this code to your settings index:
max_ngram_diff: 17
Then on your mapping, make sure you create two fields. 1 mapping for your regular field such as name and then another mapping for your ngram field such as name.ngram.
In my query, I like to give my name field a boost of 10 and my name.ngram field a boost of 5 so that the exact matches will be rendered first. You will have to play with this though.
In regard to your range query, I am using gte and lte. Here is an example:
query:{
bool: {
must: {
range: {date: {gte: params[:date], lte: params[:date], boost: 10}}
}
}
}
I hope this helps.
I need to get Array response from rails moingo cipher query.
Group By date
[["Mar 26, 2016", 5],["Mar 27, 2016", 5],["Mar 29, 2016",8],["Mar 30, 2016",5],["Apr 1, 2016",5]]
Group by year
[["2013", 15],["2014", 225],["2015",8],["2016",5],["2017",5]]
I have done same thing with ruby group_by and map, But need to do with mongo query.
If you want to use mongo query for group_by, you can use aggregation.
You can read more about aggregation from mongo official doc
https://docs.mongodb.com/manual/reference/operator/aggregation/month/
example:
ModalName.collection.aggregate([ { "$group": { _id: { month: {"$month": "$created_at"}, year: {"$year": "$created_at"} }, count: { "$sum": 1 } } } ] ).to_a
You should use group_by(&:field_name)
#Model
class Flow
include Mongoid::Document
field :title, type: String
field :category_name, type: String
end
# Rails console
Flow.all.group_by(&:category_name)
# Result
{"album"=>
[#<Flow _id: ...)>,]}
I am building a helpdesk application. I have a model called TicketDetail, with a table which uses datatables to get its data via JSON. This is in order to periodically recalculate the time a ticket has been open. The time taken is formatted by a simple helper so it's in the format "dd:hh:mm", but it should be sorted by the time (stored as a decimal) multiplied by a weighting. Here's the datatables definition
var table = $('#ticket_details').DataTable({
order: [[ 8, "desc" ], [ 9, "desc" ], [ 2, "asc" ]],
stateSave: true,
deferRender: true,
ajax: $('#ticket_details').data('source'),
"columns": [
{ "data": "reference_number" },
{ "data": "location" },
{ "data": "title" },
{ "data": "parent", className: "hidden-md hidden-sm hidden-xs" },
{ "data": { _:"time_display.time", sort: "time_display.decimal_time"}},
{ "data": "created_by", className: "hidden-md hidden-sm hidden-xs" }
]
} );
setInterval( function () {
table.ajax.reload( null, false ); }, 60000 );
Here's a simplified sample record, where the ticket has been open 3 days and 6 hours, with a weighting of x2 (i.e. 3.25 * 2 = 6.5:
{
data: [
{
id: 140,
parent: null,
title: "[",
location: "Bond St",
ticket_sla: "16 Hours",
reference_number: "1606210001",
ticket_sla_weighting: 2,
time_display: {
time: "<span class = "label label-danger">03:06:00</span>",
decimal_time: 6.5
}
]
}
The problem is that the datatable sorts correctly if I display the decimal_time, but as soon as I put the formatted time in the class, it sorts simply by the number of days, immediately to the left of the colon. (So 03:06:00 and 03:18:00 would not get sorted properly).
For Date/Time sorting in DataTable You need to use it's Sorting plug-ins
For Example,
You need to include this js files :
//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js
//cdn.datatables.net/plug-ins/1.10.12/sorting/datetime-moment.js
and then, In your jQuery use this as
$.fn.dataTable.moment( 'HH:mm MMM D, YY' ); // Pass your date time format as param
For Deeper reference please check :
Sorting Plugins
Ultimate date / time sorting plugin
I'm trying to create a mixed column/line chart using Highcharts.
I've been trying to use the library functionality to set one of my data series to be of type "line". I have tried a few different approaches, but I can't seem to figure out how to pass the type parameter of a given series using the Highcharts API.
<%= column_chart( ChartData.new(#forecast).revenue_and_net_income, library: {
title: {
text: "Revenue and Net Income"
},
series: [{
1 => {
type: "line"
}
}],
} ) %>
Where my data come from the following method:
def revenue_and_net_income
data = [
{
name: "Revenue",
data: revenue_by_year
},
{
name: "Net Income",
data: net_income_by_year,
}
]
end
Not sure what I'm doing wrong? I only seem to be able to access the Highcharts API methods listed under 'Chart', none of the series options etc. seem to work. Can anyone point me in the right direction for how to successfully get this to work?
you can try this way.
<%= line_chart [
{
name: "Amount", type: "column", data: #cause.donations.map {
|t| [t.user.name, t.amount]
}
},
{
name: "Test", type: "line", data: #cause.donations.map {
|t| [t.user.name, t.amount]
}
}
],
prefix: "$",
adapter: "highcharts"
%>
just don't care line_chart, column_chart or anythings... ONLY custom type in data. OK
I'm working on a Rails 3.1.1 app with a dashboard of various line graphs using Highcharts. I implemented the sample code in Railcast 223 (highcharts) -- and everything works as expected. But on days when no entries exists, the array plots a 0 value -- but I'm only looking to line graph actual records.
Its not an issue with the Railscast because they sample has multiple Order entries each day. It appears to be the same issue posted by another user (Thomas)...though his code didn't work in my situation.
Index view:
$(function () {
new Highcharts.Chart({
chart: { renderTo: 'orders_chart' },
title: { text: 'Orders by Day' },
xAxis: { type: 'datetime' },
yAxis: {
title: { text: 'Dollars' }
},
tooltip: {
formatter: function () {
return Highcharts.dateFormat("%B %e %Y", this.x) + ': ' +
'$' + Highcharts.numberFormat(this.y, 2);
}
},
series: [{
pointInterval: <%= 1.day * 1000 %>,
pointStart: <%= 3.weeks.ago.at_midnight.to_i * 1000 %>,
data: <%= (3.weeks.ago.to_date..Date.today).map { |date| Order.total_on(date).to_f}.inspect %>
}]
});
});
class Order < ActiveRecord::Base
def self.total_on(date)
where("date(purchased_at) = ?",date).sum(:total_price)
end
end
Any input would be greatly appreciate -- new to rails and have already found the 100 ways the don't work! Thanks!
If you want nothing to be graphed but the date to still show up, then change any zeroes to a javascript null. If you want to not graph those days, then you should reject them from the array before output.
So:
(3.weeks.ago.to_date..Date.today).map{|date| total=Order.total_on(date).to_f; total.zero? ? "null" : total }.inspect
Or:
(3.weeks.ago.to_date..Date.today).map{|date| Order.total_on(date).to_f}.reject(&:zero?).inspect