Requesting a better approach to update the JS elements on fly - javascript

How do we obtain an argument from QueryString and then apply this to the JSON object.I have the following JS file, I would like to update the dashboard-metrics-target elements on fly on basis of querystring.. "target": "sumSeries(SERVER1.metric)", must be changed to SERVER2.metric on fly using the given template.
ex.. http://testdashabord.com/sla-network.incoming.bytes-2013.11.02/logs/test&server=192.168.1.103 must obtain my metrics for '192.168.1.103'
var graphite_url = "demo"; // enter your graphite url, e.g. http://your.graphite.com
var dashboards =
[
{ "name": "Users", // give your dashboard a name (required!)
"refresh": 5000, // each dashboard has its own refresh interval (in ms)
,
"metrics": // metrics is an array of charts on the dashboard
[
{
"alias": "signups", // display name for this metric
"target": "sumSeries(SERVER1.metric)", // enter your graphite barebone target expression here
"description": "New signups to the website", // enter your metric description here
"summary": "sum", // available options: [sum|min|max|avg|last|<function>]
"summary_formatter": d3.format(",f"), // customize your summary format function. see d3 formatting docs for more options
},
{
"alias": "signup breakdown",
"target": "sumSeries(stats.*.event)", // target can use any graphite-supported wildcards
"description": "signup breakdown based on site location",
"renderer": "area", // use any rickshaw-supported renderer
"unstack": true // other parameters like unstack, interpolation, stroke are also available (see rickshaw documentation for more info)
"colspan": 3 // the graph can span across 1,2 or 3 columns
},
]
}, ...
My Approach:
..1. Obtain the parameter from URL
var first = getUrlVars()["server"];
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
..2. Update the elements of the array.
I would be thankful if a better approach is suggested.
Thanks

Related

cytoscape.js - how to merge attributes of the same node from different sources

I have a working graph which displays some nodes & their attributes. Then I get a JSON with different data, where some nodes may already exist on my graph. How to combine both data sources, to make them both visible on the same graph - BUT nodes with the same ID must be combined into one and contain attributes from both data sources (not just from one, as is by default)?
Example:
Node from source 1 => "id": "1", "name": "1", "param1": 100;
Node from source 2 => "id": "1", "name": "1", "param2": 200;
What I wish to see on the graph is one node with attributes:
"id": "1", "name": "1", "param1": 100, "param2": 200
I'm in the middle of writing code in my own application to do exactly what you're asking. The code below works, though I suspect that it's not the most efficient way. So, please don't accept this answer without waiting at least a few days for someone more experienced to post a better answer or to add a comment criticizing this answer.
The trick is to query cy (the cytoscape.js core object) for a "collection object" containing just the node with the givenĀ id, and then query the collection object to see if it's empty. If the node doesn't exist, you cy.add() it. If the node does exist, you call node.data() on the collection object to update it.
function updateGraph(g) { // g is the output from JSON.parse(), containing graph from server
gg = g; // save pointer to g, for console debugging
// Import nodes from server graph
for (const sn of g.nodes) { // sn = node as represented on the server
var node = cy.$id(sn.id) // node = cytoscape.js's representation of node
if (node.empty()) {
node = cy.add({group: 'nodes', data: {
id: sn.id,
label: sn['display-name'], // peculiar to my application
parent: sn.memberOf // peculiar to my application
/* . . . and whatever other data you want to copy to the cytoscape.js graph . . . */
}});
node.addClass(sn.class);
} else {
/* Update `node` with data from `sn`.*/
node.data( /* your overriding data goes here */ );
}
}
}
var gg; // We save the last graph dict from the server here so we can look at
// it in the Chrome debugger even after updateGraph() returns.
The gg variable isn't necessary, of course, but I've found it indispensible for seeing what's going on in the Chrome debugger.
In your application, you might be able to call Object.assign() to merge the data before calling node.data(). That would be simpler and more efficient than my code above, where data from the source has different keys than the keys expected by cytoscape.js.
//Node from source 1 => "id": "1", "name": "1", "param1": 100;
var xNode={"id": "1", "name": "1", "param1": 100}
//Node from source 2 => "id": "1", "name": "1", "param2": 200;
var yNode={"id": "1", "name": "1", "param2": 200}
// finalNode=Object.assign({},xNode,yNode)
var finalNode={...xNode,...yNode}
console.log('merge Obj:'+JSON.stringify(finalNode))

how to add more words in the Toxicity classifier

is there a way i can add more words to the
toxicity classifier ?
this is what i am using at the moment just a basic script
from the example given in the github page
// The minimum prediction confidence.
const threshold = 0.9;
// Load the model. Users optionally pass in a threshold and an array of
// labels to include.
toxicity.load(threshold).then(model => {
const sentences = ['you suck'];
model.classify(sentences).then(predictions => {
// `predictions` is an array of objects, one for each prediction head,
// that contains the raw probabilities for each input along with the
// final prediction in `match` (either `true` or `false`).
// If neither prediction exceeds the threshold, `match` is `null`.
console.log(predictions);
/*
prints:
{
"label": "identity_attack",
"results": [{
"probabilities": [0.9659664034843445, 0.03403361141681671],
"match": false
}]
},
{
"label": "insult",
"results": [{
"probabilities": [0.08124706149101257, 0.9187529683113098],
"match": true
}]
},
...
*/
});
});
https://github.com/tensorflow/tfjs-models/tree/master/toxicity
You can add more words in the array sentences for the predictions:
const sentences = ['you suck', 'add whatever you want'];
However, you cannot change the labels of the model. You can only do so during the training of the model. The toxicity model was trained using python before being ported to js. So you can only change the labels by retraining the python model.

AngularJS: How to create a model which holds an array for a dynamic list of input fields?

I have quite an interesting question (I hope) for all you AngularJS gurus out there. I am looking to create a dynamic list of form input fields based on a SELECT dropdown. As an example, we have a number of categories with each category having a set of specifications which are unique to that category. To help with the explanation we have the following:
Firstly, in the controller we start by initializing the models.
$scope.category = {};
$scope.category.specs = [];
Next we ready the data to be used in the form (actually retrieved from the server via $http). We also initialize a variable to the first element in the categories array.
$scope.categories = [
{ "id": "1", "name": "mobile", specs: [
{ "id": "1", "label": "Operating System" },
{ "id": "2", "label": "Camera type" } ] },
{ "id": "2", "name": "laptop", specs: [
{ "id": "1", "label": "Operating System" },
{ "id": "2", "label": "Graphics Card" } ] }
};
$scope.selectedCategory = $scope.categories[0];
In the form, we have a dropdown which when selected loads the appropriate input fields specific to that category. We use the ngRepeat directive to accomplish this. This is a dynamic list of fields based on $scope.categories.specs. (please note the ???)
<select ng-model="selectedCategory" ng-options="category.name for category in categories"></select>
<div ng-repeat="spec in selectedCategory.specs">
<label>{{spec.label}}</label>
<input type="text" ng-model="???">
</div>
Ultimately, when the user clicks the submit button, we would like to extract the category he/she has selected and then package it together with the specifications they have filled in. The post request should contain something like the following for instance (of course, I only included one spec item, but in reality there would be many):
{ "id": "1", specs [ { "id": "2", "details": "RADEON HD 8970M" } ] }
Unfortunately I am not really sure how to accomplish this. I need to somehow create an array for the spec model, and then ensure that both the ID and user entered data are appropriately extracted... what goes in the ??? and what do we do after? Any help would be much appreciated.
this is how I do it. I make a form, validate it with angular, and then when its valid I submit it with a function.
<form name="signup_form" novalidate ng-submit="signupForm()"></form>
$scope.signupForm = function() {
var data = $scope.signup;
$http({
method : 'POST',
url : 'http://yoursite.com/mail.php',
data : $.param(data), // pass in data as strings
headers : { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload)
})
.success(function(data) {
});
}
also if you want to look at another form validation system for angular check out http://nimbly.github.io/angular-formly/#!/ It may help you solve your current form system.
In the controller, initialize $scope.specDetails as follows:
$scope.specDetails = {};
angular.forEach($scope.categories, function (category, index1) {
$scope.specDetails[category.id] = {};
angular.forEach(category.specs, function (spec, index2) {
$scope.specDetails[category.id][spec.id] = '';
});
});
In the html, replace "???" with specDetails[selectedCategory.id][spec.id]

How to do complex conditionals or regex in jade

I'm having an interesting challenge and can't figure out how to go about solving it. I'm pulling a list of subscribers from my mailchimp and populating a members' page on my website with the data. One of the field in my sign up for says, "Website or LinkedIn profile url."
What I'd like to do is, check if they have provided a linkedin address, and if so drop their url in the linkedin member plugin, if not use the other data to create a simpler profile, name website, headline etc.
My problem is I can't say if data.websiteField.match(/linkedin/) within jade, so I either need to pass the data to some client side javascript which I'm having trouble with or do something else.
Here's a sample of data returned from mailchimp
[ // this first bit is just the fields
[
"email address",
"first name",
"last name",
"role",
"organization",
"headline",
"website",
"areas of interest",
"please email me about:",
"member_rating",
"optin_time",
"optin_ip",
"confirm_time",
"confirm_ip",
"latitude",
"longitude",
"gmtoff",
"dstoff",
"timezone",
"cc",
"region",
"last_changed"
],
[ // and here's the first user
"woop#booomshakala.com", // haha, just hiding some data
"Woop",
"Shak",
"Tester",
"ShakaCo",
"Whooooooper",
"http://linkedin.com/in/costamichailidis", // hit me up sometime
"Creativity, Innovation, Ideas and Science",
"Job Placement, Internships, Recruitment & Retention, Technology & MOOCs, Measurement & Evaluation, Documentation & Dissemination",
2,
"2013-03-28 19:28:55",
"173.52.122.111",
"2013-03-28 19:29:12",
"173.52.122.111",
"40.7648000",
"-73.7775000",
"-5",
"-4",
"America/New_York", "US", "NY", "2013-03-28 19:29:12"
]
]
Any help would rock!
Also, I'm using express. Does express make locals available in client side javascript?
Client Side Regex
Jade allows you execute arbitrary javascript using the - modifier at the start of the line
- if (profile.websiteField.match(/linkedin/)
// render linkedin profile here
- else
// render simple profile here
Server Side Regex
I think it would be simpler to format the profile information server-side and set a renderLinkedIn boolean field to true or false
function displaySignUpPage(req, res) {
var profile = formatMailChimpData()
// profile now looks like
// {
// "email address": "woop#booomshakala.com",
// "first name": "Noah",
// ...
// }
var linkedInRegex = /linkedin/;
profile.renderLinkedIn = linkedInRegex.test(profile.website) // set renderLinkedIn to true or false
// say your jade view is called signUpPage.jade
var pageData = {
title: 'Register',
profile: profile
}
res.render('signUpPage', pageData)
}
function formatMailChimpData() {
var mailChimpData = [
[
"email address",
"first name",
"last name",
"role",
"organization",
"headline",
"website"
// other fields truncated
],
[
"woop#booomshakala.com", // haha, just hiding some data
"Noah",
"Isaacson",
"Tester",
"ShakaCo",
"Whooooooper",
"http://www.linkedin.com/pub/noah-isaacson/59/6a2/553"
]
]
// mailChimp puts the keys as the first entry
var mailChimpFields = mailChimpData[0]
var mailChimpProfile = mailChimpData[1]
// make profile into key-value pairs
var keyValuePairs = mailChimpFields.map(function (field, index) {
var profileValue = mailChimpProfile[index]
var keyValuePair = [field, profileValue]
return keyValuePair
})
var profile = keyValuePairs.reduce(function(prev, pair) {
var key = pair[0]
var value = pair[1]
prev[key] = value
return prev
}, {})
return profile
}

Flatten an Object hierarchy created with d3.js nesting

I am trying to visualize team collaboration data, in a way like this:
Different colors in the chart are different collaboration artifact types.
The data from the source looks like this:
var json = [
{
"teamLabel": "Team 1",
"created_date": "2013-01-09",
"typeLabel": "Email"
"count": "5"
},
{
"teamLabel": "Team 1",
"created_date": "2013-01-10",
"typeLabel": "Email"
"count": "7"
},
/* and of course, a lot more data of this kind */
]
Note that the data is given for single days. So for the above visualization, I need to aggregate the data based on the week of year first. The team name and the artifact type need to be preserved though and are used as grouping attributes. Here's the code:
// "2013-01-09"
var dateFormat = d3.time.format.utc("%Y-%m-%d");
// "2013-02" for the 2nd week of the year
var yearWeek = d3.time.format.utc("%Y-%W");
var data = d3.nest().key(function(d) {
return d.teamLabel;
}).key(function(d) {
var created_date = dateFormat.parse(d.created_date);
return yearWeek(created_date);
})
.key(function(d) {
return d.typeLabel;
}).rollup(function(leaves) {
return d3.sum(leaves, function(d) {
return parseInt(d.count); // parse the integer
});
}
)
.map(json);
This results in an Object hierarchy based on the nesting keys. I do not see how to create the above chart from this, so I am rather looking for a way to convert data into the following structure:
[
// This list contains an element for each donut
{
"teamLabel": "Team 1",
"createdWeek": "2013-02",
"values": [
// This list contains one element for each type we found
{
"typeLabel": "Email",
"count": 12
},
{
...
}
]
},
{
...
}
]
This way, I can use createdWeek and teamLabel for the positioning on x- and y-Axis respectively, and the information under values can be passed to d3.layout.pie().
Is there a clean way to do this data transformation? If you need any clarification or further details, please let me know.
That's how you do it:
var flat = data.entries().map(function(d){
return d.value.entries().map(function(e){
return {
"teamLabel": d.key,
"createdWeek": e.key,
"values": e.value.entries().map(function(f){
return {"typeLabel": f.key, "count": f.value}
})
}
})
}).reduce(function(d1,d2){ return d1.concat(d2) },[]);
Note that I'm using d3.map instead of the standard javascript object in order to use the map.entries() helper function. I imagine that's what you tried judging by the fact that you're using:
.map(json); // whereas I used .map(json, d3.map)
instead of
.entries(json);
jsFiddle link here:
http://jsfiddle.net/RFontana/KhX2n/

Categories