Parse a Google Visualization Multi-Line Chart Data String for one data series - google-visualization

Setting up a page for my customers to view GA performance for their data. In order to facilitate faster performance, using a CRONJOB to pull the GA data for all premium members "after hours" and stick it in a DB, so when they go to look at their data, they don't have to wait for the GA code to crunch.
Already have GA Charts working for a multi-line chart for a given members data but that is at the superset level. IOW, the "google.visualization.arrayToDataTable()" string is being persisted in the DB with ALL their records. This is fine, as one of the charts is a superset chart. HOWEVER, need to also provide a line chart view for each item individually. Since the superset data is already there, WHY go back and requery GA, just parse the existing data string for the record needed.
Before I go off an develop my own custom parser for that one record, wanted to ask if anyone is aware of something already existing?
Maybe create a JSON object from the string, identify the element needed, then print that back out in the string format? Have done a little reading on that, but wanted to ask some 800lb brains before I spend alot of time going down that rabbit hole.
String data for the google.visualization.arrayToDataTable() function is in this format:
[{type: 'date', label: 'Date'},
{type: 'number', label: 'XYZ46570'},
{type: 'number', label: 'XYZ35512'},
{type: 'number', label: 'XYZ39964'}],
[new Date(2018,04,21),7,0,0],
[new Date(2018,04,22),4,1,0],
[new Date(2018,04,23),4,3,0],
[new Date(2018,04,24),4,1,0],
[new Date(2018,04,25),1,0,0]
This example is 4col, 5row string. Therefore, what is needed is to parse the string for just one of the 'XYZ' labels such as 'XYZ35512'. The resulting string would be used to create a single line GA chart:
[{type: 'date', label: 'Date'},
{type: 'number', label: 'XYZ35512'}],
[new Date(2018,04,21),0],
[new Date(2018,04,22),1],
[new Date(2018,04,23),3],
[new Date(2018,04,24),1],
[new Date(2018,04,25),0]
Thanks in advance for any help!
LarryG

Related

Best approach for Posts and PostReactions in AWS Amplify and DynamoDB

I am working on chat functionality using AWS Amplify and I have a simple Post model in my graphql schema:
type Post
...
{
id: ID!
channelId: ID #index(
name: "byChannel", sortKeyFields: ["createdAt"],
queryField: "listPostsByChannel"
)
customerId: ID #index(
name: "byCustomer", sortKeyFields: ["postType", "createdAt"]
)
text: String!
postTempId: String
postType: String
reactions: [PostReaction] #hasMany(fields: ["id"])
createdAt: AWSDateTime
updatedAt: AWSDateTime
}
What I want to achieve is to have similar to other popular chat apps - reactions with emojis attached to each post, so I've created another table and the PostReaction model.
type PostReaction
...
{
postId: ID! #primaryKey(sortKeyFields: ["customerId", "emojiUnicode"])
customerId: String!
customerMeta: CustomerMeta
emojiUnicode: String!
createdAt: AWSDateTime
updatedAt: AWSDateTime
}
Of course, each customer could add multiple emojis to a single post, the custom primary key is for handling duplicates later.
There is one disadvantage here.
Emojis will be listed in an array in the reactions field in the post, even if it's the same emoji added by many people.
Instead of a simple array of reactions that frontend would need to merge for each post, the best would be to get a result from the AppSync query for each Post like:
...
reactions: [{
emojiUnicode: "U+1F44D",
customerIds: ["ID1234", "ID5678"],
...
}, {...}]
I thought that I can use a JSON object in the reactions field, but the DynamoDB has the max size limit for a single item which is 400KB. That's not a problem for now, but next when I will add more attributes to the Post model, and when there will be many reactions from many people at the same time, this might be an issue.
Is there an option how to achieve this in the simplest way?
Best thing to not over-complicate your schema would be to enforce a maximum number of emojis just as Slack does for example:
You can add up to 23 emoji reactions to any message, but the maximum per message is 50 unique emoji.
Other than that, you could keep an item for each emoji reacted
pk
sk
data
thread123
metadata
metadata about thread
thread123
post#001
First message in thread
thread123
post#002
Second message in thread
thread123
post#003
Third message in thread
thread123
post#003#emoji#U+1F44D
[user1, user2, user45]
thread123
post#003#emoji#U+1F33R
[user56, user8, user7, user10]
Now when you want all the data to populate a given thread on your UI, you just issue a query with the pk as a parameter:
SELECT * FROM table WHERE PK = 'thread123'

