Highcharts: Comparing 2 lines with different dates - date

I'm comparing 2 users of twitter on who receives the most tweets on a particular day, and put this in a line graph of Highcharts, the following mysql code I have:
<?php
require('mysql_connect.php');
$artist1 = $_POST['dj1'];
$artist2 = $_POST['dj2'];
$dates_result = mysqli_query($con,"SELECT DISTINCT(tweetDate) FROM tb_tweetDetails");
while ($row = mysqli_fetch_array($dates_result)) {
$dates[] = $row['tweetDate'];
}
$artist1_tweetsADay_result = mysqli_query($con,"SELECT tweetDate,COUNT('tweetIds') AS 'amountTweets' FROM tb_tweetDetails WHERE tweetId IN
(SELECT tweetId FROM tb_tweetLink LEFT JOIN tb_artists ON
(tb_tweetLink.artistId = tb_artists.artistId) where artistName = '$artist1') GROUP BY tweetDate");
while ($row = mysqli_fetch_array($artist1_tweetsADay_result)) {
$artist1_tweetsADay_date[] = "'" . $row['tweetDate'] . "'";
$artist1_tweetsADay_amount[] = $row['amountTweets'];
}
$artist1_tweetsADay_result = mysqli_query($con,"SELECT tweetDate,COUNT('tweetIds') AS 'amountTweets' FROM tb_tweetDetails WHERE tweetId IN
(SELECT tweetId FROM tb_tweetLink LEFT JOIN tb_artists ON
(tb_tweetLink.artistId = tb_artists.artistId) where artistName = '$artist2') GROUP BY tweetDate");
while ($row = mysqli_fetch_array($artist1_tweetsADay_result)) {
$artist2_tweetsADay_date[] = "'" . $row['tweetDate'] . "'";
$artist2_tweetsADay_amount[] = $row['amountTweets'];
}
?>
I use this to collect all the available dates I collected tweet data (so also from other then the selected 2 artists)
Then I get the amount of tweets the user received that day, together with the date.
This all works nicely, and the output is as I expected.
Now when I put it in the graph, I put the array of the dates, as the xAxis Categories.
And put the tweetAmount for both artists in the data inputs to create both lines.
The problem is:
Artist 1 has data on 06-04-2013,08-04-2013 & 10-04-2013
Artist 2 has data on 07-04-2013,08-04-2013, 09-04-2013 & 10-04-2013 (so everyday that actually is in my database)
Artist 2 would have his data of 07-04-2013 at 06-04-2013 (since that value comes first)
Artist 1 & 2 have 08-04-2013 under the categorie 07-04-2013 since that is the second available date.
etc. etc.
Is it possible I could use the dates array, to fix the arrays of the amount of tweets, so that every missing date would have 0 assigned to it so the line stays correct with the date.

The two things that I would do to accomplish this:
1) use a datetime x axis
2) while pulling the data from your table, create an array of every date returned in addition to the arrays you are already building. loop through the array of dates, and for each date, check the individual arrays for a value. if no value exists, create it.
You will then have two arrays with the same dates, and you can plot them on a datetime axis and not worry about category index matching.

Related

VBA Autofilter subset contains extra row up top

