Highstock: left-most column gets truncated depending on chosen end date - highcharts

I'm using Highstock (version 2.1.8) to draw a column chart that has date-range-selection values of 7 days, 14 days, 6 weeks, 12 weeks, 6 months, and 12 months. I'm well aware that data values have to be supplied for the complete date-range corresponding to any of those selections. So, if the 6 week or 12 week range is selected, the date range of the data should, evidently, end on the last day of the week (I've configured weeks to begin on Sunday, so the last data point should fall on a Saturday). Naturally, I only have real data through today, so I have to generate bogus data 3 days into the future if today happens to be a Wednesday. But if the user selects the 7-day or 14-day range, then I want the last data point to fall on today's date. The problem is that I obviously can't have it both ways. So if my last data point falls on a Saturday that's 3 days in the future, the 7-day and 14-day views show data points for those future days -- not good. But if my last data point is set to today (Wednesday), the weekly views get messed up, i.e. a partially truncated pair of columns appears on the left end of the chart.
Note that this problem only happens with column charts; it doesn't happen with line charts. This is a bummer because I'd like to combine a column chart and line chart on the same graph.
This definitely seems like a bug. I checked if Highstock version 2.1.9 has the same issue, and it does. I don't want to have to supply separate arrays of data points for daily views, weekly views, and monthly views. Presumably, the monthly views will expect the last data point to fall on the last day of the month.
I've created a jsFiddle to illustrate the problem:
(There's too much code to show here, so please refer to the js fiddle).
Be sure and make a one-line edit to the Javascript code in the js fiddle: search for the comment "modify this line" and subtract or add x days from today's date so as to make tmpDate fall on some day of the week other than Saturday. Then look at the 6 week view, and you'll see the partially truncated (one of the two columns is missing) column pair on the left side of the chart.

Related

Is there a cleaner, shorter version of this Google Sheets formula for determining the next date based on a recently input date?

I have a sheet with the date of an initial assessment. A review for each assessment needs to be done every 90 days.
This is what the table looks like:
Initial
Last Review
Next Review
5/5/22
8/3/22
In the second column, the last review will be entered so the next review will also update. However, the review date is based on the initial assessment, not the date of the review. So if the review is done early or late, the next review date will still be based on the initial assessment.
This is what the table should look like
Initial
Last Review
Next Review
5/5/22
6/12/22
11/1/22
For now I am using this IFS formula in the third column that looks at the second column and updates the date for the next review:
=IFS(B1="",A1+90,(B1>=A1+0)*(B1<=A1+90),A1+180,(B1>=A1+90)*(B1<=A1+180),A1+270,(B1>=A1+180)*(B1<=A1+270),A1+360,(B1>=A1+270)*(B1<=A1+360),A1+450,(B1>=A1+360)*(B1<=A1+450),A1+540,(B1>=A1+450)*(B1<=A1+540),A1+630)
This works perfectly fine, but some reviews can potentially be more than 630 days later. Is there a way to shorten this formula, or will need to keep adding more and more to calculate the dates past 630 days?
Edit: So I had a realization after messing around with some of the dates and the answers provided. If the review is done late, the formula will skip a review date.
Using the example I included, if the first review is done on 8/6/22, then the next review will be shown as 1/30/23 instead of 11/1/22.
From the answers provided #Martin 's answer =IF(B1="",A1+90,A1+(1+ROUNDUP((B1-A1+1)/90))*90 works perfectly if the review is done early or on time. #Arav 's answer =IF(B1="",A1+90,B1+90-MOD(B1-A1,90)) will only work if the review is late.
You can try with ROUNDUP:
=IF(B1="",A1+90,A1+(1+ROUNDUP((B1-A1+1)/90))*90
That will calculate the amount of 90 days passed and round up to the next one 90s
UPDATE
I think that the only case in which a date would change the calculations is when it's done early. Meaning, as you stated in your comments, 14 days before the next revision. Considering that, the formula would be with those 14 days summing:
=IF(B1="",A1+90,A1+(+ROUNDUP((B1-A1+14)/90))*90)
What should you do if the date is more than 30 days later?? If it's late, the date of the next revision shouldn't stay but keep in the next multiple of 90 days lapse. What you can do is to use some conditional formatting, for example:
=(MOD((B1-A1),90)>30)*(MOD((B1-A1),90)<76)
That considers the dates going from more than 30 days to less than 76 (because then it would be an early review of the next date)
See this conditional formatting operating in this example, in which I mapped 5 days lapse to see how the dates are changing. As you can see, the orange is for the out-of-date revisions with the previous conditional formatting; and in green I marked the places where the dates change:
Let me know!
The formula you've provided is checking for specific ranges of days between the initial assessment and the last review, and then returning the next review date based on those ranges. It's a bit long and can be hard to read.
To shorten the formula and make it more flexible for future assessments, you could use the MOD function to check if the number of days between the initial assessment and the last review is a multiple of 90. If it is, the next review date would be 90 days after the last review. If not, you could add the remainder of days to 90 to get the next review date.
Here's an example of what that formula might look like:
=IF(B1="",A1+90,B1+90-MOD(B1-A1,90))
This formula checks if the last review is empty, if yes it returns the date of initial assessment plus 90 days, otherwise it returns the date of last review plus 90 days minus the remainder when last review date minus initial assessment date is divided by 90. This way, it will always give you the next review date after 90 days of the last review date, regardless of how many days past the last review date is.

Sum of values generated by ARRAYFORMULA() is incorrect (Google Sheet)

I have a sheet used to calculate worked time. The aim is to sum up the hours and divide them in "regular" ones (up to 8h per day) and "overtime" ones (anything more than 8h per day). Each date has to have two rows(the second one is hidden by default), as there are multiple places I can work at, but the time calculated should be summed. Also, time worked on Saturday and Sunday should always be counted as overtime.
Screencap here.
The problem I have is with calculating overtime hours.
Regular hours are generated by:
=arrayformula(IFS(
WEEKDAY(A3:A70; 1)=1;0;
WEEKDAY(A3:A70; 1)=7;0;
E3:E70+E4:E70>8;8;
E3:E70+E4:E70<=8; E3:E70+E4:E70))
They are summed by =SUM(IFERROR(G3:G71;0)), which works just fine. Overtime hours are generated by:
=arrayformula(IFS(
WEEKDAY(A3:A70; 1)=1;E3:E70+E4:E70;
WEEKDAY(A3:A70; 1)=7;E3:E70+E4:E70;
E3:E70+E4:E70>8;E3:E70+E4:E70-8;
E3:E70+E4:E70<=8; 0))
And summed similarly by =SUM(IFERROR(H3:H71;0)) in H72. However, it returns a wrong value - in the sample sheet, it is 57 instead of 7
If I select the summed range, the tooltip shows the correct sum (7). If I add/remove the decimal place or change the formatting in H72, it suddenly changes to the correct one, too. However, when any new data is added (i.e. hours form a new day), it goes back to showing incorrect values.
It is not a simple display error, because the values are then imported by another sheet via =IMPORTRANGE and it imports those wrong values.
Any idea how to fix it?
Sample sheet here
try in H72:
=INDEX(SUM(IFERROR(1*H3:H71;0)))
update:
=INDEX(SUM(IFERROR(FILTER(1*H3:H71; MOD(ROW(H3:H71)-1; 2)=0); 0)))

Add numbers in Column B based and on Day of the Week in Column A and display highest/lowest resulting Day

I have a sheet that lists every day of the year and is updated on a daily basis. Next to each day is a percentage. I would like to display the day of the week that has the highest (and lowest) percentage when adding all relative days throughout the year. (i.e.: all Thursdays)
I am using this formula, which only partially works. It displays the day of the week, but seems to only reference the latest occurrence instead of all in Column A.
B2:
=iferror(INDEX($A4:$A,MATCH(MAX(B4:B),B4:B,0)),"")
B3:
=iferror(INDEX($A4:$A,MATCH(MIN(B4:B),B4:B,0)),"")
Link to a sample book: https://docs.google.com/spreadsheets/d/1_LP5MmmgW3i0zM6ziud9YrWfH5SvuHFbZH3OmRj9W6E/edit#gid=0
I hope this is enough information to understand what I am hoping to accomplish.. Is this possible in Google Sheets?
If I can get this to work my second goal would be to show the highest/lowest for the current month (or a specific month) in addition to the whole year.
Thanks!
Take a look at the shared spreadsheet and see if it does what you want.
https://docs.google.com/spreadsheets/d/1LL4Mgn_IWa-8W6Q0TythdMhBieVFt8ZiKI_UeO9ciTI/edit?usp=sharing
Added col L,O,R,and U for numeric day of week, current month,
current year, and month number. You can hide these columns.
I added some data for testing.

Summing up data from tables Ruby on Rails

What I have is a website where I add collected data of every single shift in a factory's production lines. I add data like (Quantity in tonnes). What I want is to be able to have the data of for instance; the morning, late and night shift of the (Quantity in tonnes) which are in the Shift table and are present and visible in the Shift Index view all combined and added, and added in another page which is the Days Index page (Day contains the shifts, one day has 3 shifts), so I could see the 3 shifts' data summed up together into the data combined to see as the total output of the day.
For example, in the "Quantity in tonnes", I would like 7 + 10 + 12 (These are the inputs I already have and I have added through a form to the shifts index) to be summed up, and appear in the Days index page automatically without me interfering as "29" in the Quantity of tonnes columns in it.
How is that possible to do? I can't seem to figure out how to write the code for it so that it would loop over all the inputs and constantly give me the summed out outputs.
Let me know if you need to see any parts of my code and if there is anymore info I could add for you to understand.
Have a look at the groupdate gem, it allows you to group by day, week, hour of the day, etc.
Some code from your end would help, but here's an example use, if I wanted to get revenue for past 3 weeks:
time_range = 90.days.ago..Time.zone.now
total = Sales.where('status > 2').group_by_week(:date_scheduled, Time.zone, time_range).sum(:price)

HighStock won't force-group for a wider range than the data

I'm trying to aggregate weekly values in the middle of the week with HighStock. Granted, I don't have all the data yet (as this is still mid-week so not all the data for the week exists) so I'd like to aggregate whatever data that exists (start of the week till now).
Problem: When I use aggregation on a range wider than the existing data, HighStock would strike on me.
When I force weekly sum it won't work - just like in this fiddle:
// works
[ 'minute',[1]]
// doens't work
[ 'hour',[1]]
Uncomment the the commented out line in the fiddle and it works again. Ideally, I would expect when I aggregate over a week from prev Wednesday to this Wednesday (a week's worth of time) to get 2 values: one for prev week, another for this week (since Monday).
Any ideas what should I be adding/changing to make it work?

Resources