Contact Relationships in CRM On Demand

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

contact relationships

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.

contact relationships tableHide 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

Leave a Reply

Your email address will not be published. Required fields are marked *