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 )