Example: Complete D3 Pie with View-Specific and DataTable Events
This is the completed D3 Pie pluggable view that has both a view-specific click event and fully supports (triggers and listens for) DataTable rowselect events. This view depends on the D3js third-party library which has been imported into Presto as a pluggable library.
Important: | Presto includes certain " third party software" which JackBe licenses from third parties. Pursuant to the JackBe EULA for Presto, all Presto users are bound by the license terms and conditions of any third party software licenses. You may review these Third Party Licenses at http://documentation.softwareag.com/legal/. Software AG does not and cannot authorize any use of third party software that is not permitted by these third party software licenses. You may, however, be able to obtain licenses directly from third parties. In addition, any other software that you add and/or use in connection with Presto is subject to its own licensing requirements and may void the terms of the EULA for Presto. |
See
Example: Pluggable View Import with Library Dependencies for an example of the library properties and import process for this example.
(function($){
var configForm = [
'<div
>',
'<div>Enter Label:</div><div><select name="label"
></select></div>',
'<div>Enter Series:</div><div><select name="series"
></select></div>',
'</div>'
].join("");
Presto.namespace('Sample.d3');
Sample.d3.Pie = function(selector, dataTable, config){
var self = this,
getData = function(rows, props){
var i, data = [];
for(i=0; i < rows.length; i++){
data.push(rows[i][props.series]);
}
return data;
},
getLabels = function(rows, props){
var i, labels = [];
for(i=0; i < rows.length; i++){
labels.push(rows[i][props.label]);
}
return labels;
};
self.config = config || {};
self.selector = selector;
self.draw = function(dataTable, config){
config = config || self.config;
var el = $(selector),
onClick = function(event, index){
//update datatable for rowselect
dataTable.rowClick(index);
//trigger view-specific event
var eventData = {};
eventData[props.label] = d3.select(this).attr("name");
eventData[props.series] = event.value;
Presto.view.trigger(el, 'click', eventData);
return false;
},
//determines selected or deselected color for slice and applies
//based on selected state from datatable rowselect event
onRowSelect = function(index, selected, row) {
var c = color(index);
if(selected){
c = d3.rgb(c).brighter();
}
d3.select(arcs[0][index]).select('path').attr('fill', c);
},
props = config.properties || {},
width = config.width || el.width() || 400,
height = (config.height || el.height() || 340),
rows = Presto.view.getRows(dataTable, config.columns, { flatten: true }),
data = getData(rows, props),
labels = getLabels(rows, props),
outerRadius = Math.min(width, height) / 3,
innerRadius = outerRadius * .0,
color = d3.scale.category20(),
donut = d3.layout.pie(),
arc = d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius);
//add datatable listener for rowselect event
dataTable.addListener('rowselect',onRowSelect,self);
var vis = d3.select(el[0]).html('')
.append("svg")
.data([data])
.attr("width", width)
.attr("height", height);
var arcs = vis.selectAll("g.arc")
.data(donut)
.enter().append("g")
.attr("class", "arc")
.attr("transform", "translate(" + (width/2) + "," + (height/2) + ")");
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc)
.attr("name", function(d, i){
return labels[i];
})
.on('click', onClick);
arcs.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.attr("display", function(d) {
return Math.abs(d.startAngle - d.endAngle) > (Math.PI / 10) ? null : "none";
})
.text(function(d, i) {
return labels[i] + ' ' + d.value.toFixed(2); |
});
arcs.append("title")
.text(function(d, i) { return labels[i] + " : " + d.value.toFixed(2); });
};
self.showConfig = function(dataTable, selector, config){
config = config || self.config;
var el = $(selector),
props = config.properties || {},
initColumnSelect = function(name, value, type){
var $sel = el.find('select[name='+name+']');
$sel.empty();
config.columns.each(function(col){
var name = col.name,
datatype = col['data-type'],
selected = name == value ? 'selected="selected"' : '';
if(!type || type == datatype){
$sel.append('<option value="' + name + '" ' + selected + ' >' + name + '</option>');
}
});
};
self.configForm = el;
self.config = config;
el.html(configForm);
if(el){
initColumnSelect('label', props.label);
initColumnSelect('series', props.series);
}
};
self.getConfig = function(){
var el = self.configForm, config = self.config || {};
if(el){
config.properties = {
label: el.find('select[name=label]').val(),
series: el.find('select[name=series]').val()
}
}
return config;
};
self.validate = function(){
var config = self.getConfig(), props;
if(config){
props = config.properties;
if(props.label && props.series){
return true;
}
}
return false;
};
};
Presto.view.register({
clazz: Sample.d3.Pie,
lib: "d3-pie",
events: [ "click" ]
});
}(jQuery));