The macro attempts to filter Sheet "Temp" for one Criteria at a time (PE, AR, DC,FI), and copy column 5 that contains non-duplicate data into another sheet "Detail". Please help me understand two issues. (1) The macro does correct filtering for each of the 4 criteria. However, the filtered list for each of the criteria always contains the first item from the filtered list of the very first criteria "PE". I.e. the filtered list for criteria 2, "AR", contains all items in AR, but starts with the first item in "PE". There's a header row, but it doesn't seem to make a difference. How can I get rid of that first item in all cases except when filtering for "PE" (where it belongs)? (2) I would like to be able to count and store the number of visible rows for each filtered list. I would like to be able to paste each filtered list into another spreadsheet ("Detail"), starting in cell A4. Each consecutive list should start two rows below the list that was just pasted. For example, if the first list contains 16 items, then the next list should start in cell A22 (A4+16+2). For some reason, copiedrows (used to remember number of rows in a filtered list) is correct the first time around (=16), but not the second time (=1?). It looks like q's 1 & 2 are related. Perhaps, if I figure out #1, I can do something about #2. I reviewed exiting posts on Autofiltering, but still feel a bit stuck here. Really appreciate your help!
Sub FilterCategories()
Dim LastRow As Long
Dim startpos As Integer
Dim k As Integer
Dim copiedrows(1 To 4) As Long
Dim AG(1 To 4) As String
Dim rng As Range
AG(1) = "PE"
AG(2) = "AR"
AG(3) = "DC"
AG(4) = "FI"
'Autofilter based on each AG and copy over to 'Detail'. Create temporary
sheet for filtering.
startpos = 4
For k = LBound(AG) To UBound(AG)
Application.DisplayAlerts = False
On Error Resume Next
Sheets("Temp").Delete
Sheets("Lookup").AutoFilterMode = False
Sheets("Lookup").Copy After:=Sheets("Lookup")
ActiveSheet.Name = "Temp"
With Sheets("Temp")
AutoFilterMode = False
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
With .Range("A2:E" & LastRow)
.AutoFilter Field:=4, Criteria1:=AG(k)
.RemoveDuplicates Columns:=5
.Columns(5).SpecialCells(xlCellTypeVisible).Copy
Destination:=Sheets("Detail").Range("A" & startpos)
copiedrows(k) = .SpecialCells(xlCellTypeVisible).Rows.Count
Debug.Print copiedrows(k)
startpos = copiedrows(k) + 6
Debug.Print startpos
End With
End With
Next
End Sub

CakePHP 3 - Comparing and modifying dates

In the CakePHP 3 Cookbook on Date/Time, you can compare time intervals with future/past days/weeks using IsWithinNext/WasWithinNext. You can also modify dates/times by doing a ->modify('extra time') - eg. if $date = 2016-01-01, $date->modify('+1 week') would mean $date = 2016-01-08.
These features require the use of Cake\i18n\Time. However, when I attempted to use these features, I received a Cake error:
Call to a member function isWithinNext() on string.
This is the code I used:
$date_start = \Cake\Database\Type::build('date')->marshal($data['session']['date_start'])->i18nFormat(); //before hand my dates were in the form of an array comprised of Year, Month and Day. This changes them into date format.
if($date_start->isWithinNext('1 week')){
$deposit_due = $booking->date_confirm;
$deposit_due->modify('+48 hours');
} elseif ($date_start->isWithinNext('2 weeks')){
$deposit_due = $booking->date_confirm;
$deposit_due->modify('+1 week');
} elseif ($date_start->isWithinNext('3 weeks')){
$deposit_due = $booking->date_confirm;
$deposit_due->modify('+1 week');
} else {
$deposit_due = $booking->date_confirm;
$deposit_due->modify('+2 weeks');
}
Calling i18nFormat() returns a formatted string as you can look up in the API: https://api.cakephp.org/3.4/class-Cake.I18n.DateFormatTrait.html#_i18nFormat
This, for example, should work:
$date_start = new \Cake\I18n\Time($data['session']['date_start']);
debug($date_start->isWithinNext('2 weeks'));

How to label structure array elements in an additional field?

