Introduction
This article teaches admins how to utilize the 3B Charts component for embedding charts in a Digital Experience or Record Detail Page. 3B opened the component due to the fact that Salesforce requires an additional, more expensive license in order to embed Charts and Dashboards on a community. This component implements custom SOQL queries that are turned into beautiful charts using ChartJS javascript Framework
Digital Experience / Record Page
Security Architecture
Embedding 3B Charts requires that the administrator builds a security mechanism using Profiles, Permission Sets, Sharing Rules and Sharing Sets. These control what data flows to a 3B Chart. It is the responsibility of the administrator to set up an appropriate security architecture.
Embedding
In the App Builder, a new custom component will be available called "Chart Builder". Similarly, in the digital experience builder, the same component will be made available. Administrators need to drag and drop that component onto a page or record.
Sample SOQL
SELECT b3o__Type__c label, COUNT(Id) value FROM b3o__Chat_Message__c GROUP BY b3o__Type__c - this renders a doughnut chart that shows how many inbound messages were received vs how many outbound messages were recieved. Since we group by Type, the legend and dataset will display as Inbound and Outbound
Component Properties
Configuring
Once embedded, the App Builder side panel (or digital experience pop-up panel) will render the fields that need to be populated in order to render the chart.
There are 4 main types of components
- Chart
- Data
- Attributes
- Axes
Chart components define the element hosting the canvas, gathering the attributes and the data, and includes all the functionality of available to build a Chart using Chart.js. This component is responsible of dealing with the rendering lifecycle and also handles child events for the elements connected inside it.
Data components represent the source of data to put into the chart.
Attribute components define the different options that can be included to customize the chart. From animations to tooltip configurations, the attributes expose different properties to be filled with objects or callback functions.
Axes components allow you to determine how the data is mapped and represented inside the chart and their different scales.
Reactivity
The Charts component has been created with reactivity as a key point. All the attributes of the different components are reactive to changes, what means, that any change that you perform on real time (for example, the scale or the source data) will automatically fire an update event on the chart.
Properties
ATTRIBUTE | DESCRIPTION | VALIDATION | EXAMPLE |
---|---|---|---|
Type | Define the chart type | Picklist (line, bar, radar, doughnut, pie, polarArea, bubble, scatter) | |
Title | Define the chart title | String | |
Legend Position | Define where the legend will be displayed | Picklist (top, bottom, right, left) | |
CSS Style | Provide inline custom css style for chart container | String | position: relative; margin: auto;
|
Color palette to use | Choose the slds color palette to use | Picklist (default, colorsafe, light, bluegrass, sunrise, water, watermelon) | |
Fill the chart ? | Check this property fo fill the chart | Boolean | |
Dataset Labels | Display the label for each values set in the dataset in a JSON array of string | JSON Array [] | ["Label 1", "Label 2", ...]
|
Dataset | Define the chart values in a JSON array of object | JSON Array [] | [{"labels":"Data 1", "detail":[1, 1]},{"labels":"Data 2", "detail":[2, 2]},...]
|
SOQL | Define a SOQL to be used to fetch the data (only aggregate query). Use label alias for the label and value alias for the value | String | SELECT StageName label, SUM(Amount) value FROM Opportunity WHERE IsClosed = false WITH SECURITY_ENFORCED GROUP BY StageName LIMIT 10
|
Custom Data Provider | Define the Custom Data Provider class hander name to fetch the data. It must extends "ChartDataProvider" | String | MyCustomChartDataProvider |
Focus on the "Dataset" Property
This property is used to display static content.
Provide the JSON object you want to display.
Use this property to get fast at prototyping and to show case final render.
Focus on the "SOQL" Property
This property is used to execute a query to gather data from the server.
The SOQL query must respect those constraints :
- having a
label
alias in order to set the label of the data. - having a
value
alias in order to set the values of the data. - grouping the record by a field
- having a
limit
statement (optional) - having the
WITH SECURITY_ENFORCED
statement (optional)
The query accept to use :recordId
string placeholder and will replace this with the actual record Id if the component is placed on an object page.
IMPORTANT: The radar, bubble and scatter charts are not currently supported to work with the SOQL property. If you need to create a chart of one of these types, please use a JSON structure or check the API Documentation.
Example of a well formed query for a Component placed on an account page :
SELECT StageName label, SUM(Amount) value FROM Opportunity WHERE IsClosed = false AND AccountId = :recordId WITH SECURITY_ENFORCED GROUP BY StageName LIMIT 10
Focus on the "Custom Data Provider" Property
This property is used to execute custom apex handler to provide data.
The class provided must extend the class ChartDataProvider
.
The lwc component will pass to the class the recordId (if on an object page)
IMPORTANT: The radar, bubble and scatter charts are not currently supported to work with a Custom Data Provider.
Chart API
ATTRIBUTE NAME | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
type | string | bar
|
The type of chart. The options are: line , bar , horizontalBar , radar , doughnut , pie , polarArea , bubble and scatter
|
uuid | string | A random uuid | UUID used to identify uniquely the chart |
chartjsloadedCallback | function | Called when Chartjs is loaded. | |
canvasOnchange | function | Allows to define a callback for an event (parameter) of type change binded to the canvas.
| |
canvasOnclick | function | Allows to define a callback for an event (parameter) of type click binded to the canvas.
| |
canvasOnmouseover | function | Allows to define a callback for an event (parameter) of type mouseover binded to the canvas.
| |
canvasOnmouseout | function | Allows to define a callback for an event (parameter) of type mouseout binded to the canvas.
| |
responsive | boolean | true
|
Resizes the chart canvas when its container does (important note...). |
responsiveanimationduration | number | 0 | Duration in milliseconds it takes to animate to new size after a resize event. |
maintainaspectratio | boolean | true
|
Maintain the original canvas aspect ratio (width / height) when resizing. |
aspectratio | number | 2 | Canvas aspect ratio (i.e. width / height, a value of 1 representing a square canvas). Note that this option is ignored if the height is explicitly defined either as attribute or via the style. |
callbackResize | function | Called when a resize occurs. Gets passed two arguments: the chart instance and the new size. | |
devicepixelratio | number | window.devicePixelRatio | Override the window`s default devicePixelRatio. |
events | string[] | ['mousemove' , 'mouseout' , 'click' , 'touchstart' , 'touchmove' ]
|
The events option defines the browser events that the chart should listen to for tooltips and hovering. more... |
callbackClick | function | null | Called when any of the events fire. Called in the context of the chart and passed the event and an array of active elements (bars, points, etc). |
callbackHover | function | null | Called if the event is of type mouseup or click . Called in the context of the chart and passed the event and an array of active elements.
|
destroyChart | function | Use this to destroy any chart instances that are created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js. This must be called before the canvas is reused for a new chart. | |
updateChart(duration, lazy) | function | Triggers an update of the chart. This can be safely called after updating the data object. This will update all scales, legends, and then re-render the chart. A config object can be provided with additional configuration for the update process. This is useful when update is manually called inside an event handler and some different animation is desired. See Updating Charts for more details. | |
resetChart | function | Reset the chart to it's state before the initial animation. A new animation can then be triggered using update .
| |
renderChart(config) | function | Triggers a redraw of all chart elements. Note, this does not update elements for new data. Use .update() in that case. See .update(config) for more details on the config object.
| |
stopChart | function | Use this to stop any current animation loop. This will pause the chart during any current animation frame. Call .render() to re-animate.
| |
resizeChart | function | Use this to manually resize the canvas element. This is run each time the canvas container is resized, but you can call this method manually if you change the size of the canvas nodes container element. | |
clearChart | function | Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful. | |
toBase64ImageChart | function | This returns a base 64 encoded string of the chart in it's current state. | |
generateLegendChart | function | Returns an HTML string of a legend for that chart. The legend is generated from the legendCallback in the options. | |
getElementAtEventChart(event) | function | Calling getElementAtEvent(event) on your Chart instance passing an argument of an event, or jQuery event, will return the single element at the event position. If there are multiple items within range, only the first is returned. The value returned from this method is an array with a single parameter. An array is used to keep a consistent API between the get*AtEvent methods.
| |
getElementsAtEventChart(event) | function | Looks for the element under the event point, then returns all elements at the same data index. This is used internally for 'label' mode highlighting Calling getElementsAtEvent(event) on your Chart instance passing an argument of an event, or jQuery event, will return the point elements that are at that the same position of that event.
| |
getDatasetAtEventChart(event) | function | Looks for the element under the event point, then returns all elements from that dataset. This is used internally for 'dataset' mode highlighting | |
getDatasetMetaChart(index) | function | Looks for the dataset that matches the current index and returns that metadata. This returned data has all of the metadata that is used to construct the chart. The data property of the metadata will contain information about each point, rectangle, etc. depending on the chart type. Extensive examples of usage are available in the Chart.js tests.
|
<c-chart type="bar" responsive="true">
</c-chart>
Data API
ATTRIBUTE NAME | TYPE | DEFAULT | DESCRIPTION | CHART |
---|---|---|---|---|
backgroundColor | Color | 'rgba(0, 0, 0, 0.1)' | The bar background color. | Line, Bar, Radar, Doughnut, Pie, Polar area, Bubble |
borderAlign | string | 'center' | The border alignment ('center' or 'inner') | Doughnut, Pie, Polar area |
borderCapStyle | string | 'butt' | Cap style of the line | Line, Radar |
borderColor | Color | 'rgba(0, 0, 0, 0.1)' | The bar border color. | Line, Bar, Radar, Doughnut, Pie, Polar area, Bubble |
borderDash | number[] | [] | Length and spacing of dashes. | Line, Radar |
borderDashOffset | number | 0 | Offset for line dashes. | Line, Radar |
borderJoinStyle | string | 'miter' | Line joint style. | Line, Radar |
borderSkipped | string | 'bottom' | This setting is used to avoid drawing the bar stroke at the base of the fill ('bottom', 'left', 'top', 'right', false) | Bar |
borderWidth | number | 3 | The bar border width (in pixels). | Line, Bar, Radar, Doughnut, Pie, Polar area, Bubble |
clip | number/object | borderWidth / 2 | How to clip relative to chartArea. Positive value allows overflow, negative value clips that many pixels inside chartArea. 0 = clip at chartArea. Clipping can also be configured per side: clip: {left: 5, top: false, right: -2, bottom: 0} | Line |
cubicInterpolationMode | string | 'default' | The following interpolation modes are supported: ('default, 'monotone') | Line |
detail (required) | object[] | An array containing the data to be displayed in the chart | All | |
fill | boolean/string | true | Whether to fill the area under the line | Line, Radar |
hitRadius | number | 1 | Bubble additional radius for hit detection (in pixels). | Bubble |
hoverBackgroundColor | Color | undefined | Background color when hovered. | Line, Bar, Radar, Doughnut, Pie, Polar area, Bubble |
hoverBorderCapStyle | string | undefined | Cap style of the line when hovered | Line, Radar |
hoverBorderColor | Color | undefined | Border color when hovered. | Line, Bar, Radar, Doughnut, Pie, Polar area, Bubble |
hoverBorderDash | number[] | undefined | Length and spacing of dashes when hovered. | Line, Radar |
hoverBorderDashOffset | number | undefined | Offset for line dashes when hovered. | Line, Radar |
hoverBorderJoinStyle | string | undefined | Line joint style when hovered. | Line, Radar |
hoverBorderWidth | number | undefined | The bar border width (in pixels) when hovered. | Line, Bar, Radar, Doughnut, Pie, Polar area, Bubble |
hoverRadius | number | 4 | Bubble additional radius when hovered (in pixels). | Bubble |
label | string | '' | The label for the dataset which appears in the legend and tooltips. | Line, Bar, Radar, Bubble |
lineTension | number | 0.4 | Bezier curve tension of the line. Set to 0 to draw straightlines. This option is ignored if monotone cubic interpolation is used. | Line, Radar |
order | number | 0 | The drawing order of dataset. Also affects order for stacking, tooltip, and legend. | Line, Bar, Radar, Bubble |
pointBackgroundColor | Color | 'rgba(0, 0, 0, 0.1)' | The fill color for points. | Line, Radar |
pointBorderColor | Color | 'rgba(0, 0, 0, 0.1)' | The border color for points. | Line, Radar |
pointBorderWidth | number | 1 | The width of the point border in pixels. | Line, Radar |
pointHitRadius | number | 1 | The pixel size of the non-displayed point that reacts to mouse events. | Line, Radar |
pointHoverBackgroundColor | Color | undefined | The bar background color when hovered. | Line, Radar |
pointHoverBorderColor | Color | undefined | The bar border color when hovered. | Line, Radar |
pointHoverBorderWidth | number | 1 | The bar border width when hovered (in pixels). | Line, Radar |
pointHoverRadius | number | 4 | The radius of the point when hovered. | Line, Radar |
pointRadius | number | 3 | The radius of the point shape. If set to 0, the point is not rendered. | Line, Radar |
pointRotation | number | 0 | The rotation of the point in degrees. | Line, Radar |
pointStyle | string/Image | 'circle' | Style of the point. | Line, Radar, Bubble |
radius | number | 3 | Bubble radius (in pixels). | Bubble |
rotation | number | 0 | Bubble rotation (in degrees). | Bubble |
showLine | boolean | undefined | If false, the line is not drawn for this dataset. | Line |
spanGaps | boolean | undefined | If true, lines will be drawn between points with no or null data. If false, points with NaN data will create a break in the line. | Line, Radar |
stack | string | undefined | The ID of the group to which this dataset belongs to (when stacked, each group will be a separate stack). | Bar |
steppedLine | boolean/string | false | The following values are supported for steppedLine: (false, true, 'before', 'after', 'middle') | Line |
weight | number | 1 | The relative thickness of the dataset. Providing a value for weight will cause the pie or doughnut dataset to be drawn with a thickness relative to the sum of all the dataset weight values. | Doughnut, Pie |
xAxisID | string | first x axis | The ID of the x axis to plot this dataset on. | Line, Bar |
yAxisID | string | first y axis | The ID of the y axis to plot this dataset on. | Line, Bar |
<c-chart>
<c-dataset>
<c-data
label="data"
detail="[28, 48, 40, 19, 96, 27, 100]"
backgroundcolor="rgba(255,99,132,0.2)"
bordercolor="rgba(255,99,132,1)"
>
</c-data>
</c-dataset>
</c-chart>
Dataset API
ATTRIBUTE NAME | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
labels | string[] | Contains the list of labels that will be represented by the data, this means, the main grops |
<c-chart>
<c-dataset labels='["Blue", "Orange", "Yellow", "Green", "Light Blue", "Purple"]'>
</c-dataset>
</c-chart>
Custom Apex Data Providers
global inherited sharing class DemoDataProvider extends ChartDataProvider {
/*******************************************************************************************************
* @description Not used for this class
* @param initParameter Object
*/
public override void init(final Object initParameter) {
// TODO
}
/*******************************************************************************************************
* @description return the data
* @return List<ChartData> the list of chart data needed to display the graph
*/
public override List<ChartDataProvider.ChartData> getData() {
final List<ChartDataProvider.ChartData> chartDatas = new List<ChartDataProvider.ChartData>();
ChartDataProvider.ChartData aChartData = new ChartDataProvider.ChartData();
aChartData.labels = DEMO_LABEL;
aChartData.detail = DEMO_DATA;
aChartData.bgColor = DEMO_COLOR;
chartDatas.add(aChartData);
return chartDatas;
}
public static final List<String> DEMO_LABEL = new List<String>{ '' };
public static final List<Decimal> DEMO_DATA = new List<Decimal>{
10,
20,
15,
5,
25,
30
};
public static final String DEMO_COLOR = 'rgba(0,0,0,0.5);';
}
3B Portals
TBC