using chart-dataset-override option in angular-chart.js

I'am writing an application for budget management and i am using angular-chart.js.
i want to use a dataset to override the initial data(mainly to add new data to the graph and give diffrent color for each bar,label etc.)and set label and colors according to the value of the data.
currently,i tried to do that hard coded but only the first value is being override.
here is the code i am using :
angular.module("app2", ["chart.js"]).controller("MixedChartCtrl",
function($scope) {
$scope.colors = ['#45b7cd', '#ff6384', '#ff8e72'];
$scope.labels = ['', ''];
$scope.data = [65, 11];
$scope.datasetOverride = [
{
label: 'Override Series A',
borderWidth: 1,
type: 'bar',
data: [345]
},
{
label: "Bar chart1",
borderWidth: 1,
type: 'bar',
data: [45]
}
];
});
Hoping that yourquestion is, you want a fill color/label/something to each individual data (for each bar).
Above (your) code snippet is used when you have two data sets.
All these dataset properties will accept String when the same property value has to set for all data, and they will also accept Array[String] - when you want to set different property values for different data in the same dataset. (like below).
$scope.data = [65,11];
$scope.datasetOverride = [
{
label: ['something', 'otherthing'],
borderWidth: [1,2],
backgroundColor: ['#FF4242','#2291ff']
}
]
so now I understood that you might be adding dynamically data.
so you have to push data into DATASET something like this:
$scope.data.push(345);
So if you want to set different properties for these you need to push the properties (arrays).
$scope.datasetOverride[0][label].push('someother thing');
$scope.datasetOverride[0][borderWidth].push(2);
$scope.datesetOverride[0][backgroundColor].push('#46bfb8');
This will add a bar with new color/label/etc beside the previous bars.
I hope I understood your question and this will help.

Ember data: Insert new item at beginning of array instead of at the end

In my application I'm displaying a timeline of messages. We retrieve them from the server in descending chronological order, newest to oldest.
3 - Howdy
2 - Greetings
1 - Mahalo
Our users also have the ability to add a new message which by default gets inserted at the end of the queue like so
3 - Howdy
2 - Greetings
1 - Mahalo
4 - I'm the new message, last as usual
When I submit, I'd like new messages to show up at the top. I've written a function before that reverses the array of items, but that wouldn't work for items already in the array.
4 - I'm the new message, first finally
3 - Howdy
2 - Greetings
1 - Mahalo
What would be the best approach in this case? The ideal would be for Ember Data to prepend to the content array rather than append. Is there another option which might be better?
For most scenarios involving sorting it's recommented to use Ember.SortableMixin, which is baked into Ember.ArrayController.
Please refer to this conceptual example in JSFiddle: http://jsfiddle.net/schawaska/tbbAe/
In this sample the model has a DateTime field named when, which I'm using for filtering:
App.Greeting = DS.Model.extend({
text: DS.attr('string'),
when: DS.attr('date')
});
App.Greeting.FIXTURES = [
{id: 1, text: 'First', when: '3/4/2013 2:44:52 PM'},
{id: 2, text: 'Second', when: '3/4/2013 2:44:52 PM'},
{id: 3, text: 'Third', when: '3/4/2013 2:44:52 PM'},
{id: 4, text: 'Fourth', when: '3/4/2013 3:44:52 PM'}
];
In the controller the only thing I have to do is to set the name of the property and the sorting direction:
App.SortingMixinController = Em.ArrayController.extend({
sortProperties: ['when'],
sortAscending: false
});
Then in my Handlebars template, I can use the {{each}} helper as I would do normally.
Because in this sample, all the dates are the same except for the Forth (which because of sorting appears first), and also because of SortableMixin, these values will be sorted through another property - I'm assuming the Id here.
The other approach I've taken in that fiddle is using a computed property. I'm not really sure about that approach as it seems to consume more resources and the code in App.SortingPropertyController is worthy of laugh, but sort of works to show possibilities.
Can you use basic JavaScript to drop in the new item at a given location in the array? Not sure if this is basic ajax + js objects or full blown ember-data models but this works for the simple js array example
var arr = [];
arr[0] = "Jani";
arr[1] = "Hege";
arr[2] = "Stale";
arr[3] = "Kai Jim";
arr[4] = "Borge";
console.log(arr.join());
arr.splice(2, 0, "Lene");
console.log(arr.join());
The output of the code above will be:
Jani,Hege,Stale,Kai Jim,Borge
Jani,Hege,Lene,Stale,Kai Jim, Borge

