doevisualizations
Version:
Data Visualization Library based on RequireJS and D3.js (v4+)
332 lines (288 loc) • 14.1 kB
JavaScript
define(['jquery',
'underscore',
'jqueryuiwidget',
'handlebars',
'd3'
],
function($, _, ui, Handlebars, d3) {
$.widget("doe.doepie", {
// Options to be used as defaults
options: {},
_template: function() {
var arrHTML = [];
arrHTML.push('<div class="pieChart">');
arrHTML.push('</div>');
return arrHTML.join('');
},
_create: function() {
this._fetchAndRender();
},
_fetchAndRender: function() {
this._compileTemplate();
},
_compileTemplate: function() {
var compiled = Handlebars.compile(this._template());
this.element.html(compiled({}));
this.element.addClass('doepiecontainer');
this._bindEvents();
},
_generateRawTable: function() {
var arrHTML = [];
var data = this.options["Data"];
if (data.length > 0) {
arrHTML.push('<div class ="doehide">');
arrHTML.push('<table>');
arrHTML.push('<thead>');
arrHTML.push('<tr>');
for (p in data[1]) {
arrHTML.push('<th>');
arrHTML.push(p);
arrHTML.push('</th>');
}
arrHTML.push('</tr>');
for (var i = 0; i < data.length; i++) {
arrHTML.push('<tr>');
for (prop in data[i]) {
arrHTML.push('<td>');
arrHTML.push(data[i][prop]);
arrHTML.push('</td>');
}
arrHTML.push('</tr>');
}
arrHTML.push('</thead>');
arrHTML.push('</table>');
arrHTML.push('</div>');
}
this.element.append(arrHTML.join(''));
},
_bindEvents: function() {
var minWidth = 180, //set the minimum width and height
minHeight = 180,
width = this.element.width() < minWidth ? minWidth : this.element.width(),
height = this.element.height() < minHeight ? minHeight : this.element.height(),
radius = (Math.max(width, height) / 4) * 0.9,
donutWidth = radius / 2,
innerParam = 0;
var legendRectSize = radius / 12;
var legendSpacing = legendRectSize / 4;
var color = d3.scaleOrdinal()
.range(this.options.ColorPalette);
//var color = d3.scaleOrdinal(d3.schemeCategory10);
var formatComma = d3.format(",");
essaData = this.options;
// console.log(essaData);
var dataset = essaData["Data"];
// console.log("Pie dataset:", dataset);
var visualType = essaData["Visualization"];
var labelField = essaData["XFields"]
var countField = essaData["YFields"]
var title = essaData["ChartTitle"]
var subTitle = essaData["ChartSubTitle"]
var showLegend = essaData["Legend"]
var tooltipTemplate = essaData["TooltipTemplate"]
var tooltipFields = essaData["TooltipFields"]
var that = this;
var toolTipMasterTemplate = [];
toolTipMasterTemplate.push('<div class="tooltipprogress">');
toolTipMasterTemplate.push('<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>');
toolTipMasterTemplate.push('</div>');
toolTipMasterTemplate.push('<div class="tooltipcontent doehide">');
toolTipMasterTemplate.push(this.options["TooltipTemplate"]);
toolTipMasterTemplate.push('</div>');
var tooltipCompiled = Handlebars.compile(toolTipMasterTemplate.join(''));
var arc = d3.arc()
.outerRadius(radius)
.innerRadius(innerParam);
var arcOver = d3.arc()
.outerRadius(radius * 1.1)
.innerRadius(innerParam);
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d[countField];
});
var svg = d3.select(this.element.find('div.pieChart').get(0))
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 4 + "," + 3 * height / 5 + ")");
svg.append("text")
.attr('class', 'title')
.attr("x", width / 4)
.attr("y", -height / 2)
.style("text-anchor", "middle")
.text(title);
svg.append("text")
.attr('class', 'subTitle')
.attr("x", width / 4)
.attr("y", -height / 2 + 7 * legendSpacing)
.style("text-anchor", "middle")
.text(subTitle);
dataset.forEach(function(d) { //handle *
if (d[countField] === "*") {
d[countField] = 0;
}
});
// var path = svg.selectAll('path')
// .data(pie(dataset))
// .enter()
// .append('path')
// .attr('d', arc)
// .attr('fill', function(d, i) {
// return color(i);
// // return color(d["data"][labelField]);
// });
// Add tooltip
var tooltip = d3.select(this.element.find('div.pieChart').get(0))
.append("div")
.attr("class", "tooltip");
// tooltip.append("div")
// .attr("class", 'label');
// Add legend if true
if (showLegend == true) {
var legend = svg.selectAll(this.element.find('.legend').get(0))
// .data(color.domain())
.data(pie(dataset))
.enter()
.append('g')
.attr('class', 'legend')
.attr('transform', function(d, i) {
var height = legendRectSize + legendSpacing;
var offset = height * (pie(dataset)).length / 2;
var horz = 14 * legendRectSize;
var vert = i * height - offset;
return 'translate(' + horz + ',' + vert + ')';
});
legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', function(d, i) {
return color(i);
})
.on('mouseover', function(d, i) {
d3.select(this)
.style("stroke", "black");
var unitPath = path["_groups"][0][i];
d3.select(unitPath)
.attr("d", arcOver);
})
.on('mouseout', function(d, i) {
d3.select(this)
.style("stroke", "none");
var unitPath = path["_groups"][0][i];
d3.select(unitPath)
.attr("d", arc);
tooltip.style('display', 'none');
});
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) {
//if (d["data"][countField] > 0) {
return d["data"][labelField] + ' (' + d["data"][countField] + '%' + ')';
//} else {
// return d["data"][labelField] + ' (Protected)';
//}
})
.on('mouseover', function(d, i) {
d3.select(this).transition()
.attr('font-size', 14)
.attr('fill', 'black');
var unitPath = path["_groups"][0][i];
d3.select(unitPath)
.attr("d", arcOver);
})
.on('mouseout', function(d, i) {
d3.select(this).transition()
.attr('font-size', 12)
.attr('fill', 'black');
var unitPath = path["_groups"][0][i];
d3.select(unitPath)
.attr("d", arc);
tooltip.style('display', 'none');
});
}
dataset.forEach(function(d) { //format tooltip
for (var i = 0; i < tooltipFields.length; i++) {
if (isNaN(parseFloat(d[tooltipFields[i]]))) {
d[tooltipFields[i]] = d[tooltipFields[i]];
} else {
d[tooltipFields[i]] = parseFloat(d[tooltipFields[i]]);
}
if (typeof(d[tooltipFields[i]]) === "number") {
d[tooltipFields[i]] = formatComma(d[tooltipFields[i]]);
}
}
});
if (dataset.filter(function(d) { return d[countField] > 0; }).length > 0) {
var path = svg.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d, i) {
return color(i);
// return color(d["data"][labelField]);
});
// Add mouse events
path.on('mouseover', function(d) {
if (tooltipTemplate) {
// var template = Handlebars.compile(tooltipTemplate);
// var context = {
// Race: d["data"][labelField],
// RacePctGrad: d["data"][countField]
// };
var compiledTmpl = tooltipCompiled(d["data"]);
tooltip.html(compiledTmpl);
//tooltip.select('.percent').html('Percentage: ' + percent + '%');
tooltip.style('display', 'block');
} else { tooltip.style('display', 'none'); }
that._trigger("tooltiprefreshed", null, {});
});
path.on('mouseout', function(d, i) {
d3.select(this)
.attr("d", arc);
// .attr("stroke", "none")
// var legendRow = legend["_groups"][0][i];
// d3.select(legendRow)
// .style("stroke", "none");
tooltip.style('display', 'none');
});
path.on('mousemove', function(d, i) {
d3.select(this)
// .attr("stroke", "#000")
.attr("d", arcOver);
// .attr("stroke-width", "2px")
// .attr("stroke-opacity", .5);
// var legendRow = legend["_groups"][0][i];
// d3.select(legendRow)
// .style("stroke", "black");
tooltip.style('top', (d3.event.layerY + 10) + 'px')
.style('left', (d3.event.layerX + 30) + 'px');
});
} else {
var dataset = [10];
var pie = d3.pie()
.sort(null)
.value(function(d) { return d; });
var path = svg.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', "#7b6888");
}
this._generateRawTable();
this._trigger("complete", null, {});
},
destroy: function() {
},
_setOption: function(key, value) {
this._super(key, value);
},
_setOptions: function(options) {
this._super(options);
}
});
});