Continuing with THIS series of posts, today we are looking at using the Flot JScript library for visual rendering of data. Flot is a great little library for charting. It is available from HERE.
The Flot library has a few graphing variations available, and we can easily change the CSS as needed to make it look even more appealing. The idea is that presenting information visually will make our users so much faster, and more inclined to quickly glance to see what’s going on, rather than deep dive.
In this short article we focus on the Flot pie charts. What we will achieve is this:
Notice how, for the purpose of this demo, I have left the available rendering option buttons on the form. You can change the rendering type as needed, until you figure out which is the best to use. I like to do that with customers because giving them choice empowers them and engages them in the discussion.
On the final production-ready chart, of course, remove the unwanted rendering options and only keep the one your customer wants.
So, let’s look and see how we can do this.
First step, start by adding your web resource. You need jquery, jquery.flot and jquery.flot.pie
Next add the CSS web resource
And last, add your HTML web resource.
Add the following code to your web resource. The code is rather long, but you will observer that each section starting with $(“#example-1”).click is related to each button for a different rendering type.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>
<title>Flot Examples: Pie Charts</title>
<link href=”../examples.css” rel=”stylesheet” type=”text/css”>
<!–[if lte IE 8]><script language=”javascript” type=”text/javascript” src=”../../excanvas.min.js”></script><![endif]–>
<script language=”javascript” type=”text/javascript” src=”http://<srvname>/extremecrm/WebResources/new_jquery_1.11.0.min”></script>
<script language=”javascript” type=”text/javascript” src=”http://<srvname>/extremecrm/WebResources/new_jquery.flot”></script>
<script language=”javascript” type=”text/javascript” src=”http://<srvname>/extremecrm/WebResources/new_jquery.flot.pie”></script>
<script type=”text/javascript”>
$(function () {
var data = new Array();
data = GetCRMData();
var placeholder = $(“#placeholder”);
$(“#example-1”).click(function () {
placeholder.unbind();
$(“#title”).text(“Default pie chart”);
$(“#description”).text(“The default pie chart with no options set.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true
}
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true”,
” }”,
” }”,
“});”
]);
});
$(“#example-2”).click(function () {
placeholder.unbind();
$(“#title”).text(“Default without legend”);
$(“#description”).text(“The default pie chart when the legend is disabled. Since the labels would normally be outside the container, the chart is resized to fit.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”
]);
});
$(“#example-3”).click(function () {
placeholder.unbind();
$(“#title”).text(“Custom Label Formatter”);
$(“#description”).text(“Added a semi-transparent background to the labels and a custom labelFormatter function.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 1,
formatter: labelFormatter,
background: {
opacity: 0.8
}
}
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true,”,
” radius: 1,”,
” label: {“,
” show: true,”,
” radius: 1,”,
” formatter: labelFormatter,”,
” background: {“,
” opacity: 0.8″,
” }”,
” }”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”
]);
});
$(“#example-4”).click(function () {
placeholder.unbind();
$(“#title”).text(“Label Radius”);
$(“#description”).text(“Slightly more transparent label backgrounds and adjusted the radius values to place them within the pie.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 3 / 4,
formatter: labelFormatter,
background: {
opacity: 0.5
}
}
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true,”,
” radius: 1,”,
” label: {“,
” show: true,”,
” radius: 3/4,”,
” formatter: labelFormatter,”,
” background: {“,
” opacity: 0.5″,
” }”,
” }”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”
]);
});
$(“#example-5”).click(function () {
placeholder.unbind();
$(“#title”).text(“Label Styles #1”);
$(“#description”).text(“Semi-transparent, black-colored label background.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 3 / 4,
formatter: labelFormatter,
background: {
opacity: 0.5,
color: “#000”
}
}
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: { “,
” show: true,”,
” radius: 1,”,
” label: {“,
” show: true,”,
” radius: 3/4,”,
” formatter: labelFormatter,”,
” background: { “,
” opacity: 0.5,”,
” color: ‘#000′”,
” }”,
” }”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”
]);
});
$(“#example-6”).click(function () {
placeholder.unbind();
$(“#title”).text(“Label Styles #2”);
$(“#description”).text(“Semi-transparent, black-colored label background placed at pie edge.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true,
radius: 3 / 4,
label: {
show: true,
radius: 3 / 4,
formatter: labelFormatter,
background: {
opacity: 0.5,
color: “#000”
}
}
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true,”,
” radius: 3/4,”,
” label: {“,
” show: true,”,
” radius: 3/4,”,
” formatter: labelFormatter,”,
” background: {“,
” opacity: 0.5,”,
” color: ‘#000′”,
” }”,
” }”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”
]);
});
$(“#example-7”).click(function () {
placeholder.unbind();
$(“#title”).text(“Hidden Labels”);
$(“#description”).text(“Labels can be hidden if the slice is less than a given percentage of the pie (10% in this case).”);
$.plot(placeholder, data, {
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 2 / 3,
formatter: labelFormatter,
threshold: 0.1
}
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true,”,
” radius: 1,”,
” label: {“,
” show: true,”,
” radius: 2/3,”,
” formatter: labelFormatter,”,
” threshold: 0.1″,
” }”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”
]);
});
$(“#example-8”).click(function () {
placeholder.unbind();
$(“#title”).text(“Combined Slice”);
$(“#description”).text(“Multiple slices less than a given percentage (5% in this case) of the pie can be combined into a single, larger slice.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true,
combine: {
color: “#999”,
threshold: 0.05
}
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true,”,
” combine: {“,
” color: ‘#999’,”,
” threshold: 0.1″,
” }”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”
]);
});
$(“#example-9”).click(function () {
placeholder.unbind();
$(“#title”).text(“Rectangular Pie”);
$(“#description”).text(“The radius can also be set to a specific size (even larger than the container itself).”);
$.plot(placeholder, data, {
series: {
pie: {
show: true,
radius: 500,
label: {
show: true,
formatter: labelFormatter,
threshold: 0.1
}
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true,”,
” radius: 500,”,
” label: {“,
” show: true,”,
” formatter: labelFormatter,”,
” threshold: 0.1″,
” }”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”
]);
});
$(“#example-10”).click(function () {
placeholder.unbind();
$(“#title”).text(“Tilted Pie”);
$(“#description”).text(“The pie can be tilted at an angle.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true,
radius: 1,
tilt: 0.5,
label: {
show: true,
radius: 1,
formatter: labelFormatter,
background: {
opacity: 0.8
}
},
combine: {
color: “#999”,
threshold: 0.1
}
}
},
legend: {
show: false
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true,”,
” radius: 1,”,
” tilt: 0.5,”,
” label: {“,
” show: true,”,
” radius: 1,”,
” formatter: labelFormatter,”,
” background: {“,
” opacity: 0.8″,
” }”,
” },”,
” combine: {“,
” color: ‘#999’,”,
” threshold: 0.1″,
” }”,
” }”,
” },”,
” legend: {“,
” show: false”,
” }”,
“});”,
]);
});
$(“#example-11”).click(function () {
placeholder.unbind();
$(“#title”).text(“Donut Hole”);
$(“#description”).text(“A donut hole can be added.”);
$.plot(placeholder, data, {
series: {
pie: {
innerRadius: 0.5,
show: true
}
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” innerRadius: 0.5,”,
” show: true”,
” }”,
” }”,
“});”
]);
});
$(“#example-12”).click(function () {
placeholder.unbind();
$(“#title”).text(“Interactivity”);
$(“#description”).text(“The pie can be made interactive with hover and click events.”);
$.plot(placeholder, data, {
series: {
pie: {
show: true
}
},
grid: {
hoverable: true,
clickable: true
}
});
setCode([
“$.plot(‘#placeholder’, data, {“,
” series: {“,
” pie: {“,
” show: true”,
” }”,
” },”,
” grid: {“,
” hoverable: true,”,
” clickable: true”,
” }”,
“});”
]);
placeholder.bind(“plothover”, function (event, pos, obj) {
if (!obj) {
return;
}
var percent = parseFloat(obj.series.percent).toFixed(2);
$(“#hover”).html(“<span style=’font-weight:bold; color:” + obj.series.color + “‘>” + obj.series.label + ” (” + percent + “%)</span>”);
});
placeholder.bind(“plotclick”, function (event, pos, obj) {
if (!obj) {
return;
}
percent = parseFloat(obj.series.percent).toFixed(2);
alert(“” + obj.series.label + “: ” + percent + “%”);
});
});
// Show the initial default chart
$(“#example-1”).click();
// Add the Flot version string to the footer
$(“#footer”).prepend(“Flot ” + $.plot.version + ” – “);
});
// A custom label formatter used by several of the plots
function labelFormatter(label, series) {
return “<div style=’font-size:8pt; text-align:center; padding:2px; color:white;’>” + label + “<br/>” + Math.round(series.percent) + “%</div>”;
}
//
function setCode(lines) {
$(“#code”).text(lines.join(“\n”));
}
</script>
</head>
<body>
<div id=”content”>
<h3 id=”title”></h3>
<div class=”demo-container”>
<div id=”placeholder” class=”demo-placeholder”></div>
<div id=”menu”>
<button id=”example-1″>Default Options</button>
<button id=”example-2″>Without Legend</button>
<button id=”example-3″>Label Formatter</button>
<button id=”example-4″>Label Radius</button>
<button id=”example-5″>Label Styles #1</button>
<button id=”example-6″>Label Styles #2</button>
<button id=”example-7″>Hidden Labels</button>
<button id=”example-8″>Combined Slice</button>
<button id=”example-9″>Rectangular Pie</button>
<button id=”example-10″>Tilted Pie</button>
<button id=”example-11″>Donut Hole</button>
<button id=”example-12″>Interactivity</button>
</div>
</div>
<p id=”description”></p>
</div>
</body>
</html>
You will also need the same GetCRMData function we have used in the previous blog posts about visualization. You can either use this in the header, or put it in a JScript library if you are re-using it. This time we formatted the return to bring back a total of both Active and Closed cases. I would strongly suggest when querying this data, to limit your query results for a specific period to report on (for example, current month, or last 30 days, etc.)
<script type=”text/javascript”>
function GetCRMData() {
//debugger;
var _serverURL = window.parent.Xrm.Page.context.getServerUrl() +
“/xrmservices/2011/organizationdata.svc”;
var AddressReq = new XMLHttpRequest();
AddressReq.open(“GET”, _serverURL + “/IncidentSet?$filter=CustomerId/Id eq (guid'” + window.parent.Xrm.Page.data.entity.getId() + “‘)”, false);
AddressReq.setRequestHeader(“Accept”, “application/json”);
AddressReq.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
AddressReq.send();
if (AddressReq.readyState == 4 /* complete */) {
if (AddressReq.status == 200 || AddressReq.status == 400) {
var retrieved = this.JSON.parse(AddressReq.responseText).d;
var Results = retrieved.results;
var retData = new Array();
var caseActive = 0;
var caseClosed = 0;
for (var i = 0; i < Results.length; i++) {
// StateCode values:
// 0 – Active
// 1 – Resolved
// 2 – Cancelled
if(Results[i].StateCode.Value == 0) {
caseActive++;
}
else if (Results[i].StateCode.Value == 1 ||
Results[i].StateCode.Value == 2) {
caseClosed++;
}
}
retData = [
{ label: “Active Cases”, data: caseActive },
{ label: “Closed Cases”, data: caseClosed }
];
return retData;
}
}
}
</script>
Now, with all this together, on the Account form create a new iFrame, and point it to your newly create HTML Web Resource. Save and publish all.
Now when navigating to an account that has related Cases, you will see the pie chart rendering in whichever format you have chosen.
Et voila,
Enjoy!
Leave a Reply