I have a 1800x1 structure array with 5 fields. In the field "trial" I`ve stored 14 different numbers which are indicative for a certrain trial characteristica. So for example if 1 stands for rewarded trial and 2 stands for non rewarded trial, I want to add another field which tells me the labels of the respective other field. Any ideas about how to do that?
Assuming you have this data:
a = num2cell(randi(3,15,1));
strings = {'Laurie','rewarded trial','yada yada'};
s = struct('trail',a,'name',[]);
where the value in s(k).trail is the index from strings to be assigned to s(k).name, you can write:
s = struct('trail',a,'name',strings(cell2mat({s.trail})).');
Alternatively, you can do it with a loop:
for k = 1:size(s,1)
s(k).names = strings{s(k).trail};
end

MATLAB - Count Number of Entries in Each Year

I have a .mat file that contains data from the years 2006-2100. Each year, there is a different number of lines. I need to count how many lines are 2006, how many are 2007, etc.
The set up, by column, is: Year, Month, Day, Lat, Long
I just want to count the number of rows containing the same Year entry and get an array back with an array containing that info.
I'm thinking a for or while loop should work, but I don't know how to right it.
If we assume your data are in a numeric matrix, you can just do:
num_lines2006 = sum(data(:,1)==2006);
data2006 = data(data(:,1)==2006),:);
If you want to add a column with number of rows for corresponding year, here is a solution with a loop:
for k=size(data,1):-1:1
num_year(k,1) = sum(data(:,1)==data(k,1));
end
data = [data num_year];
Here is a solution without loop:
[unq_year,~,idx] = unique(data(:,1),'stable');
num_year = grpstats(data(:,1),unq_year,#numel);
data = [data num_year(idx)];
To count numeric entries, you may want to use histc
years = unique(data(:,1);
counts = histc(data(:,1),years);
Since you just want to count the number of rows you could just write something simple like:
years = unique(data(:, 1));
counts = arrayfun(#(year) nnz(data(:, 1) == year), years);
years contains the unique years, and numRows the number of times they are found.
You could also use a one-liner inspired by Jonas' answer:
[counts, years] = hist(data(:,1), unique(data(:,1))');

sum two values from different datasets using lookups in report builder

I have a report that should read values from 2 dataset by Currency:
Dataset1: Production Total
Dataset2: Net Total
Ive tried to use:
Lookup(Fields!Currency_Type.Value,
Fields!Currency_Type1.Value,
Fields!Gross_Premium_Amount.Value,
"DataSet2")
This returns only the first amount from dataset 2.
I've tried Lookupset function as well but it didn't SUM the retrieved values.
Any help would be appreciated.
Thanks Jamie for the reply.
THis is what i have done and it worked perfect:
From Report Properties--> Code , write the below function:
Function SumLookup(ByVal items As Object()) As Decimal
If items Is Nothing Then
Return Nothing
End If
Dim suma As Decimal = New Decimal()
Dim ct as Integer = New Integer()
suma = 0
ct = 0
For Each item As Object In items
suma += Convert.ToDecimal(item)
Next
If (ct = 0) Then return 0 else return suma
End Function
Then you can call the function:
code.SumLookup(LookupSet(Fields!Currency_Type.Value, Fields!Currency_Type1.Value,Fields!Gross_Premium_Amount.Value, "DataSet2"))
Yes, Lookup will only return the first matching value. Three options come to mind:
Change your query, so that you only need to get one value: use a GROUP BY and SUM(...) to combine your two rows in the query. If you are using this query other places, then make a copy and change that.
Is there some difference in the rows? Such as one is for last year and one is for this year? If so, create an artificial lookup key and lookup the two values separately:
=Lookup(Fields!Currency_Type.Value & ","
& YEAR(DATEADD(DateInterval.Year,-1,today())),
Fields!Currency_Type1.Value & ","
& Fields!Year.Value,
Fields!Gross_Premium_Amount.Value,
"DataSet2")
+
Lookup(Fields!Currency_Type.Value & ","
& YEAR(today()),
Fields!Currency_Type1.Value & ","
& Fields!Year.Value,
Fields!Gross_Premium_Amount.Value,
"DataSet2")
Use the LookupSet function as mentioned. With this you'll get a collection of the values back, and then need to add those together. The easiest way to do this is with embedded code in the report. Add this function to the report's code:
Function AddList(ByVal items As Object()) As Double
If items Is Nothing Then
Return 0
End If
Dim Total as Double
Total = 0
For Each item As Object In items
Total = Total + CDbl(item)
Next
Return Total
End Function
Now call that with:
=Code.AddList(LookupSet(Fields!Currency_Type.Value,
Fields!Currency_Type1.Value,
Fields!Gross_Premium_Amount.Value,
"DataSet2"))
(Note: this code was not tested. I just composed it in the Stack Overflow edit window & I'm no fan of VB. But it should give you a good idea of what to do.)