Ext.form.ComboBox: Use template for displayField

Is there any way to apply a template to the selected value of a ComboBox? I'm using a template to display the drop down values of the ComboBox, but as soon as i select one, the plain value from the datastore is shown.
{
id: 'requestStatusCombo',
hiddenName: 'requestStatus',
tpl: '<tpl for="."><div class="x-combo-list-item">{statusCode:requestStatus}</div></tpl>',
fieldLabel: 'Status',
xtype: 'combo',
mode: 'local',
triggerAction: 'all',
store: new Ext.data.ArrayStore({
fields: ['statusCode'],
data: [['unassigned'],['assigned'],['closed']]
}),
valueField: 'statusCode',
displayField: 'statusCode'
}
I want to use my format function requestStatus to translate the statusCodes into locale spesific status names, and this works well for the drop down list, but as soon as I select something, the statusCode is shown.
So is it possible to assign a template to the displayField, or perhaps do some simple batch modification on the datastore? By processing the input through a reader maybe? Is there another <tpl for="?"> keyword that will make this happen?
I'm looking for some simple method utilizing the Ext library. If the only solution is to pre process the data, I'm capable of doing that myself.
I found a solution!
I changed my datastore, and added a reader to pre-process the status using a convert function:
{
id: 'requestStatusCombo',
hiddenName: 'requestStatus',
fieldLabel: 'Status',
xtype: 'combo',
mode: 'local',
triggerAction: 'all',
store: new Ext.data.Store({
data: [['unassigned'],['assigned'],['closed']],
reader: new Ext.data.ArrayReader({},[
{name: 'statusCode', mapping: 0},
{name: 'displayname', mapping: 0, convert: function(statusCode) {
return Ext.util.Format.requestStatus(statusCode);
}}
])
}),
valueField: 'statusCode',
displayField: 'displayname'
}
Examinig generated DOM you will notice that while list elements are DIVs, the field itself is html INPUT element. You can't have HTML within INPUT element... so no... no xtemplate here.
This does not mean it can't be done by extending Ext.form.ComboBox (or Ext.Component maybe)

Using Google's annotated timeline in the Visualizations API, can you insert annotations regardless of data set?

I can insert annotations on specific datasets on the graph but I wish to have multiple lines on the graph without associating the annotation with a specific line, but with a date instead.
Here is an example of what I want to do. Notice the bubbles appended to the x-axis and not a specific line on the graph.
I've read through the API and can't see an option like this but wondering if someone knows a way.
Thanks.
No experience, but my instant reaction was that you might try a series with the annotations attached with all zeros as the data - and exclude it from the legend?
If you don't mind using an SVG Line Chart with Annotations you can recreate this as well with more flexibility. If you set the Annotation column to immediately follow the X-axis values, the annotations will appear at the very bottom of the chart (on the axis) and not be attached to any category. Here is a sample:
function drawVisualization() {
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('number','Day');
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn({type: 'string', role: 'annotationText'});
data.addColumn('number', '.DJI');
data.addColumn('number', '.INX');
data.addColumn('number', '.INIC');
data.addRows([
[1, null, null, 1000, 400, 300],
[2, 'A', 'did stuff', 1170, 460, 400],
[3, 'B', 'did more stuff', 660, 1120, 540],
[4, null, null, 1030, 540, 620],
[5, 'C', 'stopped stuff', 1070, 600, 700]
]);
// Create and draw the visualization.
new google.visualization.LineChart(document.getElementById('visualization')).
draw(data, {focusTarget: 'category',
width: 500, height: 400,
vAxis: {maxValue: 10},}
);
}
This ends up looking like this: