Filter DOM elements via JavaScript - javascript

I have elements that get created like this:
function appendCalendarEventToList(className, event) {
var eventObject = {
title: event.title,
id: event.id,
type: event.type,
color: event.color,
description: event.description,
canReoccur: event.canReoccur,
reoccurVal: event.reoccurVal,
estHours: event.estHours,
project: event.project
};
var div = document.createElement("div");
div.className = 'external-event';
div.style.background = event.color;
div.innerHTML = event.title;
// store the Event Object in the DOM element so we can get to it later
$(div).data('eventObject', eventObject);
$(div).draggable({
helper: function () {
$copy = $(this).clone();
$copy.data('eventObject', eventObject);
$copy.css({ "list-style": "none", "width": $(this).outerWidth() }); return $copy;
},
appendTo: 'body',
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
$(className).append(div);
$(div).qtip({
content: event.title,
position:
{
target: 'mouse'
},
// show: { event: 'click' },
hide: { event: 'mousedown mouseleave' },
style: {
classes: 'custSideTip',
width: 200,
padding: 5,
color: 'black',
textAlign: 'left',
border: {
width: 1,
radius: 3
}
}
});
return div;
}
Every event has a project attribute as you see.
However there are projects and tasks (and cases that can be ignored):
function refetchUnscheduled() {
$.ajax({
type: "POST",
url: "CalendarServices.aspx/GetUnscheduled",
data: '',
async:false,
success: function (data) {
var projects = '.project-container';
var tasks = '.task-container';
var cases = '.case-container';
$(projects).html('');
$(tasks).html('');
$(cases).html('');
var numProjects = 0;
var numTasks = 0;
var numCases = 0;
$.each(data, function () {
var className = '';
var url = '';
var typeName = '';
var crm = this.crm;
switch(this.type)
{
case 'p':
className = projects;
url = 'ProjectViewFrame.aspx?id=' + this.id;
typeName = 'Project';
numProjects++;
break;
case 't':
className = tasks;
url = 'TaskViewFrame.aspx?id=' + this.id;
typeName = 'Task';
numTasks++;
break;
case 'c':
className = cases;
url = 'CaseViewFrame.aspx?id=' + this.id;
typeName = 'Case';
numCases++;
break;
default:
}
var curDiv = appendCalendarEventToList(className, this);
var curEvent = this;
$(curDiv).bind('contextmenu', function (e) {
$('#contextMenuContainer').html('');
var btn1 = createLink('Edit ' + typeName, 'context-elem-name');
$('#contextMenuContainer').append(btn1);
$(btn1).on('click', function () {
if (crm == '')
showCalendarModal('Edit ' + typeName, url);
else
showCRM(crm);
})
prepContextMenu(e);
return false;
});
});
changeUnscheduledHeaders();
}
,
error: function () {
}
});
}
Here is what I need that I am unsure how to do:
I need an OR based filter:
Given the following:
function filter(criteria,projects-div,tasks-div)
{
var words = criteria.split(' ');
}
I need to first, hide all projects whos
obj.data('eventObject').title contains one or more words.
Then, once these are filtered:
I need to first show all tasks whos project is visible,
So:
obj.data('eventObject').project is == to one of the visible project's project property.
Then, I need to also show any tasks that have any of the words.
All comparing must be case insensitive too.
So say my criteria is 'hello world'
I show all projects with hello or world in the title.
I show all tasks whos project attribute is visible after the first step
I show all tasks whos title has hello or world
Thanks

I'm on mobile, but at first glance, what about [].filter.call (NodeList, filterFn)?

Related

Remove charts drawn the first time with progressbar.js

On page load, I have a function like this :
function getResults(id) {
var url = "/users/" + id;
$.getJSON(url, function (data) {
var vid = data.calculated.length - 1;
getResults(vid);
data.survey.forEach(function (surveyData) {
$('#surveys').append(
new Option(
new Date(surveyData.submittedDate).toDateString(),
surveyData.id));
}
})
});
}
The getResults function does this :
function getResults(vid) {
var url = "/survey/" + vid;
$.getJSON(url, function (data) {
var results = data;
AnimateCircle("circle1", results.surveyResults["first"], "A");
AnimateCircle("circle1", results.surveyDataResults["second"], "B");
})
}
Now, after the dropdown with surveys has been filled out with values, when the option is changed I call getResults again where vid is different :
$('#data').change(function () {
var vid = $('#data').val();
getResults(vid);
});
The problem is that the charts called with AnimateCircle() function,gets called every time I choose a different option in the dropdown, and instead I want the old charts to be removed, and new ones with the new values on top of them.
I tried by calling circle.destroy(); on the onChange function, but it only destroys the last AnimateCircle called.
How do I make a loop to destroy all of them ? Or is there a better way that when I call the function for the second time, the first charts get updated ?
AnimateCircle function :
function AnimateCircle(container_id, animatePercentage, type) {
var startColor = '#FC5B3F';
var endColor = '#F18F01';
var element = document.getElementById(container_id);
circle = new ProgressBar.Circle(element, {
color: startColor,
trailColor: '#eee',
trailWidth: 3,
duration: 1400,
easing: 'easeInOut',
strokeWidth: 3,
text: {
value: "<h4>" + type + "</h4>" + "<h4>" + (animatePercentage) * 10 + "</h1>",
className: 'progressbar__label'
},
step: function (state, circle) {
circle.path.setAttribute('stroke', state.color);
}
});
circle.animate(animatePercentage, {
from: {
color: startColor
},
to: {
color: endColor
}
});
circle.path.style.strokeLinecap = 'round';
}
Uses progressbar.js
I couldn't really test this code, so I'm not 100% sure it will work, but I was thinking of something like:
var first, second;
function getResults(vid) {
var url = "/survey/" + vid;
$.getJSON(url, function (data) {
var results = data;
if (first) first.destroy();
if (second) second.destroy();
first = AnimateCircle("circle1", results.surveyResults["first"], "A");
second = AnimateCircle("circle1", results.surveyDataResults["second"], "B");
})
}
and as for your AnimateCircle:
function AnimateCircle(...) {
...
var circle = new ProgressBar.Circle(element, ...);
// do your stuff
return circle;
}

Array callback for every item apart from one

I have the following array:
var videos = [];
$('.video').each(function(){
videos.push($(this).attr('id'));
});
and inside here:
events: {
onPlay: function() {
var id = vid.attr('id');
var index = videos.indexOf(id);
videos.splice(index, 1);
console.log(videos);
}
}
I have also tried something like this:
// if($(this).attr('id') != $('.video').attr('id') ){
// jwplayer( $('.video').attr('id')).stop();
// }
I want to run a function for every array item (videos) apart from the array value equal to:
vid.attr('id')
I am using splice but that removes the item completely and since I have multiple videos I will end up with an empty array. I basically want only one video to play at the time so I need to stop the others.
Full function code:
$(function(){
//add attributes to your ".video" DIV placeholder to customimize output
//example: data-autostart="true" - see customSettings Object below.
if (typeof(jwplayer) !== 'undefined'){
var videos = [];
$('.video').each(function(){
videos.push($(this).attr('id'));
});
$('.video').each(function(){
var vid = $(this),
videoSettings = {},
settings = {
autostart: false,
width: '100%',
aspectratio: '16:9',
image: ''
},
customSettings = {
autostart: vid.attr('data-autostart'),
width: vid.attr('data-width'),
aspectratio: vid.attr('data-aspectratio'),
image: vid.attr('data-image')
};
$.extend(videoSettings, settings, customSettings);
var playerInstance = jwplayer( vid.attr('id') ).setup({
primary: "flash",
file: Drupal.settings.basePath + $(this).attr('data-src'),
autostart: videoSettings.autostart,
aspectratio: videoSettings.aspectratio,
image: Drupal.settings.basePath + videoSettings.image,
skin: "glow",
stretching: "exactfit",
width: videoSettings.width,
events: {
onPlay: function() {
var id = vid.attr('id');
var index = videos.indexOf(id);
videos.splice(index, 1);
console.log(videos);
// if($(this).attr('id') != $('.video').attr('id') ){
// jwplayer( $('.video').attr('id')).stop();
// }
}
}
// ga:{idstring: videoSettings.videotitle,
// trackingobject: "pageTracker"
// }
});
});
}
});
What about a simple forEach?
onPlay: function() {
var id = vid.attr('id');
videos.forEach(function(videoId) {
if(videoId != id) {
//You may want to check first if video is running at all
jwplayer(videoId).stop();
}
});
}
onPlay: function() {
var id = vid.attr('id');
for (var v in videos) {
if(id != v[i]) {
jwplayer(v[i].stop();
}
}
}

Refactoring repeated code in javascript prototype constructor

I have a open function that once triggered, simply plays video in a dedicated panel.
This function can be triggered in two ways - one with a click and another one with a page load (window load) with url that contains a valid anchor tag.
They all work fine but some codes of the window load handler are repetitive and I'm not too sure how I can keep this DRY.
Please take a look and point me in some directions on how I can write this better.
I commented in open function which is for which.
$.videoWatch.prototype = {
init: function() {
this.$openLinks = this.$element.find(".open");
this.$closeLinks = this.$element.find(".close");
this.open();
this.close();
},
_getContent: function(element) {
var $parent = element.parent(),
id = element.attr('href').substring(1),
title = $parent.data('title'),
desc = $parent.data('desc');
return {
title: title,
desc: desc,
id: id
}
},
open: function() {
var self = this;
//open theatre with window load with #hash id
window.onload = function() {
var hash = location.hash;
var $a = $('a[href="' + hash + '"]'),
content = self._getContent($a),
$li = $a.parents("li"),
$theatreVideo = $(".playing"),
$theatreTitle = $(".theatre-title"),
$theatreText = $(".theatre-text");
$(".theatre").attr('id', content.id);
$theatreTitle.text(content.title);
$theatreText.text(content.desc);
if ($theatreText.text().length >= 90) {
$(".theatre-text").css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter($theatreText);
}
$a.parent().addClass("active");
$(".theatre").insertAfter($li);
$(".theatre").slideDown('fast', scrollToTheatre);
oldIndex = $li.index();
}
//open theatre with click event
self.$openLinks.on("click", function(e) {
// e.preventDefault();
if (curID == $(this).parent().attr("id")) {
$("figure").removeClass("active");
$("button.more").remove();
$(".theatre").slideUp('fast');
$('.playing').attr("src", "");
removeHash();
oldIndex = -1;
curID = "";
return false
} else {
curID = $(this).parent().attr("id");
}
var $a = $(this),
content = self._getContent($a),
$li = $a.parents("li"),
$theatreVideo = $(".playing"),
$theatreTitle = $(".theatre-title"),
$theatreText = $(".theatre-text");
$(".theatre").attr('id', content.id);
$theatreTitle.text(content.title);
$theatreText.text(content.desc);
if ($theatreText.text().length >= 90) {
$(".theatre-text").css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter($theatreText);
}
if (!($li.index() == oldIndex)) {
$("figure").removeClass("active");
$(".theatre").hide(function(){
$a.parent().addClass("active");
$(".theatre").insertAfter($li);
$(".theatre").slideDown('fast', scrollToTheatre);
oldIndex = $li.index();
});
} else {
$(".theatre").insertAfter($li);
scrollToTheatre();
$("figure").removeClass("active");
$a.parent().addClass("active");
}
});
},
...
Simplified and refactored open method:
open: function() {
var self = this;
var serviceObj = {
theatreVideo : $(".playing"),
theatre: $(".theatre"),
theatreTitle : $(".theatre-title"),
theatreText : $(".theatre-text"),
setTheatreContent: function(content){
this.theatre.attr('id', content.id);
this.theatreTitle.text(content.title);
this.theatreText.text(content.desc);
if (this.theatreText.text().length >= 90) {
this.theatreText.css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter(this.theatreText);
}
},
activateTeatre: function(a, li){
a.parent().addClass("active");
this.theatre.insertAfter(li);
this.theatre.slideDown('fast', scrollToTheatre);
oldIndex = li.index();
}
};
//open theatre with window load with #hash id
window.onload = function() {
var hash = location.hash;
var $a = $('a[href="' + hash + '"]'),
content = self._getContent($a),
$li = $a.parents("li");
serviceObj.setTheatreContent(content);
serviceObj.activateTeatre($a, $li);
}
//open theatre with click event
self.$openLinks.on("click", function(e) {
// e.preventDefault();
if (curID == $(this).parent().attr("id")) {
$("figure").removeClass("active");
$("button.more").remove();
$(".theatre").slideUp('fast');
$('.playing').attr("src", "");
removeHash();
oldIndex = -1;
curID = "";
return false
} else {
curID = $(this).parent().attr("id");
}
var $a = $(this),
content = self._getContent($a),
$li = $a.parents("li");
serviceObj.setTheatreContent(content);
if (!($li.index() == oldIndex)) {
$("figure").removeClass("active");
$(".theatre").hide(function(){
serviceObj.activateTeatre($a, $li);
});
} else {
$(".theatre").insertAfter($li);
scrollToTheatre();
$("figure").removeClass("active");
$a.parent().addClass("active");
}
});
},
1st of all there are variables that don't depend on the input, you could pull them to the class (I'll show just one example, as you asked for directions):
init: function() {
this.$theatreVideo = $(".playing");
All the variables that do depend on the input, like $li could be moved to a function:
var $a = $(this),
$dependsOnA = self.dependsOnA($a);
self.actionDependsOnA($dependsOnA); // see below
function dependsOnA($a) {
return {
a: $a,
li: $a.parents("li"),
content: self._getContent($a)
}
}
Also the code that "repeats" can be moved to a function:
function actionDependsOnA($dependsOnA)
$(".theatre").attr('id', $dependsOnA.content.id);
$theatreTitle.text($dependsOnA.content.title);
$theatreText.text($dependsOnA.content.desc);
}

philogb/Treemap only renders undefined

I am trying to use https://github.com/philogb/jit to create a treemap of data coming from top. The data looks like:
"{"rsyslogd":{"children":[{"children":[],"data":{"PID":"17670","$color":"#D40106","cmdinfo":"<br><b>USER</b>:syslog<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:383m<br><b>RES</b>:5412<br><b>SHR</b>:1108<br><b>S</b>:S<br><b>CPU</b>:177%<br>%<b>MEM</b>:0.3%<br><b>TIME+</b>:32230:25<br>","$area":4},"id":"proc-1-17670","name":"rsyslogd"}],"data":{"PID":"rsyslogd","$area":50},"id":"proc-rsyslogd","name":"rsyslogd(1)"},"init":{"children":[{"children":[],"data":{"PID":"1","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:root<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:23584<br><b>RES</b>:1324<br><b>SHR</b>:1044<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.1%<br><b>TIME+</b>:0:00.10<br>","$area":2},"id":"proc-1-1","name":"init"}],"data":{"PID":"init","$area":30},"id":"proc-init","name":"init(1)"},"dbus-daemon":{"children":[{"children":[],"data":{"PID":"88","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:messageb<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:23556<br><b>RES</b>:328<br><b>SHR</b>:324<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.0%<br><b>TIME+</b>:0:00.00<br>","$area":1},"id":"proc-1-88","name":"dbus-daemon"}],"data":{"PID":"dbus-daemon","$area":20},"id":"proc-dbus-daemon","name":"dbus-daemon(1)"},"sshd":{"children":[{"children":[],"data":{"PID":"183","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:root<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:49436<br><b>RES</b>:1640<br><b>SHR</b>:1528<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.1%<br><b>TIME+</b>:0:00.14<br>","$area":2},"id":"proc-1-183","name":"sshd"}],"data":{"PID":"sshd","$area":30},"id":"proc-sshd","name":"sshd(1)"},"cron":{"children":[{"children":[],"data":{"PID":"209","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:root<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:18900<br><b>RES</b>:704<br><b>SHR</b>:628<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.0%<br><b>TIME+</b>:0:01.34<br>","$area":1},"id":"proc-1-209","name":"cron"}],"data":{"PID":"cron","$area":20},"id":"proc-cron","name":"cron(1)"},"mysqld":{"children":[{"children":[],"data":{"PID":"240","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:mysql<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:334m<br><b>RES</b>:49m<br><b>SHR</b>:3988<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.2%<br><b>TIME+</b>:58:21.44<br>","$area":33},"id":"proc-1-240","name":"mysqld"}],"data":{"PID":"mysqld","$area":340},"id":"proc-mysqld","name":"mysqld(1)"},"sendmail-mta":{"children":[{"children":[],"data":{"PID":"317","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:root<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:68284<br><b>RES</b>:844<br><b>SHR</b>:648<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.1%<br><b>TIME+</b>:0:31.61<br>","$area":2},"id":"proc-1-317","name":"sendmail-mta"}],"data":{"PID":"sendmail-mta","$area":30},"id":"proc-sendmail-mta","name":"sendmail-mta(1)"},"apache2":{"children":[{"children":[],"data":{"PID":"372","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:root<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:342m<br><b>RES</b>:8404<br><b>SHR</b>:5412<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.5%<br><b>TIME+</b>:0:50.46<br>","$area":6},"id":"proc-1-372","name":"apache2"},{"children":[],"data":{"PID":"24804","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:369m<br><b>RES</b>:81m<br><b>SHR</b>:56m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:5.3%<br><b>TIME+</b>:0:07.93<br>","$area":54},"id":"proc-1-24804","name":"apache2"},{"children":[],"data":{"PID":"24821","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:366m<br><b>RES</b>:66m<br><b>SHR</b>:41m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.3%<br><b>TIME+</b>:0:06.27<br>","$area":44},"id":"proc-1-24821","name":"apache2"},{"children":[],"data":{"PID":"24828","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:359m<br><b>RES</b>:71m<br><b>SHR</b>:53m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.7%<br><b>TIME+</b>:0:06.39<br>","$area":48},"id":"proc-1-24828","name":"apache2"},{"children":[],"data":{"PID":"24832","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:361m<br><b>RES</b>:70m<br><b>SHR</b>:52m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.6%<br><b>TIME+</b>:0:04.18<br>","$area":47},"id":"proc-1-24832","name":"apache2"},{"children":[],"data":{"PID":"24860","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:368m<br><b>RES</b>:77m<br><b>SHR</b>:53m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:5.1%<br><b>TIME+</b>:0:06.15<br>","$area":52},"id":"proc-1-24860","name":"apache2"},{"children":[],"data":{"PID":"24862","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:361m<br><b>RES</b>:58m<br><b>SHR</b>:41m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.8%<br><b>TIME+</b>:0:03.86<br>","$area":39},"id":"proc-1-24862","name":"apache2"},{"children":[],"data":{"PID":"24878","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:359m<br><b>RES</b>:51m<br><b>SHR</b>:34m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.4%<br><b>TIME+</b>:0:01.54<br>","$area":35},"id":"proc-1-24878","name":"apache2"},{"children":[],"data":{"PID":"24882","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:362m<br><b>RES</b>:53m<br><b>SHR</b>:34m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.5%<br><b>TIME+</b>:0:01.60<br>","$area":36},"id":"proc-1-24882","name":"apache2"},{"children":[],"data":{"PID":"24885","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:366m<br><b>RES</b>:61m<br><b>SHR</b>:38m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.0%<br><b>TIME+</b>:0:02.65<br>","$area":41},"id":"proc-1-24885","name":"apache2"},{"children":[],"data":{"PID":"24887","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:366m<br><b>RES</b>:73m<br><b>SHR</b>:50m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.8%<br><b>TIME+</b>:0:02.04<br>","$area":49},"id":"proc-1-24887","name":"apache2"},{"children":[],"data":{"PID":"24888","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:363m<br><b>RES</b>:60m<br><b>SHR</b>:36m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.9%<br><b>TIME+</b>:0:02.34<br>","$area":40},"id":"proc-1-24888","name":"apache2"},{"children":[],"data":{"PID":"24889","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:363m<br><b>RES</b>:61m<br><b>SHR</b>:39m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.0%<br><b>TIME+</b>:0:02.81<br>","$area":41},"id":"proc-1-24889","name":"apache2"},{"children":[],"data":{"PID":"24892","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:356m<br><b>RES</b>:47m<br><b>SHR</b>:33m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.1%<br><b>TIME+</b>:0:02.60<br>","$area":32},"id":"proc-1-24892","name":"apache2"},{"children":[],"data":{"PID":"24893","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:355m<br><b>RES</b>:49m<br><b>SHR</b>:33m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.2%<br><b>TIME+</b>:0:01.70<br>","$area":33},"id":"proc-1-24893","name":"apache2"},{"children":[],"data":{"PID":"24897","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:363m<br><b>RES</b>:62m<br><b>SHR</b>:38m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.1%<br><b>TIME+</b>:0:02.44<br>","$area":42},"id":"proc-1-24897","name":"apache2"},{"children":[],"data":{"PID":"24900","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:365m<br><b>RES</b>:63m<br><b>SHR</b>:39m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.1%<br><b>TIME+</b>:0:01.82<br>","$area":42},"id":"proc-1-24900","name":"apache2"},{"children":[],"data":{"PID":"24903","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:364m<br><b>RES</b>:56m<br><b>SHR</b>:36m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.7%<br><b>TIME+</b>:0:03.43<br>","$area":38},"id":"proc-1-24903","name":"apache2"},{"children":[],"data":{"PID":"24924","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:365m<br><b>RES</b>:61m<br><b>SHR</b>:37m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.0%<br><b>TIME+</b>:0:02.13<br>","$area":41},"id":"proc-1-24924","name":"apache2"},{"children":[],"data":{"PID":"24926","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:362m<br><b>RES</b>:51m<br><b>SHR</b>:33m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.3%<br><b>TIME+</b>:0:00.81<br>","$area":34},"id":"proc-1-24926","name":"apache2"},{"children":[],"data":{"PID":"24930","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:367m<br><b>RES</b>:61m<br><b>SHR</b>:36m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.0%<br><b>TIME+</b>:0:01.32<br>","$area":41},"id":"proc-1-24930","name":"apache2"},{"children":[],"data":{"PID":"24933","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:355m<br><b>RES</b>:44m<br><b>SHR</b>:30m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:2.9%<br><b>TIME+</b>:0:00.56<br>","$area":30},"id":"proc-1-24933","name":"apache2"},{"children":[],"data":{"PID":"24935","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:353m<br><b>RES</b>:39m<br><b>SHR</b>:24m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:2.5%<br><b>TIME+</b>:0:00.28<br>","$area":26},"id":"proc-1-24935","name":"apache2"},{"children":[],"data":{"PID":"24936","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:359m<br><b>RES</b>:52m<br><b>SHR</b>:33m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.4%<br><b>TIME+</b>:0:00.98<br>","$area":35},"id":"proc-1-24936","name":"apache2"},{"children":[],"data":{"PID":"24939","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:354m<br><b>RES</b>:41m<br><b>SHR</b>:27m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:2.7%<br><b>TIME+</b>:0:00.28<br>","$area":28},"id":"proc-1-24939","name":"apache2"},{"children":[],"data":{"PID":"24941","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:362m<br><b>RES</b>:57m<br><b>SHR</b>:34m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.7%<br><b>TIME+</b>:0:00.43<br>","$area":38},"id":"proc-1-24941","name":"apache2"},{"children":[],"data":{"PID":"24942","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:357m<br><b>RES</b>:41m<br><b>SHR</b>:26m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:2.7%<br><b>TIME+</b>:0:00.31<br>","$area":28},"id":"proc-1-24942","name":"apache2"},{"children":[],"data":{"PID":"24943","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:346m<br><b>RES</b>:16m<br><b>SHR</b>:8604<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:1.1%<br><b>TIME+</b>:0:00.09<br>","$area":12},"id":"proc-1-24943","name":"apache2"},{"children":[],"data":{"PID":"24944","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:351m<br><b>RES</b>:34m<br><b>SHR</b>:21m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:2.3%<br><b>TIME+</b>:0:00.18<br>","$area":24},"id":"proc-1-24944","name":"apache2"},{"children":[],"data":{"PID":"24945","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:363m<br><b>RES</b>:67m<br><b>SHR</b>:43m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:4.4%<br><b>TIME+</b>:0:00.99<br>","$area":45},"id":"proc-1-24945","name":"apache2"},{"children":[],"data":{"PID":"24946","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:342m<br><b>RES</b>:5552<br><b>SHR</b>:1800<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.4%<br><b>TIME+</b>:0:00.03<br>","$area":5},"id":"proc-1-24946","name":"apache2"},{"children":[],"data":{"PID":"24950","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:www-data<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:360m<br><b>RES</b>:48m<br><b>SHR</b>:30m<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:3.2%<br><b>TIME+</b>:0:00.39<br>","$area":33},"id":"proc-1-24950","name":"apache2"}],"data":{"PID":"apache2","$area":11400},"id":"proc-apache2","name":"apache2(32)"},"newrelic-daemon":{"children":[{"children":[],"data":{"PID":"399","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:root<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:16232<br><b>RES</b>:292<br><b>SHR</b>:288<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.0%<br><b>TIME+</b>:0:00.00<br>","$area":1},"id":"proc-1-399","name":"newrelic-daemon"},{"children":[],"data":{"PID":"400","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:root<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:264m<br><b>RES</b>:7284<br><b>SHR</b>:2360<br><b>S</b>:S<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.5%<br><b>TIME+</b>:40:33.01<br>","$area":6},"id":"proc-1-400","name":"newrelic-daemon"}],"data":{"PID":"newrelic-daemon","$area":80},"id":"proc-newrelic-daemon","name":"newrelic-daemon(2)"},"top":{"children":[{"children":[],"data":{"PID":"24988","$color":"#0EAB06","cmdinfo":"<br><b>USER</b>:root<br><b>PR</b>:20<br><b>NI</b>:0<br><b>VIRT</b>:19196<br><b>RES</b>:1328<br><b>SHR</b>:1048<br><b>S</b>:R<br><b>CPU</b>:0%<br>%<b>MEM</b>:0.1%<br><b>TIME+</b>:0:00.00<br>","$area":2},"id":"proc-1-24988","name":"top"}],"data":{"PID":"top","$area":30},"id":"proc-top","name":"top(1)"}}"
I then convert this into a JavaScript Object using JSON.parse(...) and assign it to data .
Then the actual InfoVis code:
function getCanvasConfig() {
var ua = navigator.userAgent,
iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
typeOfCanvas = typeof HTMLCanvasElement,
nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
textSupport = nativeCanvasSupport
&& (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
//I'm setting this based on the fact that ExCanvas provides text support for IE
//and that as of today iPhone/iPad current text support is lame
return {
labelType: (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML',
nativeTextSupport: (!nativeCanvasSupport || (textSupport && !iStuff)),
useGradients: nativeCanvasSupport,
animate: !(iStuff || !nativeCanvasSupport)
};
}
var config = getCanvasConfig();
var attrs = {id: "infovis"};
var tmConfig = {
//where to inject the visualization
injectInto: attrs.id,
//parent box title heights
titleHeight: 15,
//enable animations
animate: config.animate,
//box offsets
offset: 1,
//Attach left and right click events
Events: {
enable: true,
onClick: function(node) {
if(node) tm.enter(node);
},
onRightClick: function() {
tm.out();
}
},
duration: 1000,
//Enable tips
Tips: {
enable: true,
//add positioning offsets
offsetX: 20,
offsetY: 20,
//implement the onShow method to
//add content to the tooltip when a node
//is hovered
onShow: function(tip, node, isLeaf, domElement) {
var html = "<div class=\"tip-title\">" + node.name
+ "</div><div class=\"tip-text\">";
var data = node.data;
if(data.PID) {
html += "<br><b>PID</b>: " + data.PID;
}
if(data.cmdinfo) {
html += ""+ data.cmdinfo +"";
}
tip.innerHTML = html;
}
},
//Add the name of the node in the correponding label
//This method is called once, on label creation.
onCreateLabel: function(domElement, node){
domElement.innerHTML = node.name;
var data = node.data;
var PID = data.PID;
var style = domElement.style;
style.display = '';
style.border = '1px solid transparent';
domElement.onclick = function() {
$('input#PIDtext').val(PID);
};
domElement.onmouseover = function() {
style.border = '1px solid #efefef';
};
domElement.onmouseout = function() {
style.border = '1px solid transparent';
};
}
};
var tm = new $jit.TM.Squarified(tmConfig);
tm.loadJSON(data);
tm.refresh();
However, all I keep getting is "undefined" injected into the canvas. Any clues?
Just leaving this here:
The problem was with the data. I need to have a root node with appropriate name & ID that had the rest of the data as children.

jQuery plugin data mixup with multiple instances

I'm trying to develop a jQuery plugin to display adaptive image galleries. I'm using .data() to store the information for each slide of the gallery.
Everything appears to be working okay when displaying a single gallery, but gets mixed up when trying to have multiple gallery instances on a single page. A rough demo can be viewed here.
Here is the code that is being run:
(function($) {
$.Gallery = function(element, options) {
this.$el = $(element);
this._init(options);
};
$.Gallery.defaults = {
showCarousel : true,
};
$.Gallery.prototype = {
_init : function(options) {
var $this = $(this);
var instance = this;
// Get settings from stored instance
var settings = $this.data('settings');
var slides = $this.data('slides');
// Create or update the settings of the current gallery instance
if (typeof(settings) == 'undefined') {
settings = $.extend(true, {}, $.Gallery.defaults, options);
}
else {
settings = $.extend(true, {}, settings, options);
}
$this.data('settings', settings);
if (typeof(slides) === 'undefined') {
slides = [];
}
$this.data('slides', slides);
instance.updateCarousel();
},
addItems : function(newItems) {
var $this = $(this),
slides = $this.data('slides');
for (var i=0; i<newItems.length; i++) {
slides.push(newItems[i]);
};
},
updateCarousel : function() {
var instance = this,
$this = $(this);
slides = $(instance).data('slides');
var gallery = instance.$el.attr('id');
/* Create carousel if it doesn't exist */
if (instance.$el.children('.carousel').length == 0) {
$('<div class="carousel"><ul></ul></div>').appendTo(instance.$el);
var image = instance.$el.find('img');
};
var carouselList = instance.$el.find('.carousel > ul'),
slideCount = slides.length,
displayCount = carouselList.find('li').length;
if (displayCount < slideCount) {
for (var i=displayCount; i<slides.length; i++) {
slides[i].id = gallery + '-slide-' + i;
slide = $('<img>').attr({src : slides[i].thumb}).appendTo(carouselList).wrap(function() {
return '<li id="' + slides[i].id + '" />'
});
slide.on({
click : function() {
instance.slideTo($(this).parent().attr('id'));
},
});
};
};
},
slideTo : function(slideID) {
var $this = $(this);
var slides = $this.data('slides');
var image;
var $instance = $(this.$el);
$(slides).each( function() {
if (this.id == slideID){
image = this.img;
};
});
$('<img/>').load( function() {
$instance.find('div.image').empty().append('<img src="' + image + '"/>');
}).attr( 'src', image );
},
};
$.fn.gallery = function(options) {
args = Array.prototype.slice.call(arguments, 1);
this.each(function() {
var instance = $(this).data('gallery');
if (typeof(options) === 'string') {
if (!instance) {
console.error('Methods cannot be called until jquery.responsiveGallery has been initialized.');
}
else if (!$.isFunction(instance[options])) {
console.error('The method "' + options + '" does not exist in jquery.responsiveGallery.');
}
else {
instance[options].apply(instance, args);
}
}
else {
if (!instance) {
$(this).data('gallery', new $.Gallery(this, options));
}
}
});
return this;
};
})(jQuery);
$(window).load(function() {
$('#gallery2').gallery();
$('#gallery3').gallery();
$('#gallery2').gallery('addItems', [
{
img: 'images/image2.jpg',
thumb: 'images/image2_thumb.jpg',
desc: 'Image of number 2'
},
{
img: 'images/image3.jpg',
thumb: 'images/image3_thumb.jpg',
desc: 'Image of number 3'
},
{
img: 'images/image4.jpg',
thumb: 'images/image4_thumb.jpg',
desc: 'Image of number 4'
},
{
img: 'images/image5.jpg',
thumb: 'images/image5_thumb.jpg',
desc: 'Image of number 5'
}
]);
$('.pGallery').gallery('addItems', [
{
img: 'images/2.jpg',
thumb: 'images/2_thumb.jpg',
desc: 'Image of number 0'
},
{
img: 'images/image1.jpg',
thumb: 'images/image1_thumb.jpg',
desc: 'The second image'
}
]);
$('.pGallery').gallery('updateCarousel');
});
On the surface it appears to create two galleries with the proper slide structure of:
gallery2
gallery2-slide-0
gallery2-slide-1
gallery2-slide-2
gallery2-slide-3
gallery2-slide-4
gallery2-slide-5
gallery3
gallery3-slide-0
gallery3-slide-1
However, the onclick action doesn't work for the last two slides of Gallery2 (the slides duplicated in both galleries). Upon closer inspection of the DOM, I can see that the slides stored in data for gallery2, have the following ids:
gallery2
gallery2-slide-0
gallery2-slide-1
gallery2-slide-2
gallery2-slide-3
gallery3-slide-0
gallery3-slide-1
I'm not sure what is causing the mix-up or how to fix, so any help would be greatly appreciated.
Thanks
Your problem is that calling $('.pGallery').gallery('addItems'... cause the same objects to be added to the internal structure of both galleries, when you call $('.pGallery').gallery('updateCarousel'); the ids stored in those objects are overwritten.
You need to put a copy of the original objects in there. Do:
addItems : function(newItems) {
var $this = $(this),
slides = $this.data('slides');
for (var i=0; i<newItems.length; i++) {
//slides.push(newItems[i]);
slides.push(jQuery.extend({}, newItems[i]));
};
},
With jQuery.extend({}, oldObject) you can perform a shallow copy;

Categories