Is there a simple way to include the TOTAL value in the stackedAreaChart's interactiveGuideline tooltip? It'd be great if I could display total users using this awesome tooltip as well.
If not, what's the cleanest alternative?
You can use interactiveGuideline.tooltip.contentGenerator
https://github.com/novus/nvd3/blob/master/src/tooltip.js#L316
e.g.
chart.multiChart.interactiveLayer.tooltip.contentGenerator(function(d) {
var header = d.value;
var headerhtml =
"<thead><tr><td colspan='3'><strong class='x-value'>" +
header +
"</strong></td></tr></thead>";
var bodyhtml = "<tbody>";
var series = d.series;
series.forEach(function(c) {
var value = (c.value || 0).toFixed(2);
if (
c.key === keyForActualGreaterThanPredicted ||
c.key === keyForActualLessThanPredicted
) {
var diff = Math.abs(c.data.y0 - c.data.y1);
if (diff === 0) {
value = "-";
} else {
value = diff.toFixed(2);
}
}
bodyhtml =
bodyhtml +
"<tr><td class='legend-color-guide'><div style='background-color: " +
c.color +
";'></div></td><td class='key'>" +
c.key +
"</td><td class='value'>" +
value +
"</td></tr>";
});
bodyhtml = bodyhtml + "</tbody>";
return "<table>" + headerhtml + "" + bodyhtml + "</table>";
});
Related
Working with this plugin. Demo here https://www.jqueryscript.net/demo/animated-lines-elements-bezier/
On this demo when you resize the page it redraws. When I use this locally it doesn't redraw and the reason seems to be the this.selector is undefined when I run locally so after it clears the svg's it can't recreate them. Anyone have any idea why this might be?
See // Bug: comment below. Is this.selector a special variable for jquery plugins because I don't see it defined anywhere here, but the demo works so not sure how.
(function ($) {
$.fn.extend({
bezier: function (options) {
var defaults = {
strokeColor: '#999',
strokeWidth: 2,
opacity: 1,
fill: 'none',
animate: true,
animationDirection: 'right',
animationDuration: 0.75
};
// Color wheel stuff
var color_wheel = [];
var frequency = .3;
for (var i = 0; i < 32; ++i) {
red = Math.sin(frequency * i + 0) * 127 + 128;
green = Math.sin(frequency * i + (2 * Math.PI / 3)) * 127 + 128;
blue = Math.sin(frequency * i + (4 * Math.PI / 3)) * 127 + 128;
color_wheel.push(RGB2Color(red, green, blue));
}
var color_index = 0;
function RGB2Color(r, g, b) {
return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b);
}
function byte2Hex(n) {
var nybHexString = "0123456789ABCDEF";
return String(nybHexString.substr((n >> 4) & 0x0F, 1)) + nybHexString.substr(n & 0x0F, 1);
}
// Color wheel stuff
//override default options with user set options
var settings = $.extend(defaults, options);
var me = {};
me.init = function (initObj) {
if (initObj) {
$.each(initObj, function (index, value) {
settings[index] = value;
});
}
};
me.set = function (prop, val) {
settings[prop] = val;
};
me.on = function (el1, el2) {
var $el1 = $(el1);
var $el2 = $(el2);
if ($el1.length && $el2.length) {
var svgheight, p, svgleft, svgtop, svgwidth;
var el1pos = $(el1).offset();
var el2pos = $(el2).offset();
var el1H = $(el1).outerHeight();
var el1W = $(el1).outerWidth();
var el2H = $(el2).outerHeight();
var el2W = $(el2).outerWidth();
svgleft = Math.round(el1pos.left + el1W);
svgwidth = Math.round(el2pos.left - svgleft);
var curvinessFactor, cpt;
////Determine which is higher/lower
if ((el2pos.top + (el2H / 2)) <= (el1pos.top + (el1H / 2))) {
// console.log("low to high");
svgheight = Math.round((el1pos.top + el1H / 2) - (el2pos.top + el2H / 2));
svgtop = Math.round(el2pos.top + el2H / 2) - settings.strokeWidth;
cpt = Math.round(svgwidth * Math.min(svgheight / 300, 1));
p = "M0," + (svgheight + settings.strokeWidth) + " C" + cpt + "," + (svgheight + settings.strokeWidth) + " " + (svgwidth - cpt) + "," + settings.strokeWidth + " " + svgwidth + "," + settings.strokeWidth;
}
else {
// console.log("high to low");
svgheight = Math.round((el2pos.top + el2H / 2) - (el1pos.top + el1H / 2));
svgtop = Math.round(el1pos.top + el1H / 2) - settings.strokeWidth;
cpt = Math.round(svgwidth * Math.min(svgheight / 300, 1));
p = "M0," + settings.strokeWidth + " C" + cpt + ",0 " + (svgwidth - cpt) + "," + (svgheight + settings.strokeWidth) + " " + svgwidth + "," + (svgheight + settings.strokeWidth);
}
$ropebag = $('#ropebag').length ? $('#ropebag') : $('main').append($("<div id='ropebag' />")).find('#ropebag');
var svgnode = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var newpath = document.createElementNS('http://www.w3.org/2000/svg', "path");
var color_to_use = (settings.strokeColor != 'rainbow') ? settings.strokeColor : color_wheel[color_index];
color_index = color_index + 1;
if (color_index == 32) {
color_index = 0;
}
newpath.setAttributeNS(null, "d", p);
newpath.setAttributeNS(null, "stroke", color_to_use);
newpath.setAttributeNS(null, "stroke-width", settings.strokeWidth);
newpath.setAttributeNS(null, "opacity", settings.opacity);
newpath.setAttributeNS(null, "fill", settings.fill);
svgnode.appendChild(newpath);
$(svgnode).css({
left: svgleft,
top: svgtop,
position: 'absolute',
width: svgwidth,
height: svgheight + settings.strokeWidth * 2,
minHeight: '20px'
});
$ropebag.append(svgnode);
if (settings.animate) {
var pl = newpath.getTotalLength();
// Set up the starting positions
newpath.style.strokeDasharray = pl + ' ' + pl;
if (settings.animationDirection == 'right') {
newpath.style.strokeDashoffset = pl;
}
else {
newpath.style.strokeDashoffset = -pl;
}
// IE sucks, dont expect this to work.
newpath.getBoundingClientRect();
newpath.style.transition = newpath.style.WebkitTransition = 'stroke-dashoffset ' + settings.animationDuration + 's ease-in-out';
newpath.style.strokeDashoffset = '0';
}
}
};
me.off = function () {
$("#ropebag").empty();
};
// Redraw upon resizing the window
var selector = this.selector;
$(window).resize(function () {
me.off();
// BUG: selector is undefined
console.log(selector);
$(selector).each(function () {
console.log("looping over eac comp");
var theID = this.id;
$("." + theID).each(function (i, e) {
var rand = Math.random() * 0.7 + 0.3;
me.set('animationDuration', rand);
me.on($("#" + theID), e);
console.log("Window resize" + theID);
});
});
});
// Loop through each parent and draw the lines connecting children
return this.each(function () {
var theID = this.id;
$("." + theID).each(function (i, e) {
var rand = Math.random() * 0.7 + 0.3;
me.set('animationDuration', rand);
me.on($("#" + theID), e);
});
});
}
});
})(jQuery);
Here is my code , the same code hitting the URL in chrome, setGridParam function is not working properly, but its not working in firebox, i tried as much as possible ways, please help me to out.
Cur_Status = $("#ddlStatus option:selected").val();
var FromDate = $("#txtFromDate").attr("value");
var ToDate = $("#txtToDate").attr("value");
var pieces = FromDate.split('/');
pieces.reverse();
FromDate = pieces.join('-');
var pieces = ToDate.split('/');
pieces.reverse();
ToDate = pieces.join('-');
if (new Date(FromDate) > new Date(ToDate)) {
alert("Please select ToDate greater than FromDate.");
return false;
}
var MyCall = 0;
var check = document.getElementById("ChkMycall").checked;
if (check) {
MyCall = 1;
}
else {
MyCall = 0;
}
var CheckStatus =
$('input:radio[name=rbt_Type]:checked').val();
FromDate = $("#txtFromDate").attr("value");
ToDate = $("#txtToDate").attr("value");
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1; //January is 0!
var yyyy = today.getFullYear();
if (dd < 10) {
dd = '0' + dd
}
if (mm < 10) {
mm = '0' + mm
}
var today = mm + '/' + yyyy;
var Cur_Date = today;
var qryStr = CheckStatus + "^" + FromDate + "^" + ToDate + "^" + MyCall;
$("#tblCallStatus").jqGrid("clearGridData");
$("#tblCallStatus").setGridParam({ url: "../Handlers/CallStatusHandler.ashx? Mode=Load & iStatus=" + Cur_Status + "&Date=" + Cur_Date + "& QryString=" + qryStr, datatype: "json" });
$("#tblCallStatus").trigger('reloadGrid');
this the code i am using, to hit the URL, through the javascript i try to load the JQGrid.
The URL, which you set contains a lot of spaces, which should be not used. Try to replace
url: "../Handlers/CallStatusHandler.ashx? Mode=Load & iStatus=" + Cur_Status + "&Date=" + Cur_Date + "& QryString=" + qryStr
to
url: "../Handlers/CallStatusHandler.ashx?Mode=Load&iStatus=" + Cur_Status + "&Date=" + Cur_Date + "&QryString=" + qryStr
There is a problem with my run time execution in my code. It takes too long to finish, since I have to loop a large amounts of data to look for matching data. I used array on the first loop value though, I don't know how to array the second value without affecting the first array.
Name of the first array : Source
Name of the Second array : Target
Here is my Code:
function inactive_sort_cebu() {
var ss = SpreadsheetApp.openById('169vIeTMLK4zN5VGCw1ktRteCwMToU8eGABFDxg52QBk');
// var sheet = ss.getSheets()[0];// Manila Roster
var sheet2 = ss.getSheets()[1];// Cebu Roster
var column = sheet2.getRange("C1:C").getValues();
var last = column.filter(String).length;
// -----------------------------------------------------------
var ss1 = SpreadsheetApp.openById('153ul2x2GpSopfMkCZiXCjmqdPTYhx4QiOdP5SBYzQkc');
// var sched_sheet = ss1.getSheets()[0];// ScheduledForm_Manila
var sched_sheet2 = ss1.getSheets()[1];// ScheduledForm_Cebu
var column2 = sched_sheet2.getRange("C1:C").getValues();
var last2 = column2.filter(String).length;
//// -------------------------Manila-Roster---------------------------------
var i= 2;
var column3 = sched_sheet2.getRange("J1:J").getValues();
var a = column3.filter(String).length - 1;
// var a = 0;
try{
var source = sched_sheet2.getRange("C2:C").getValues();
for (a;a<=last2;){
/// this is the code that i need to array without affecting the other array which is the source variable
var target = sheet2.getRange("C"+ i).getValue();
if(source[a] == target){
// Get "No Schedule Request data on Cell H
var data = sched_sheet2.getRange("H"+(a+2)).getValue();
// Get "Schedule Request data on Cell F
var data1 = sched_sheet2.getRange("F"+(a+2)).getValue();
var condition_1 = sched_sheet2.getRange("D"+(a+2)).getValue();
var condition_2 = sched_sheet2.getRange("G"+(a+2)).getValue();
var format_Con_2 = Utilities.formatDate(condition_2, 'Asia/Manila', 'm/dd/yyyy');
var condition_3 = sched_sheet2.getRange("K"+ (a+2)).getValue();
var date = new Date();
var date_Manila = Utilities.formatDate(date, 'Asia/Manila', 'm/dd/yyyy');
if(condition_1 == "No Schedule Request" && format_Con_2 <= date_Manila && condition_3 ==""){
sheet2.getRange("AA"+ i).setValue("N - "+ data);
sched_sheet2.getRange("J"+ (a+2)).setValue("Cebu");
sched_sheet2.getRange("K"+ (a+2)).setValue("Done");
a++;
}
else if (condition_1 == "Schedule Request" && format_Con_2 <= date_Manila && condition_3 ==""){
sheet2.getRange("AA"+ i).setValue("Y - "+data1);
sched_sheet2.getRange("J"+ (a+2)).setValue("Cebu");
sched_sheet2.getRange("K"+ (a+2)).setValue("Done");
a++;
}
else{a++;}
i=2;}
else {i++;}
}
This is a simple example of a web app that puts an editable spreadsheet on an HTML Page. Publish as a webapp. I loops through the 2D array that you get when you getValues from the getDataRange() method. In this case I'm just intertwining html into the mix.
Code.gs:
var SSID='SpreadsheetID';
var sheetName='Sheet Name';
function htmlSpreadsheet(mode)
{
var mode=(typeof(mode)!='undefined')?mode:'dialog';
var br='<br />';
var s='';
var hdrRows=1;
var ss=SpreadsheetApp.openById(SSID);
var sht=ss.getSheetByName(sheetName);
var rng=sht.getDataRange();
var rngA=rng.getValues();
s+='<table>';
for(var i=0;i<rngA.length;i++)
{
s+='<tr>';
for(var j=0;j<rngA[i].length;j++)
{
if(i<hdrRows)
{
s+='<th id="cell' + i + j + '">' + '<input id="txt' + i + j + '" type="text" value="' + rngA[i][j] + '" size="10" onChange="updateSS(' + i + ',' + j + ');" />' + '</th>';
}
else
{
s+='<td id="cell' + i + j + '">' + '<input id="txt' + i + j + '" type="text" value="' + rngA[i][j] + '" size="10" onChange="updateSS(' + i + ',' + j + ');" />' + '</th>';
}
}
s+='</tr>';
}
s+='</table>';
//s+='<div id="success"></div>';
s+='</body></html>';
switch (mode)
{
case 'dialog':
var userInterface=HtmlService.createHtmlOutputFromFile('htmlss').setWidth(1000).setHeight(450);
userInterface.append(s);
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Spreadsheet Data for ' + ss.getName() + ' Sheet: ' + sht.getName());
break;
case 'web':
var userInterface=HtmlService.createHtmlOutputFromFile('htmlss').setWidth(1000).setHeight(450);
return userInterface.append(s).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
}
function updateSpreadsheet(i,j,value)
{
var ss=SpreadsheetApp.openById(SSID);
var sht=ss.getSheetByName(sheetName);
var rng=sht.getDataRange();
var rngA=rng.getValues();
rngA[i][j]=value;
rng.setValues(rngA);
var data = {'message':'Cell[' + Number(i + 1) + '][' + Number(j + 1) + '] Has been updated', 'ridx': i, 'cidx': j};
return data;
}
function doGet()
{
var output=htmlSpreadsheet('web');
return output;
}
htmlss.html:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
});
function updateSS(i,j)
{
var str='#txt' + String(i) + String(j);
var value=$(str).val();
$(str).css('background-color','#ffff00');
google.script.run
.withSuccessHandler(successHandler)
.updateSpreadsheet(i,j,value)
}
function successHandler(data)
{
$('#success').text(data.message);
$('#txt' + data.ridx + data.cidx).css('background-color','#ffffff');
}
console.log('My Code');
</script>
<style>
th{text-align:left}
</style>
</head>
<body>
<div id="success"></div>
I would like to select the XPath of a tag and the content of the tag, something similar to what Evernote is doing. However, I cannot find any examples. How could this be achieved?
After some research we found this:
function createXPathFromElement(elm) {
var allNodes = document.getElementsByTagName('*');
for (segs = []; elm && elm.nodeType == 1; elm = elm.parentNode)
{
if (elm.hasAttribute('id')) {
var uniqueIdCount = 0;
for (var n=0;n < allNodes.length;n++) {
if (allNodes[n].hasAttribute('id') && allNodes[n].id == elm.id) uniqueIdCount++;
if (uniqueIdCount > 1) break;
};
if ( uniqueIdCount == 1) {
segs.unshift('id("' + elm.getAttribute('id') + '")');
return segs.join('/');
} else {
segs.unshift(elm.localName.toLowerCase() + '[#id="' + elm.getAttribute('id') + '"]');
}
} else if (elm.hasAttribute('class')) {
segs.unshift(elm.localName.toLowerCase() + '[#class="' + elm.getAttribute('class') + '"]');
} else {
for (i = 1, sib = elm.previousSibling; sib; sib = sib.previousSibling) {
if (sib.localName == elm.localName) i++;
};
segs.unshift(elm.localName.toLowerCase() + '[' + i + ']');
};
};
return segs.length ? '/' + segs.join('/') : null;
}
function lookupElementByXPath(path) {
var evaluator = new XPathEvaluator();
var result = evaluator.evaluate(path, document.documentElement, null,XPathResult.FIRST_ORDERED_NODE_TYPE, null);
return result.singleNodeValue;
}
I am using jquery ajax to pull from the twitter api, i'm sure there's a easy way, but I can't find it on how to get the "tweet" to render any links that were tweeted to appear as a link. Right now it's only text.
$.ajax({
type : 'GET',
dataType : 'jsonp',
url : 'http://search.twitter.com/search.json?q=nettuts&rpp=2',
success : function(tweets) {
var twitter = $.map(tweets.results, function(obj, index) {
return {
username : obj.from_user,
tweet : obj.text,
imgSource : obj.profile_image_url,
geo : obj.geo
};
});
UPDATE:
The following function (plugin) works perfectly.
(function($) {
$.socialFader = function(options) {
var settings = {
tweetHolder : null,
tweetCount : 100,
fadeSpeed : 500,
tweetName: 'jquery'
};
if (options) {
$.extend(settings, options);
};
var URL = "http://search.twitter.com/search.json?q="+settings.tweetName+"&rpp=" + settings.tweetCount + "&callback=?";
function relative_time(time_value) {
var values = time_value.split(" ");
time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
var parsed_date = Date.parse(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
delta = delta + (relative_to.getTimezoneOffset() * 60);
var r = '';
if (delta < 60) {
r = 'a minute ago';
} else if(delta < 120) {
r = 'couple of minutes ago';
} else if(delta < (45*60)) {
r = (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (90*60)) {
r = 'an hour ago';
} else if(delta < (24*60*60)) {
r = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
r = '1 day ago';
} else {
r = (parseInt(delta / 86400)).toString() + ' days ago';
}
return r;
};
String.prototype.hashify = function() {
return this.replace(/#([A-Za-z0-9\/\.]*)/g, function(m) {
return '<a target="_new" href="http://twitter.com/search?q=' + m.replace('#','') + '">' + m + "</a>";
});
};
String.prototype.linkify = function(){
return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
return m.link(m);
});
};
String.prototype.atify = function() {
return this.replace(/#[\w]+/g, function(m) {
return '' + m + "";
});
};
$.getJSON(URL, function(JSON) {
$.each(JSON.results, function(i, tweet) {
var profilePicture = tweet.profile_image_url;
var userLink = tweet.from_user;
var text = tweet.text;
text = text.linkify().atify().hashify();
var createdAt = new Date(tweet.created_at);
var myTweet = '' + userLink + ' ';
myTweet += text;
$(settings.tweetHolder).append('<li class="cycles">' + myTweet + '</li>');
});
var elements = $(settings.tweetHolder).children();
var timeOutStart = 5000;
function fader(elementId) {
setTimeout(function() {
$(elements[elementId]).fadeOut(settings.fadeSpeed, function() {
$(elements[elementId + 1]).fadeIn(settings.fadeSpeed);
});
}, timeOutStart * (elementId));
};
for (var j = 0; j < elements.length; j++) {
fader(j);
};
});
};
})(jQuery);
Within my Ready Statement :
$.socialFader({ tweetHolder:"#twitter", tweetName:"nettuts", tweetCount:2 });
Here is a plugin I wrote which really simplifies the tweet/json aggregation then parsing. It fades the tweets in and out. Just grab the needed code. Enjoy.
(function($) {
$.socialFader = function(options) {
var settings = {
tweetHolder : null,
tweetCount : 99,
fadeSpeed : 500,
};
if (options) {
$.extend(settings, options);
};
var URL = "http://search.twitter.com/search.json?q=jquery&rpp=" + settings.tweetCount + "&callback=?";
function relative_time(time_value) {
var values = time_value.split(" ");
time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
var parsed_date = Date.parse(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
delta = delta + (relative_to.getTimezoneOffset() * 60);
var r = '';
if (delta < 60) {
r = 'a minute ago';
} else if(delta < 120) {
r = 'couple of minutes ago';
} else if(delta < (45*60)) {
r = (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (90*60)) {
r = 'an hour ago';
} else if(delta < (24*60*60)) {
r = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
r = '1 day ago';
} else {
r = (parseInt(delta / 86400)).toString() + ' days ago';
}
return r;
};
String.prototype.hashify = function() {
return this.replace(/#([A-Za-z0-9\/\.]*)/g, function(m) {
return '<a target="_new" href="http://twitter.com/search?q=' + m.replace('#','') + '">' + m + "</a>";
});
};
String.prototype.linkify = function(){
return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
return m.link(m);
});
};
String.prototype.atify = function() {
return this.replace(/#[\w]+/g, function(m) {
return '' + m + "";
});
};
$.getJSON(URL, function(JSON) {
$.each(JSON.results, function(i, tweet) {
var profilePicture = tweet.profile_image_url;
var userLink = tweet.from_user;
var text = tweet.text;
text = text.linkify().atify().hashify();
var createdAt = new Date(tweet.created_at);
var myTweet = '' + userLink + ' ';
myTweet += text;
$(settings.tweetHolder).append('<li class="cycles">' + myTweet + '</li>');
});
var elements = $(settings.tweetHolder).children();
var timeOutStart = 5000;
function fader(elementId) {
setTimeout(function() {
$(elements[elementId]).fadeOut(settings.fadeSpeed, function() {
$(elements[elementId + 1]).fadeIn(settings.fadeSpeed);
});
}, timeOutStart * (elementId));
};
for (var j = 0; j < elements.length; j++) {
fader(j);
};
});
};
})(jQuery);
You need to parse the tweet content, find the urls and then put them in between yourself.
Unfortunately, at the moment, the search API doesn't have the facility to break out tweet entities (i.e., links, mentions, hashtags) like some of the REST API methods. So, you could either parse out the entities yourself (I use regular expressions) or call back into the rest API to get the entities.
If you decide to call back into the REST API, and once you have extracted the status ID from the search API results, you would make a call to statuses/show like the following:
http://api.twitter.com/1/statuses/show/60183527282577408.json?include_entities=true
In the resultant JSON, notice the entities object.
"entities":{"urls":[{"expanded_url":null,"indices":[68,88],"url":"http:\/\/bit.ly\/gWZmaJ"}],"user_mentions":[],"hashtags":[{"text":"wordpress","indices":[89,99]}]}
You can use the above to locate the specific entities in the tweet (which occur between the string positions denoted by the indices property) and transform them appropriately.
If you prefer to parse the entities yourself, here are the (.NET Framework) regular expressions I use:
Link Match Pattern
(?:<\w+.*?>|[^=!:'"/]|^)((?:https?://|www\.)[-\w]+(?:\.[-\w]+)*(?::\d+)?(?:/(?:(?:[~\w\+%-]|(?:[,.;#:][^\s$]))+)?)*(?:\?[\w\+%&=.;:-]+)?(?:\#[\w\-\.]*)?)(?:\p{P}|\s|<|$)
Mention Match Pattern
\B#([\w\d_]+)
Hashtag Match Pattern
(?:(?:^#|[\s\(\[]#(?!\d\s))(\w+(?:[_\-\.\+\/]\w+)*)+)
Twitter also provides an open source library that helps capture Twitter-specific entities like links, mentions and hashtags. This java file contains the code defining the regular expressions that Twitter uses, and this yml file contains test strings and expected outcomes of many unit tests that exercise the regular expressions in the Twitter library.
How you process the tweet is up to you, however I process a copy of the original tweet, and pull all the links first, replacing them in the copy with spaces (so as not to modify the string length.) I capture the start and end locations of the match in the string, along with the matched content. I then pull mentions, then hashtags -- again replacing them in the tweet copy with spaces.
This approach ensures that I don't find false positives for mentions and hashtags in any links in the tweet.
I slightly modified previous one. Nothing lefts after all tweets disappears one by one.
Now it checks if there is any visible tweets and then refreshes tweets.
(function($) {
$.socialFader = function(options) {
var settings = {
tweetHolder : null,
tweetCount : 99,
fadeSpeed : 500,
};
if (options) {
$.extend(settings, options);
};
var URL = "http://search.twitter.com/search.json?q=istanbul&rpp=" + settings.tweetCount + "&callback=?";
function relative_time(time_value) {
var values = time_value.split(" ");
time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
var parsed_date = Date.parse(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
delta = delta + (relative_to.getTimezoneOffset() * 60);
var r = '';
if (delta < 60) {
r = 'a minute ago';
} else if(delta < 120) {
r = 'couple of minutes ago';
} else if(delta < (45*60)) {
r = (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (90*60)) {
r = 'an hour ago';
} else if(delta < (24*60*60)) {
r = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
r = '1 day ago';
} else {
r = (parseInt(delta / 86400)).toString() + ' days ago';
}
return r;
};
String.prototype.hashify = function() {
return this.replace(/#([A-Za-z0-9\/\.]*)/g, function(m) {
return '<a target="_new" href="http://twitter.com/search?q=' + m.replace('#','') + '">' + m + "</a>";
});
};
String.prototype.linkify = function(){
return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
return m.link(m);
});
};
String.prototype.atify = function() {
return this.replace(/#[\w]+/g, function(m) {
return '' + m + "";
});
};
$.getJSON(URL, function(JSON) {
$(settings.tweetHolder).find('li.cycles').remove();
$.each(JSON.results, function(i, tweet) {
var profilePicture = tweet.profile_image_url;
var userLink = tweet.from_user;
var text = tweet.text;
text = text.linkify().atify().hashify();
var createdAt = new Date(tweet.created_at);
var myTweet = '' + userLink + ' ';
myTweet += text;
$(settings.tweetHolder).append('<li class="cycles">' + myTweet + '</li>');
});
var elements = $(settings.tweetHolder).children();
var timeOutStart = 5000;
function fader(elementId) {
setTimeout(function() {
$(elements[elementId]).fadeOut(settings.fadeSpeed, function() {
$(elements[elementId + 1]).fadeIn(settings.fadeSpeed);
});
if (jQuery('#twitter ul li.cycles:visible').length==1) {
jQuery.socialFader({ tweetHolder:"#twitter ul", tweetCount:5 });
}
}, timeOutStart * (elementId));
};
for (var j = 0; j < elements.length; j++) {
fader(j);
};
});
};
})(jQuery);
jQuery(document).ready(function(){
jQuery.socialFader({ tweetHolder:"#twitter ul", tweetCount:5 });
});