This diagram tries to provide insight on how contacts are related to each other.
Disclaimer: This is not a finished report and should not be considered as such. This is just a proof of concept to show what the reporting engine of CRM On Demand is capable of.
HTML5 Canvas and Javascript are not a required skill for normal CRM On Demand report generation at all! But using these techniques enable a wide range of unusual data visualizations.
Here is all you need to make a contact relationship report in CRM On Demand. But before you try this out, you might want to learn more about how narrative views actually work by checking out this video recording
Result Example
Concepts
- Lines are drawn between related contacts that match
- Lines could get colors to indicate the type or the importance of the relationship
Criteria Fields
From the ‘Reporting’ subject areas, I used: ‘Contact Relationships’
Field Name | Calculated Field | Formula |
---|---|---|
From | Contact.”Contact Name” | |
To | “Related Contact”.”Contact Name” |
Criteria Filters
- Any filter to reduce the number of contacts within a certain scope
- a set of accounts
- types of contacts
- …
Data Formatting
Format the date till the table view looks something like the example below.
Hide the table once the narrative view is ready.
Narrative View Definition
Prefix
<canvas id="myCanvas" width="600" height="600"></canvas> <script> var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); var references = []; var relations = []; var params = []; params['canvasWidth'] = canvas.width; params['canvasHeight'] = canvas.height; params['middleX'] = Math.round(params['canvasWidth'] / 2); params['middleY'] = Math.round(params['canvasHeight'] / 2); params['radius'] = 150; function drawNames() { // context.beginPath(); // context.arc(params['middleX'], params['middleY'], params['radius'], 0, 2 * Math.PI, false); // context.lineWidth = 2; // context.strokeStyle = 'black'; // context.stroke(); for (reference in references) { var details = []; details[1] = references[reference]; angle = Math.PI * 2 / references.length * reference; details[2] = params['middleX'] + Math.round(Math.cos(angle) * params['radius']); details[3] = params['middleY'] - Math.round(Math.sin(angle) * params['radius']) ; references[reference] = details; if ((angle <= Math.PI /2) || (angle > Math.PI * 1.5)) { textAngle = -1 * angle; textAlign = 'left'; } else { textAngle = (-1 * angle) + Math.PI; textAlign = 'right'; } context.save(); context.translate(references[reference][2], references[reference][3]); context.font = '10pt Calibri'; context.rotate(textAngle); context.textAlign = textAlign; context.textBaseline = 'middle'; context.fillText(references[reference][1], 0, 0); context.restore(); } } function findRelations() { for (relation in relations) { relations[relation][1] = references.indexOf(relations[relation][1]); relations[relation][2] = references.indexOf(relations[relation][2]); } } function drawRelations() { for (relation in relations) { context.beginPath(); context.moveTo(references[relations[relation][1]][2], references[relations[relation][1]][3]); context.quadraticCurveTo(params['middleX'], params['middleY'], references[relations[relation][2]][2], references[relations[relation][2]][3]); context.lineWidth = 1; context.strokeStyle = 'black'; context.stroke(); } }
Narrative
var reference = []; reference = '@1'; if (references.indexOf('@1') == -1) { references[references.length] = reference; } var relation = []; relation[1] = '@1'; relation[2] = '@2'; relations[relations.length] = relation;
Row separator: empty
Postfix
findRelations(); drawNames(); drawRelations(); </script>
Rows to Display: empty