Skip to content

Instantly share code, notes, and snippets.

@diethardsteiner
Last active August 29, 2015 14:17
Show Gist options
  • Save diethardsteiner/9e8af30e6c67469b3f00 to your computer and use it in GitHub Desktop.
Save diethardsteiner/9e8af30e6c67469b3f00 to your computer and use it in GitHub Desktop.
Demo: Using Pentaho CCC to create a context chart.
<html>
<head>
<!-- Java Script Resources -->
<script src="https://code.jquery.com/jquery-2.1.1.js" type="text/javascript"></script>
<script src="http://www.webdetails.pt/ctools/charts/lib/jquery.tipsy.js" type="text/javascript"></script>
<script src="http://www.webdetails.pt/ctools/charts/lib/protovis.js" type="text/javascript"></script>
<script src="http://www.webdetails.pt/ctools/charts/lib/protovis-msie.js" type="text/javascript"></script>
<script src="http://www.webdetails.pt/ctools/charts/lib/tipsy.js" type="text/javascript"></script>
<script src="http://www.webdetails.pt/ctools/charts/lib/def.js" type="text/javascript"></script>
<script src="http://www.webdetails.pt/ctools/charts/lib/pvc-r2.0.js" type="text/javascript"></script>
<!--
<script src="js/libs/jquery/jquery.js" type="text/javascript"></script>
<script src="js/libs/jquery.tipsy/jquery.tipsy.js" type="text/javascript"></script>
<script src="js/libs/webdetails/protovis.js" type="text/javascript"></script>
<script src="js/libs/webdetails/protovis-msie.js" type="text/javascript"></script>
<script src="js/libs/webdetails/tipsy.js" type="text/javascript"></script>
<script src="js/libs/webdetails/def.js" type="text/javascript"></script>
<script src="js/libs/webdetails/pvc-r2.0.js" type="text/javascript"></script>
-->
<!-- sprintf-js: sourced from dist folder in https://github.com/alexei/sprintf.js -->
<script src="https://github.com/alexei/sprintf.js/raw/master/dist/sprintf.min.js" type="text/javascript"></script>
<!-- <script src="js/libs/sprintf/sprintf.js" type="text/javascript"></script>
-->
<!-- Sample Data -->
<script src="http://www.webdetails.pt/ctools/charts/lib/q01-01.js" type="text/javascript"></script>
<script src="http://www.webdetails.pt/ctools/charts/lib/bp.js" type="text/javascript"></script>
<!--
<script src="js/libs/webdetails/q01-01.js" type="text/javascript"></script>
<script src="js/libs/webdetails/bp.js" type="text/javascript"></script>
-->
<!-- Stylesheet -->
<link rel="stylesheet" href="http://www.webdetails.pt/ctools/charts/lib/tipsy.css" type="text/css" />
<!--
<link rel="stylesheet" href="js/libs/webdetails/tipsy.css" type="text/css" />
-->
<style>
h1 {
font: bold 14px sans-serif;
}
#logSel, #logWin {
font: 12px sans-serif;
}
#description {
font: 12px Verdana, Geneva, sans-serif;
}
</style>
</head>
<body>
<div id='description'>Note that the selection in the context chart is in this case restricted to days. You can also restrict to any other intervals or completely disable the restriction.</div>
<div id="cccMasterChart"></div>
<br />
<div id="cccContextChart"></div>
<br />
<h1>Focus Window</h1>
<div id="logWin">&nbsp;</div>
<br />
<h1>Selection</h1>
<div id="logSel">&nbsp;</div>
<script type="text/javascript">
var relational_01_ds = {
"resultset": [
["London", "2011-01-05", 72],
["London", "2011-01-06", 50],
["London", "2011-01-07", 20],
["London", "2011-01-08", 23],
["London", "2011-01-09", 72],
["London", "2011-01-10", 80],
["London", "2011-01-11", 23],
["London", "2011-01-13", 72],
["London", "2011-01-14", 50],
["London", "2011-01-15", 20],
["London", "2011-01-16", 20],
["Paris", "2011-01-05", 27],
["Paris", "2011-01-07", 32],
["Paris", "2011-01-08", 24],
["Paris", "2011-01-10", 80],
["Paris", "2011-01-11", 90],
["Paris", "2011-01-12", 53],
["Paris", "2011-01-14", 17],
["Paris", "2011-01-15", 20],
["Paris", "2011-01-16", 43],
["Lisbon", "2011-01-06", 30],
["Lisbon", "2011-01-07", 60],
["Lisbon", "2011-01-10", 80],
["Lisbon", "2011-01-15", 15]
],
"metadata": [{
"colIndex": 0,
"colType": "String",
"colName": "City"
}, {
"colIndex": 1,
"colType": "String",
"colName": "Date"
}, {
"colIndex": 2,
"colType": "Numeric",
"colName": "Quantity"
}]
};
var masterChart = new pvc.LineChart({
canvas: "cccMasterChart",
width: 600,
height: 300,
title: "Master Chart - Daily Focus Selection",
timeSeries: true,
line_interpolate: 'monotone',
animate: true,
selectable: true,
hoverable: false,
tooltipEnabled: false,
// axisGrid: true,
// dotsVisible: true,
stacked: true,
pointingMode: 'over', // legacy mode
// nullInterpolationMode: 'linear' // creates dotted line for sections where there is no data available
})
.setData(relational_01_ds, {crosstabMode: false})
.render()
;
var contextChart = new pvc.LineChart({
canvas: "cccContextChart",
width: 600,
height: 120,
// title: "Context Chart",
timeSeries: true,
line_interpolate: 'monotone',
animate: false,
// nullInterpolationMode: 'linear',
selectable: true,
selectionMode: 'focuswindow',
clearSelectionMode: 'none',
tooltipEnabled: false,
// A one month window
//focusWindowBaseBegin: new Date('2011-01-08'),
//focusWindowBaseEnd: new Date('2011-01-09'),
//focusWindowBaseResizable: false,
//focusWindowBaseMovable: false,
// off_focusWindowBaseConstraint: function(oper) {
// oper.value = pvc.time.withoutTime(oper.value);
//
// },
// Round dates to Day.
focusWindowBaseConstraint: function(oper) {
console.log(oper);
// oper has following properties:
// target: 'begin' or 'end', tells you which focus handle was pulled
// value: postition of the focus handle in milliseconds
// min: begin handle value
// max: end handle value
// minView: min possible begin handle value to stay in view
// maxView: max possible end handl value to stay in view
// type: new (on first call and whenever the user clicks outside the focuswindow),
// resize-begin, (pulling left handle)
// resize-end (pulling right handle),
// move (the whole selection)
// Duarte's bug workaround
// Only for when focusWindowBaseBegin/End are not specified.
if(oper.type === 'new' && oper.length0 === oper.length) {
var len = (oper.max - oper.min) / 4;
var middle = ((+oper.max) + (+oper.min))/2;
oper.value = new Date(middle - len / 2);
oper.length = len;
}
// Set time namespace
var tim = pvc.time;
var interval = tim.weekday;
// testing
// var myDate = new Date('2015-01-01T12:00:00');
// var finalDate = interval.closestOrSelf(tim.withoutTime(myDate));
// console.log(finalDate);
// Set min length
// pvc.time.intervals.* returns amount of milliseconds for interval
var minLen = tim.intervals.d;
var sign = oper.target === 'end' ? -1 : +1;
var t0 = +oper.value;
// Round to closest day
var t = interval.closestOrSelf(tim.withoutTime(oper.value));
// Don't let value go below the minimum value in the view
oper.min = interval.previousOrSelf(tim.withoutTime(oper.minView));
// Don't let value go above the maximum value in the view
oper.max = interval.previousOrSelf(tim.withoutTime(oper.maxView));
// Ensure minimum length
if(oper.type === 'new') {
oper.value = t;
oper.length = Math.max(oper.length, minLen);
return;
}
var l = +oper.length;
var o = t0 + sign * l;
l = sign * (o - t);
if(l < minLen) {
t = o - sign * minLen;
}
oper.value = t;
},
focusWindowChanged: function() {
var fwb = this.chart.focusWindow.base;
// bug workaround: start and end are sometimes dates and sometimes integers
var selectionStart = new Date(fwb.begin);
var selectionEnd = new Date(fwb.end);
$('#logSel').html("Beg: " + selectionStart +
"<br />End: " + selectionEnd +
"<br />Len: " + (+fwb.length) + " ms"); // BUG: Sometimes it is a Date, others a number...
// refresh focus chart
try{
// make sure to set within chart.options and just chart
masterChart.options.baseAxisFixedMin = selectionStart;
masterChart.options.baseAxisFixedMax = selectionEnd;
masterChart.render(/*bypassAnimation:*/true, /*recreate:*/true, /*reloadData:*/false);
} catch(error){
alert(error + '');
}
// for CDE use something like this:
// var comp = Dashboards.getComponentByName("render_comp_chart_viewers");
// comp.chart.options.baseAxisFixedMin = fwb.begin;
// comp.chart.options.baseAxisFixedMax = fwb.end;
// comp.chart.render(/*bypassAnimation:*/true, /*recreate:*/true, /*reloadData:*/false);
},
// This event is triggered when you stop dragging/moving the focusWindow,
// and might be preferable in some situations to only refresh the focus chart
// in here, instead of in focusWindowChanged.
selectionChangedAction: function(selected) {
$('#logSel')
.html("Count: " + selected.length);
},
extensionPoints: {
// Focused Window Bg (behind elements) [pv.Bar]
//focusWindowBg_fillStyle: 'rgba(100, 0, 0, 0.2)',
// Focused Window Fg (in front of elements) [pv.Bar]
//focusWindow_fillStyle: 'rgba(100, 0, 0, 0.2)',
// Begin and End out of focus areas [pv.Bar] (should not have Base in the name :-( )
//focusWindowBaseCurtain_fillStyle: 'transparent',
// Base direction - Begin And End Grip [pv.Bar]
//focusWindowBaseGripBegin_fillStyle: 'red',
//focusWindowBaseGripEnd_fillStyle: 'green'
}
})
.setData(relational_01_ds, {crosstabMode: false})
.render()
;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment