Skip to content

Instantly share code, notes, and snippets.

@rigobertocontreras
Forked from randerzander/front.html
Created August 5, 2017 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rigobertocontreras/89e5d26c28c9db123b96910a9585c8f7 to your computer and use it in GitHub Desktop.
Save rigobertocontreras/89e5d26c28c9db123b96910a9585c8f7 to your computer and use it in GitHub Desktop.
zeppelin angular-tricks
%angular
<input id="textbox" class="hide" ng-model="someAngularVar"></input>
<button id="btn" type="submit" onclick="update()">UpperCase It!</button>
<script type="text/javascript">
function update(){
var element = $('#textbox');
var currentVal = element.val();
//Update the value
element.val(currentVal.toUpperCase());
//Give Angular a few ms to mark 'textbox' as dirty & get ready to catch change event
window.setTimeout(function(){
//Triggers Angular to do its thing with changed model values
element.trigger('input');
}, 500);
}
</script>
%sh
# It's a good idea to wrap and parameterize download steps
# You never know how many times users will "Run All" a notebook, constantly re-downloading files
URL=ftp://ita.ee.lbl.gov/traces/NASA_access_log_Jul95.gz
TARGET=logs.gz
if [ ! -f $TARGET ]; then
echo "Downloading logs.."
wget -nv $URL -O $TARGET
fi
echo "Logs saved to $TARGET.."
%angular
<!-- To avoid editing JS, I put the downstream paragraph IDs in a comma separated attribute "refresh" -->
<div id="chart" data="data" yAxes="Requests" title="Web Activity"
refresh="20160914-221415_1942638313,20160914-225103_297917127,20160914-221501_1892040487,20160912-040402_885019782"></div>
<input id="bounds" type="text" class="hide" ng-model="bounds"></input>
<center>
<h5 id="t1">Left Bound: </h5><h5 id="t2">Right Bound: </h5>
<button id="btnRefresh" type="submit" class="btn btn-primary" ng-click="">Run Queries</button>
</center>
<script type="text/javascript">
var div = $('#chart');
var bounds = $('#bounds');
//Get list of paragraphs to refresh on button click
$.each(div.attr('refresh').split(','), function(i, v){
$('#btnRefresh').attr('ng-click', $('#btnRefresh').attr('ng-click') + "z.runParagraph('"+v+"');");
});
var data = window.angularVars[div.attr('data')];
var schema = window.angularVars[div.attr('data')+'Schema'];
//Convert query results into Plotly traces: https://plot.ly/javascript/multiple-axes/#multiple-yaxes
var traces = [];
$.each(schema.fields.slice(1), function(i, field){ //Setup trace metadata
var trace = {x: [], y: [], name: field.name, type: 'scatter', yaxis: 'y'};
traces.push(trace);
});
//Load query results into trace arrays
$.each(data, function(i,row){
//First value is a date
var date = new Date(row.values[0]);
$.each(row.values.slice(1), function(v, cell){
traces[v].x.push(date);
traces[v].y.push(cell);
});
});
//Setup axis labels
var layout = { title: div.attr('title'), legend: {orientation: 'h'}};
$.each(div.attr('yAxes').split(','), function(i, v){
var axis = {title: v};
var key = 'yaxis';
if (i > 0){
key += i+1;
axis.side = 'right';
axis.overlaying = 'y';
axis.position = 1-.04*(i-1);
}
layout[key] = axis;
});
//Hide some of Plotly's external web-links
var config = {displaylogo: div.attr('showLinks'), showLinks: div.attr('showLinks'), modeBarButtonsToRemove: ['sendDataToCloud']};
//Draw the chart
Plotly.newPlot('chart', traces, layout, config);
//Execute this function when user zooms in/out
div.bind('plotly_relayout', function(event,meta){
var t1 = new Date(meta['xaxis.range[0]']);
var t2 = new Date(meta['xaxis.range[1]']);
$('#t1').text('Left Bound: ' + t1);
$('#t2').text('Right Bound: ' + t2);
var text = Math.floor(t1.getTime()/1000) + "|" + Math.floor(t2.getTime()/1000);
bounds.val(text);
//Give Angular a few ms to mark 'bounds' as dirty/get ready to catch change event
window.setTimeout(function(){bounds.trigger('input');}, 500);
});
%angular
<!-- Avoid constantly editing JS and list the Angular vars you want exposed in an HTML attribute: -->
<div id="dummy" vars="someScopeVar1,someScopeVar2"></div>
<script type="text/javascript">
//Given an element in the note & list of values to fetch from Spark
//window.angularVars.myVal will be current value of backend Spark val of same name
function hoist(element){
var varNames = element.attr('vars').split(',');
window.angularVars = {};
var scope = angular.element(element.parent('.ng-scope')).scope().compiledScope;
$.each(varNames, function(i, v){
window[v+'-watcher'] = scope.$watch(v, function(newVal, oldVal){
window.angularVars[v] = newVal;
});
});
}
hoist($('#dummy'));
</script>
%angular
<div id="myAppDiv"></div>
<script type="text/javascript">
var element = $('#myAppDiv');
element.append(window.angularVars.someScopeVar1 + window.angularVars.someScopeVar2);
</script>
%spark
case class Log(Source: String, ts: String, Verb: String, URL: String, Protocol: String, Code: String, Size: Int)
/*
Sample Data:
199.72.81.55 - - [01/Jul/1995:00:00:01 -0400] "GET /history/apollo/ HTTP/1.0" 200 6245
199.120.110.21 - - [01/Jul/1995:00:00:09 -0400] "GET /shuttle/missions/sts-73/mission-sts-73.html HTTP/1.0" 200 4085
burger.letters.com - - [01/Jul/1995:00:00:11 -0400] "GET /shuttle/countdown/liftoff.html HTTP/1.0" 304 0
knuth.mtsu.edu - - [22/Jul/1995:01:49:32 -0400] "GET /images/">index of /images HTTP/1.0" 404 -
*/
sc.textFile("logs.gz").filter(_.split("\\s").size >= 10).map(x => {
val req = x.split("\"").slice(1, x.split("\"").size-1).mkString("\"").split("\\s")
val ts = x.split("\\[")(1).split("\\]")(0).split(" ")(0)
val postReq = x.split("\"").last.trim.split("\\s")
Log(x.split(" ")(0), ts, req.head, req.slice(1, req.size-1).mkString(" "), req.last, postReq(0), if (postReq.size > 1) postReq(1).replace("-", "0").toInt else 0)
}).toDF().createOrReplaceTempView("weblogs_raw")
sqlContext.sql("""
create table if not exists weblogs stored as parquet as
select source, from_unixtime(unix_timestamp(ts, 'dd/MMMM/yyyy:HH:mm:ss')) as datetime, verb, url, protocol, code, size from weblogs_raw
""")
sqlContext.cacheTable("weblogs")
sqlContext.sql("select count(*) from weblogs").collect()
%spark
//Query for populating Plotly graph
val query = """
select
concat(date_format(datetime, 'yyyy-MM-dd HH'), ':00:00') as time,
count(*) as activity
from weblogs
group by concat(date_format(datetime, 'yyyy-MM-dd HH'), ':00:00')
order by time asc
"""
val data = sqlContext.sql(query)
z.angularBind("data", data.collect())
z.angularBind("dataSchema", data.schema)
z.run("20160912-040323_647948317")
//Convenient wrapper around table display syntax: https://zeppelin.apache.org/docs/0.7.0-SNAPSHOT/displaysystem/basicdisplaysystem.html#table
def printQueryResultsAsTable(query: String) : Unit = {
val df = sqlContext.sql(query.replace("?", ""))
println("%table " + df.columns.mkString("\t"))
println(df.map(x => x.mkString("\t")).collect().mkString("\n"))
}
//Create variables to hold query texts
var logQuery = ""
var sourceQuery = ""
var areaQuery = ""
var codeQuery = ""
//Helper for resetting query texts to default
def resetQueries() : Unit = {
logQuery = "select * from weblogs ?WHERE limit 50"
sourceQuery = "select source, count(*) as count from weblogs ?WHERE group by source order by count desc limit 50"
codeQuery = "select code, count(*) as count from weblogs ?WHERE group by code"
areaQuery = """
select
split(regexp_replace(url, 'http\:\/\/', ''), '/')[1] as area,
count(*) as count
from weblogs
?WHERE
group by split(regexp_replace(url, 'http\:\/\/', ''), '/')[1]
order by count desc limit 50
"""
}
resetQueries()
//Init the Angular variable "bounds"
z.angularBind("bounds", "")
//Init the callback listening for changes to "bounds"
z.angularWatch("bounds", (oldVal, newVal) => {
val t1 = newVal.asInstanceOf[String].split("\\|")(0)
val t2 = newVal.asInstanceOf[String].split("\\|")(1)
resetQueries()
//If bounds are valid dates, add set the where filter.. otherwise remove it
val where = if (t1.equals("NaN") || t2.equals("NaN")) "" else "where unix_timestamp(datetime) >= " + t1 + " and unix_timestamp(datetime) <= " + t2
logQuery = logQuery.replace("?WHERE", where)
sourceQuery = sourceQuery.replace("?WHERE", where)
areaQuery = areaQuery.replace("?WHERE", where)
codeQuery = codeQuery.replace("?WHERE", where)
})
%spark
var value = "abc"
z.angularBind("someAngularVar", value)
z.angularWatch("someAngularVar", (before, after) => {
value = after.asInstanceOf[String]
})
%spark
z.angularBind("someScopeVar1", 1)
z.angularBind("someScopeVar2", 2)
z.run("20160911-191805_2145183823")
%angular
<div id="someId"></div>
<script type="text/javascript">
var element = $('#someId');
var angularVar = 'someScopeVar';
var scope = angular.element(element.parent('.ng-scope')).scope().compiledScope;
//Annoying callback setup here
window.watcher = scope.$watch(angularVar, function(newVal, oldVal){
element.text(angularVar + ': ' + oldVal + ' to: ' + newVal);
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment