Skip to content
Snippets Groups Projects
Commit 189d1165 authored by Georgi's avatar Georgi
Browse files

Added a script for drawing a big Donut view for reviewing the amount of...

Added a script for drawing a big Donut view for reviewing the amount of evidences per agent. Some functionality still is not working (Work in progress)
parent 65eb82c1
No related branches found
No related tags found
No related merge requests found
Pipeline #7904 passed
function DetailDonut(data, element) {
// chart dimensions
var width = 800;
var height = 800;
// a circle chart needs a radius
var radius = Math.min(width, height) / 2;
var donutWidth = 100; // size of donut hole. not needed if doing pie chart
// legend dimensions
var legendRectSize = 25; // defines the size of the colored squares in legend
var legendSpacing = 6; // defines spacing between squares
// define color scale
var color = d3.scaleOrdinal(d3.schemePuBu[9]);
// calculate new total
var total = d3.sum(data, d => d.value);
// define new total section
var newTotal = d3.select('.new-total-holder')
.append('span')
.attr('class', 'newTotal').text(total);
var svg = d3.select(element) // select element provided to the method
.append('svg') // append an svg element to the element we've selected
.attr('width', width) // set the width of the svg element we just added
.attr('height', height) // set the height of the svg element we just added
.append('g') // append 'g' element to the svg element
.attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')'); // our reference is now to the 'g' element. centerting the 'g' element to the svg element
var arc = d3.arc()
.innerRadius(radius - donutWidth) // radius - donutWidth = size of donut hole. use 0 for pie chart
.outerRadius(radius); // size of overall chart
var pie = d3.pie() // start and end angles of the segments
.value(function(d) { return d.value; }) // how to extract the numerical data from each entry in our dataset
.sort(null); // by default, data sorts in oescending value. this will mess with our animation so we set it to null
//**********************
// TOOLTIP
//**********************
//var tooltip = d3.select(element) // select element in the DOM provided to the method
// .append('div') // append a div element to the element we've selected
// .attr('class', 'tooltip'); // add class 'tooltip' on the divs we just selected
var tooltip = d3.select(element)
.append('div')
.attr('class', 'd3-tooltip')
.style('position', 'absolute')
.style('z-index', '10')
.style('visibility', 'hidden')
.style('padding', '10px')
.style('background', 'rgba(0,0,0,0.6)')
.style('border-radius', '4px')
.style('color', '#fff');
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'label'); // add class 'label' on the selection
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'value'); // add class 'value' on the selection
tooltip.append('div') // add divs to the tooltip defined above
.attr('class', 'percent'); // add class 'percent' on the selection
data.forEach(function(d) {
d.value = +d.value; // calculate value as we iterate through the data
d.enabled = true; // add enabled property to track which entries are checked
});
// creating the chart
var path = svg.selectAll('path') // select all path elements inside the svg. specifically the 'g' element. they don't exist yet but they will be created below
.data(pie(data)) //associate dataset wit he path elements we're about to create. must pass through the pie function. it magically knows how to extract values and bakes it into the pie
.enter() //creates placeholder nodes for each of the values
.append('path') // replace placeholders with path elements
.attr('d', arc) // define d attribute with arc function above
.attr('fill', function(d) { return color(d.data.label); }) // use color scale to define fill of each label in dataset
.each(function(d) { this._current - d; }); // creates a smooth animation for each track
// mouse event handlers are attached to path so they need to come after its definition
path.on('mouseover', function(event, d, i) { // when mouse enters div
var total = d3.sum(data.map(function(d) { // calculate the total number of tickets in the dataset
return (d.enabled) ? d.value : 0; // checking to see if the entry is enabled. if it isn't, we return 0 and cause other percentages to increase
}));
var percent = Math.round(1000 * d.data.value / total) / 10; // calculate percent
tooltip.select('.label').html('Agent: ' + d.data.label); // set current label
tooltip.select('.value').html('Value: ' + d.data.value); // set current value
tooltip.select('.percent').html('Percentage: ' + percent + '%'); // set percent calculated above
tooltip.style('visibility', 'visible'); // set visibility
});
path.on('mouseout', function(event, d) { // when mouse leaves div
tooltip.style('visibility', 'hidden'); // hide tooltip for that element
});
path.on('mousemove', function(event, d) { // when mouse moves
tooltip.style('top', (event.layerY + 10) + 'px') // always 10px below the cursor
.style('left', (event.layerX + 10) + 'px'); // always 10px to the right of the mouse
});
// define legend
var legend = svg.selectAll('.legend') // selecting elements with class 'legend'
.data(color.domain()) // refers to an array of labels from our dataset
.enter() // creates placeholder
.append('g') // replace placeholders with g elements
.attr('class', 'legend') // each g is given a legend class
.attr('transform', function(d, i) {
var height = legendRectSize + legendSpacing; // height of element is the height of the colored square plus the spacing
var offset = height * color.domain().length / 2; // vertical offset of the entire legend = height of a single element & half the total number of elements
var horz = -2 * legendRectSize; // the legend is shifted to the left to make room for the text
var vert = i * height - offset; // the top of the element is hifted up or down from the center using the offset defiend earlier and the index of the current element 'i'
return 'translate(' + horz + ',' + vert + ')'; //return translation
});
// adding colored squares to legend
legend.append('rect') // append rectangle squares to legend
.attr('width', legendRectSize) // width of rect size is defined above
.attr('height', legendRectSize) // height of rect size is defined above
.style('fill', color) // each fill is passed a color
.style('stroke', color) // each stroke is passed a color
.on('click', function(label) {
var rect = d3.select(this); // this refers to the colored squared just clicked
var enabled = true; // set enabled true to default
var totalEnabled = d3.sum(data.map(function(d) { // can't disable all options
return (d.enabled) ? 1 : 0; // return 1 for each enabled entry. and summing it up
}));
if (rect.attr('class') === 'disabled') { // if class is disabled
rect.attr('class', ''); // remove class disabled
} else { // else
if (totalEnabled < 2) return; // if less than two labels are flagged, exit
rect.attr('class', 'disabled'); // otherwise flag the square disabled
enabled = false; // set enabled to false
}
pie.value(function(d) {
if (d.label === label) d.enabled = enabled; // if entry label matches legend label
return (d.enabled) ? d.value : 0; // update enabled property and return value or 0 based on the entry's status
});
path = path.data(pie(data)); // update pie with new data
path.transition() // transition of redrawn pie
.duration(750) //
.attrTween('d', function(d) { // 'd' specifies the d attribute that we'll be animating
var interpolate = d3.interpolate(this._current, d); // this = current path element
this._current = interpolate(0); // interpolate between current value and the new value of 'd'
return function(t) {
return arc(interpolate(t));
};
});
// calculate new total
var newTotalCalc = d3.sum(data.filter(function(d) { return d.enabled;}), d => d.value)
console.log(newTotalCalc);
// append newTotalCalc to newTotal which is defined above
newTotal.text(newTotalCalc);
});
// adding text to legend
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) { return d; }); // return label
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment