DiaColloDB-WWW
view release on metacpan or search on metacpan
share/htdocs/diacollo.js view on Meta::CPAN
case 38: // up: +speed
case 187: // plus
case 107: // keypad plus
case 106: // keypad times
d3SpeedSet(Math.min(dcpSpeed*(e.shiftKey ? 1.125 : 2), speedBrush.y().domain()[0]),100,"elastic");
break;
case 220: // less-than | greater-than : skip-(left|right)
dskip = e.shiftKey ? 1 : -1;
break;
case 37: // left: skip-left
case 33: // page-up
dosnap = !e.shiftKey;
dskip = -1;
break;
case 39: // right: skip-right
case 34: // page-down
dosnap = !e.shiftKey;
dskip = 1;
break;
default: return; // exit this handler for other keys
}
//-- date-slice skip
var dur = dosnap ? 400 : 100;
var easeby = dosnap ? "elastic" : "cubic-in-out";
if (dskip < 0) {
//-- skip-left
dcpBrushSet((dosnap
? (dsnapto < dcur ? dsnapto : Math.max(0,Math.round(dcur+dskip)))
: Math.max(0,dcur+dskip/4)),
dur,easeby,dosnap);
} else if (dskip > 0) {
//-- skip-right
dcpBrushSet((dosnap
? (dsnapto > dcur ? dsnapto : Math.min(dlabels.length-1,Math.round(dcur+dskip)))
: Math.min(dlabels.length-1,dcur+dskip/4)),
dur,easeby,dosnap);
}
e.preventDefault(); // prevent the default action (scroll / move caret)
});
//-- set focus handlers
jsel.focusin(function(e) { d3SetFocus(true); })
.focusout(function(e) { d3SetFocus(false); });
//-- set focus
if (ix==1) jsel.focus();
}
}
//-- d3: keyboard bindings & focus: focus handlers
var d3HasFocus=false;
function d3SetFocus(val) {
if (val==null) val=!d3HasFocus;
d3HasFocus = val;
//debug_log("setFocus("+val+")");
//exportMenuHide(0);
if (val) {
//-- enable keyboard focus
$("#kbicon").attr("title","Keyboard shortcuts enabled (arrow-keys, spacebar)");
$("#kbiconx").hide();
} else {
//-- disable keyboard focus
$("#kbicon").attr("title","Keyboard shortcuts disabled (click to enable)");
$("#kbiconx").show();
}
}
//---------------------------------------------------------------------.
// d3: play/pause transport
var dcpPlaying=false;
var dcpSpeed=1, speedNode, speedBrush, speedScale, speedHandle;
function dcpTransportButtons(parent_selector, opts) {
if (opts==null) { opts = {}; }
if (opts.id==null) { opts.id = "d3buttons"; }
if (opts.width==null) { opts.width = 75; }
if (opts.height==null) { opts.height = 50; }
if (opts.pad==null) { opts.pad = 10; }
var margin = opts.margin==null ? {} : opts.margin;
if (margin.top==null) { margin.top=4; }
if (margin.bottom==null) { margin.bottom=1; }
if (margin.left==null) { margin.left=1; }
if (margin.right==null) { margin.right=1; }
if (opts.bpad==null) { opts.bpad = (opts.height-margin.top-margin.bottom)/8; }
if (opts.bround==null) { opts.bround = (opts.height-margin.top-margin.bottom)/4; }
//debug_log("dcpTransportButtons(parent_selector="+JSON.stringify(parent_selector)+", opts="+JSON.stringify(opts)+")");
//var div = d3.select(selector);
var parent = d3.select(parent_selector);
var svg = parent.append("g")
.attr("id", opts.id)
.attr("width", opts.width)
.attr("height", opts.height);
var btn = svg.append("g")
.attr("class","btn")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.on("mouseenter", function(b) { btn.classed("hovering",true); })
.on("mouseleave", function(b) { btn.classed("hovering",false); })
.on("click", function() { dcpPlay(!dcpPlaying); });
btn.append("title")
.text("Toggle play/pause animation (click or space to toggle)");
var bsize = opts.height-margin.top-margin.bottom;
var border = btn.append("rect")
.attr("class","border")
.attr("x",0)
.attr("y",0)
.attr("width",bsize)
.attr("height",bsize)
.attr("rx",opts.bround)
.attr("ry",opts.bround);
var bplay = btn.append("polygon")
.attr("class","symbol play")
.attr("points",
share/htdocs/diacollo.js view on Meta::CPAN
//-- initialize play/pause visibility
dcpPlay(false);
return svg;
}
function d3SpeedBrushDebug(label) {
//debug_log(label+": val=" + speedBrush.extent()[0] + " ~ " + speedScale(speedBrush.extent()[0]));
return;
}
function d3SpeedBrushMove(value,dur,easeby) {
dcpSpeed = value;
speedBrush.extent([value,value]);
var voff = speedHandle.attr("height")/2;
var fmt = d3.format(".3f");
if (dur==null || easeby==null) {
speedHandle.attr("y",speedBrush.y()(value)-voff);
} else {
speedHandle.transition()
.duration(dur)
.ease(easeby)
.attr("y",speedBrush.y()(value)-voff);
}
$("#curspeed").text(fmt(value)+"x"); //-- +"\u00d7"
if (dcpPlaying) dcpPlay(true,true); //-- re-compute play animation
}
function d3SpeedSet(value,dur,easeby) {
//debug_log("d3SpeedSet("+JSON.stringify({"value":value,"dur":dur,"easeby":easeby})+")");
dcpSpeed = value;
d3SpeedBrushMove(value,dur,easeby);
}
function d3OnSpeedBrushStart() {
//d3SpeedBrushDebug("d3OnSpeedBrushStart()");
if (d3.event.sourceEvent) { // not a programmatic event
speedNode.classed("brushing",true);
}
}
function d3OnSpeedBrush() {
//d3SpeedBrushDebug("d3OnSpeedBrush()");
var value = speedBrush.extent()[0];
if (d3.event.sourceEvent) { // not a programmatic event
value = speedBrush.y().invert(d3.mouse(this)[1]);
}
d3SpeedBrushMove(value);
}
function d3OnSpeedBrushEnd() {
//d3SpeedBrushDebug("d3OnSpeedBrushEnd()");
speedNode.classed("brushing",false);
}
//----------------------------------------------------------------------
// d3: play/pause transport: callbacks
function dcpPlay(playing,force) {
if (playing==null) playing = dcpPlaying;
if (force==null) force=false;
//exportMenuHide(0);
//-- setup buttons
var btn = d3.selectAll(".btn");
btn.selectAll(".play").style("opacity",Number(!playing));
btn.selectAll(".pause,.stop").style("opacity",Number(playing));
if (!force && playing==dcpPlaying) return;
dcpPlaying = playing;
//-- maybe start playing
if (playing) {
//-- play
if (dlabels.length < 2) {
alert("Play animation only available for multi-slice profiles!");
return dcpPlay(false);
}
var pos0 = dbrush.extent()[0];
var pos1 = dlabels.length-1;
if (pos0 == pos1) { pos0 = 0; }
var totaldur = 15000 / dcpSpeed; //-- play-length for total sequence (in ms; google motion chart ~15s; [2s=.133x .. 40s=2.6x])
var interp = d3.interpolate(pos0,pos1);
d3.select("#d3slider")
.transition()
.duration((totaldur/(dlabels.length-1))*(pos1-pos0))
.ease("linear")
.tween("brush", function() {
//-- hack: check dcpPlaying to avoid transition interference (keybd interrupting play)
return function(t) { if (dcpPlaying) dcpBrushMove(interp(t)); }
})
.each("end",function() { dcpPlay(false); });
}
else {
//-- stop
d3.select("#d3slider")
.transition()
.duration(0)
.tween("brush", function() { return function(t) { ; } })
//.call(dbrush.event)
;
}
}
//----------------------------------------------------------------------
// d3: legend (color-scale / "y axis")
function dcpLegend(parent_selector,opts) {
//-- defaults
if (opts==null) opts={};
if (opts.id==null) { opts.id="d3legend"; }
if (opts.width==null) { opts.width = 50; }
if (opts.height==null) { opts.height = 450; }
if (opts.opacity==null) { opts.opacity = 1; }
var margin = opts.margin==null ? {} : opts.margin;
if (margin.left==null) margin.left = 0;
if (margin.right==null) margin.right = 0;
if (margin.top==null) margin.top = 0;
if (margin.bottom==null) margin.bottom = 0;
if (opts.translate==null) opts.translate = {x:0,y:0};
//debug_log("dcpLegend(parent_selector="+JSON.stringify(parent_selector)+", opts="+JSON.stringify(opts)+")");
share/htdocs/diacollo.js view on Meta::CPAN
.style("opacity",opts.opacity);
}
//$("#profileDataD3").show(); //-- debug
return svg;
}
//----------------------------------------------------------------------
// d3: export: export svg guts
// + see http://stackoverflow.com/questions/23218174/how-do-i-save-export-an-svg-file-after-creating-an-svg-with-d3-js-ie-safari-an
function d3exportSvg(event) {
//get svg element.
var mode = $("#profileDataChart").is(":visible") ? 'hichart' : 'd3';
var svg;
if (mode == 'hichart') {
svg = d3.select("#profileDataChart svg");
} else {
svg = d3.select("#d3content");
}
svg = svg.node().cloneNode(true);
//-- insert inline css into svg (d3 only)
if (mode == 'd3') {
var style = document.createElementNS("http://www.w3.org/2000/svg","style");
var css = getcss(true,/diacollo\.css/,/d3/);
$(style).text(css);
svg.insertBefore(style, svg.firstChild);
//-- boldface current slider slice label (hack for inkscape)
$(svg).find("#d3slider .brush .tick text.selected").css("font-weight","bold");
}
//-- get svg source.
var serializer = new XMLSerializer();
var source = serializer.serializeToString(svg);
//-- add namespaces
if(!source.match(/^<svg[^>]*xmlns="http\:\/\/www\.w3\.org\/2000\/svg"/)){
source = source.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
}
if(!source.match(/^<svg[^>]*"http\:\/\/www\.w3\.org\/1999\/xlink"/)){
source = source.replace(/^<svg/, '<svg xmlns:xlink="http://www.w3.org/1999/xlink"');
}
//-- add xml declaration
source = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r\n' + source;
//-- convert svg source to URI data scheme
//var url = "data:image/svg+xml;charset=utf-8,"+encodeURIComponent(source);
var url = "data:image/svg+xml;charset=utf-8,"+encodeURIComponent(source);
//-- set url value to the export button's element's href attribute
$("#exportBtn")
//.prop("target","_tab")
.prop("download","diacollo.svg")
.prop("href",url);
//-- go get it (must use DOM click() method, not jQuery if using exportTarget != event.target)
/*
exportMenuHide();
document.getElementById('exportTarget').click();
*/
//-- direct-click button: just return true
return true;
}
//--------------------------------------------------------------
// d3: export: utils: get css string from selected stylsheets
// + see http://stackoverflow.com/questions/1679507/getting-all-css-used-in-html-file
function getcss(wantIntern, hrefRegex, selectorRegex) {
var css = ""; //variable to hold all the css that we extract
//-- add internal styles
if (wantIntern) {
$("style").each(function(i,s) {
css += s.innerHTML;
});
}
//-- check for selected external stylesheets
if (hrefRegex==null) hrefRegex = /./;
if (selectorRegex==null) selectorRegex = /./;
for (var si = 0; si < document.styleSheets.length; si++) {
var sheet = document.styleSheets[si];
if (String(sheet.href).search(hrefRegex) == -1) continue;
//-- loop over all the styling rules in this external stylesheet
for (var ri = 0; ri < sheet.cssRules.length; ri++) {
if (sheet.cssRules[ri].selectorText.search(selectorRegex) != -1) {
css += sheet.cssRules[ri].cssText; //-- extract the styling rule
}
}
}
return css;
}
//----------------------------------------------------------------------
// d3: common: controls & geometry
// + opts:
// legendOpacity:OPACITY //-- legend color-scale opacity
// width:WIDTH, //-- total width (default=window.innerWidth-16)
// height:HEIGHT, //-- total height (default=500)
// bodyWidth:WIDTH //-- body,slider width
// buttonsWidth:WIDTH //-- buttons width
// legendWidth:WIDTH //-- legend width
// + returns: opts + keys
// bodyWidth:WIDTH //-- body width
// bodyHeight:HEIGHT //-- body height
function d3SetupCommon(opts) {
//-- options
if (opts.legendOpacity==null) opts.legendOpacity=1;
//-- common variables
if (opts==null) opts={};
if (opts.height==null) opts.height = 500;
if (opts.buttonsWidth==null) opts.buttonsWidth = 90; //$("#d3buttons").width(); //-- not defined yet!
if (opts.legendWidth==null) opts.legendWidth = 50; //$("#d3legend").width(); //-- not defined yet!
if (opts.bodyHeight==null) opts.bodyHeight = opts.height - 50 - 5; //-- -5:ypad
( run in 5.436 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )