Campaign Dashboard Tab: Is there a way click bar graph for list of Campaign Members by Status?

  • 1
  • Question
  • Updated 3 years ago
  • Answered
I am trying to build a Campaign Dashboard Tab that will display charts of Campaign Members Status totals across Campaigns with Status: In Progress and Type: Client Engagement.  I pretty much have it working . . .

Yet there is one added wish: I'd like to be able to click on one of the bars to drill down and see a listing of Campaign Members with that particular status code. I don't know if that is something we can do with Skuid but I thought I'd check because it would be incredibly helpful.

We may have 20 or more active campaigns at any given time. So it is hard to "see" where work is required in response to a Campaign Member Status code. Consequently, as an example, I'd like to be able to pull up a list across multiple campaigns campaigns of the 97 campaign members with the Status code Data Entry Pending depicted below by clicking on that bar . .  .



Second best, I have tried adding Drawer pop-ups on the Campaign table to enable checking for the Data Entry Pending members campaign-by-campaign. It is not an ideal work around, as we'd have to open and close 20 drawers row by row to determine which campaigns have the members with a particular status code. Moreover, with everything else going on on this page, I'm throwing "Apex heap size too large" errors trying the add the drawer pop up.  I don't believe I can throttle back the records loaded in the Campaign Member model without screwing up the counts in the dashboard  (While experimenting I noticed a relationship between the two . . . )


Below is the code for my page thus far. 

I welcome your thoughts  . . .

Many thanks!
Krista


Campaign Tab Dashboard - Campaign Member Status Counts

<skuidpage showsidebar="false" showheader="true" tabtooverride="Campaign" unsavedchangeswarning="" theme="" personalizationmode="server">   <models>
      
      
   <model id="Campaign" limit="" query="true" createrowifnonefound="false" adapter="" type="" sobject="Campaign" orderby="Name" doclone="">
<fields>
   <field id="Id"/>
   <field id="Name"/>
   <field id="CampaignMembers" type="childRelationship" limit="10">
      <fields>
         <field id="Id"/>
         <field id="CampaignMember_Power_of_One__c"/>
         <field id="Status"/>
         <field id="ContactId"/>
         <field id="Company_Name_lookup__c"/>
         <field id="Contact.Title"/>
         <field id="Contact.AccountId"/>
         <field id="CampaignId"/>
         <field id="Campaign.Status"/>
      </fields>
   </field>
   <field id="Status"/>
   <field id="Type"/>
   <field id="StartDate"/>
   <field id="EndDate"/>
   <field id="Search_ID__c"/>
   <field id="NumberOfContacts"/>
</fields>
<conditions>
   <condition type="fieldvalue" value="In Progress" enclosevalueinquotes="true" field="Status" state="filterableon" inactive="false" name="Status" operator="="/>
   <condition type="multiple" value="" field="Type" state="filterableon" inactive="false" name="Type" operator="in" enclosevalueinquotes="true">
      <values>
         <value>Client Engagement</value>
         <value>Internal Research</value>
         <value>Internal New Business</value>
      </values>
   </condition>
   <condition type="multiple" field="Status" operator="in" inactive="true" enclosevalueinquotes="true" name="__autofilter__Status" state="filterableoff" value=""/>
   <condition type="multiple" field="Type" operator="in" inactive="true" enclosevalueinquotes="true" name="__autofilter__Type" state="filterableoff" value=""/>
</conditions>
<actions/>
</model>
<model id="CampaignMembers" limit="1200" query="true" createrowifnonefound="false" adapter="" type="" sobject="CampaignMember" doclone="" orderby="">
   <fields>
      <field id="Id"/>
      <field id="CampaignId"/>
      <field id="Campaign.Name"/>
      <field id="Status"/>
      <field id="Campaign.Status"/>
      <field id="Campaign.Type"/>
      <field id="CampaignMember_Power_of_One__c"/>
      <field id="AccountID__c"/>
      <field id="Contact.Title"/>
      <field id="Contact.AccountId"/>
      <field id="Contact.Account.Name"/>
      <field id="Priority__c"/>
      <field id="ContactId"/>
      <field id="Contact.Name"/>
      <field id="Client_Interest__c"/>
      <field id="Recruitability_Comments__c"/>
   </fields>
   <conditions>
      <condition type="join" value="" operator="in" field="CampaignId" enclosevalueinquotes="true" joinobject="Campaign" joinfield="Id">
         <conditions>
            <condition type="fieldvalue" value="In Progress" enclosevalueinquotes="true" field="Status"/>
            <condition type="multiple" value="" field="Type" operator="in" enclosevalueinquotes="true" state="">
               <values>
                  <value>Client Engagement</value>
                  <value>Internal Research</value>
               </values>
            </condition>
         </conditions>
      </condition>
      <condition type="multiple" value="" field="Status" operator="not in" enclosevalueinquotes="true">
         <values>
            <value>09 Closed Out - Responded</value>
            <value>09 Closed Out - No Response</value>
            <value>Do Not Contact</value>
         </values>
      </condition>
   </conditions>
   <actions/>
</model>
</models>
   <components>
<pagetitle model="CampaignMembers" uniqueid="sk-1ZfvRj-190">
   <actions>
      <action type="multi" label="Revert to Salesforce UI" icon="/701?nooverride=1">
         <renderconditions logictype="and"/>
         <enableconditions/>
      </action>
      <action type="savecancel"/>
   </actions>
   <renderconditions logictype="and"/>
   <maintitle>Campaign Dashboard</maintitle>
</pagetitle>
      
      
      <panelset type="custom" scroll="" uniqueid="sk-14vCXm-93">
         <panels>
            <panel width="50%">
               <components>
                  <skuidvis__chart model="CampaignMembers" maintitle="by Status" type="column" uniqueid="sk-14vCXm-94" subtitle="Campaign Members">
                     <dataaxes>
                        <axis id="axis1" title="Total Members"/>
                     </dataaxes>
                     <categoryaxes>
                        
                     <axis id="axis2" categorytype="field" title="Status" field="Status"/>
</categoryaxes>
                     <serieslist>
                        <series valuefield="Status" splittype="field" modelId="CampaignMembers" aggfunction="count" splitfield="Status" categoryAxisId="axis2" type="" categoryField="Status"/>
                     </serieslist>
                     <colors/>
                     <legend layout="horizontal" halign="center" valign="bottom"/>
                     <allowedtypes>
                        <type>line</type>
                        <type>spline</type>
                        <type>area</type>
                        <type>areaspline</type>
                        <type>column</type>
                        <type>bar</type>
                     </allowedtypes>
                  <renderconditions logictype="and"/>
</skuidvis__chart>
               </components>
            </panel>
            
         <panel width="50%">
<components>
   <skuidvis__chart model="Campaign" maintitle="By Campaign" type="donut" uniqueid="sk-1ZeJy--144" subtitle="Campaign Members">
      <dataaxes>
         <axis id="axis1"/>
      </dataaxes>
      <categoryaxes>
         <axis id="categories" categorytype="field"/>
      </categoryaxes>
      <serieslist>
         <series valuefield="NumberOfContacts" splittype="field" modelId="Campaign" aggfunction="sum" splitfield="Name"/>
      </serieslist>
      <colors/>
      <legend layout="horizontal" halign="center" valign="bottom" showlabels="false"/>
      <renderconditions logictype="and"/>
   </skuidvis__chart>
</components>
</panel>
</panels>
      <renderconditions logictype="and"/>
</panelset>
      <skootable showconditions="true" showsavecancel="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="false" model="Campaign" mode="read" instantfilters="false" allowscrollbars="true" tablescrollheight="300px" floatheader="true" freezeleftcolumns="false" uniqueid="sk-14vCXn-96" buttonposition="left">
         <fields>
<field id="Status" valuehalign="" type="" allowordering="true"/>
<field id="Type" valuehalign="" type="" allowordering="true"/>
            <field id="Name" valuehalign="" type="" allowordering="true"/>
<field id="Id" valuehalign="" type="" allowordering="true"/>
<field id="StartDate" valuehalign="" type="" allowordering="true"/>
<field id="EndDate" valuehalign="" type="" allowordering="true"/>
<field id="Search_ID__c" decimalplaces="" valuehalign="" type="" required="false" allowordering="true"/>
            
            
            
            
            
            
            
         </fields>
         <rowactions>
            <action type="edit"/>
            <action type="delete"/>
         </rowactions>
         <massactions usefirstitemasdefault="true">
            <action type="massupdate"/>
            <action type="massdelete"/>
         </massactions>
         <views>
            <view type="standard"/>
         </views>
         <actions defaultlabel="Global Actions" defaulticon="ui-silk-wand" usefirstitemasdefault="true"/>
         <filters>
            
            
            
            
         <filter type="multiselect" filteroffoptionlabel="Any Type" createfilteroffoption="true" affectcookies="true" autocompthreshold="25" conditionsource="auto" labelmode="auto" conditionfield="Type" conditionoperator="in"/>
<filter type="select" filteroffoptionlabel="" createfilteroffoption="true" affectcookies="true" autocompthreshold="25" conditionsource="auto" labelmode="auto" condition="Status"/>
</filters>
         <searchfields/>
      <renderconditions logictype="and"/>
</skootable>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript>
         <jsitem location="inline" name="poll for updates" cachelocation="false" url="">(function(skuid){
var $ = skuid.$;
$(function(){
   // THe names of the Models that should be checked every so often for updates
   // These should NOT be the Models associated with Charts / Tables, etc.
   var RECENT_UPDATES_MODELS = [
       'RecentUpdates_Opportunity'
   ];
   // The number of seconds to wait before checking for updates
var INTERVAL_IN_SECONDS = 10;
// Each of our Models should have a Condition named "LastModifiedDate"
var COMMON_CONDITION_NAME = "LastModifiedDate";

var milliseconds = INTERVAL_IN_SECONDS * 1000;
var RecentUpdates = $.map(RECENT_UPDATES_MODELS,function(modelId){ return skuid.$M(modelId); });
setInterval(function(){
   var now = new Date();
   var previous = new Date(now.getTime() - milliseconds);
   $.each(RecentUpdates,function(i,model){
       var condition = model.getConditionByName(COMMON_CONDITION_NAME,true);
       var sfDateTime = skuid.time.getSFDateTime(previous);
       model.setCondition(condition,previous);
   });
   $.when(skuid.model.updateData(RecentUpdates))
       .done(function(){
          // If there are records in any of our Models, show our message
          var foundModelWithUpdates = false;
          $.each(RecentUpdates,function(i,model){
              if (model.getRows().length) {
                   foundModelWithUpdates = true;
              }
          });
          // If we found any Model(s) with recent updates,
          // show our updated records alert
          if (foundModelWithUpdates) {
               $('#UpdatedRecordsAlert').show('fast');    
          }
       });
},milliseconds);
});
})(skuid);</jsitem>
         <jsitem location="inlinecomponent" name="newRecordsAlert" cachelocation="false" url="">var element = arguments[0],
$ = skuid.$;

// The names of the Models that we want to REFRESH
// if there are any updates
var MODELS_TO_REFRESH = {
    'RecentUpdates_Opportunity' : 'Opportunity' 
};
var ALERT_MESSAGE = 'There are new / updated Opportunities.';
var MESSAGE_WHILE_LOADING = 'Loading new / updated records...';

var dismissMessage = function(){
  element.hide('fast');
};

var refreshList = $('&lt;a&gt;Click to refresh list&lt;/a&gt;')
    .css('text-decoration','underline')
    .css('color','white')
    .on('click',function(){
        $.blockUI({
            message: MESSAGE_WHILE_LOADING
        });
        // Determine the Models we need to update
        // Only update the ones whose corresponding RecentUpdate model has data rows
        var modelsToUpdate = [];
        $.each(MODELS_TO_REFRESH,function(checkModelId,updateModelId){
            var checkModel = skuid.$M(checkModelId);
            var updateModel = skuid.$M(updateModelId);
           if (checkModel &amp;&amp; checkModel.getRows().length &amp;&amp; updateModel) {
               modelsToUpdate.push(updateModel); 
           }
        });
        $.when(skuid.model.updateData(modelsToUpdate))
            .done(function(){
                dismissMessage();    
                $.unblockUI(); 
            });
        
    });

element
    .on('click',dismissMessage)
    .append(ALERT_MESSAGE)
    .append(refreshList)
    // Hide our element initially
    .hide();</jsitem>
      </javascript>
   </resources>
<styles>
<styleitem type="background" bgtype="none"/>
</styles>
</skuidpage>
Photo of krista06880

krista06880

  • 816 Points 500 badge 2x thumb
  • interested to learn if possible . . .

Posted 3 years ago

  • 1
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,006 Points 20k badge 2x thumb
A few thoughts. 

1. Drill down.  You should absolutely be able to connect the chart section to a detail list of records in a popup.   Have you looked at this:  http://help.skuidify.com/m/supercharge-your-ui/l/436074-visualizations-chart-sets-aka-visualization-...   

2.  Drawers.   I suspect you are trying to load ALL the client records and then use context conditions to put the right ones in the drawer.  This will get you in trouble with Heap Sizes pretty quick.  You should use "before open actions" on the drawer to query only the records you need.   Follow this tutorial:  http://help.skuidify.com/m/supercharge-your-ui/l/269735-add-nested-rows-to-your-table-with-drawers

3. Have fun!