D3.js…meet Lightning Web Components

4 things I learned creating an interactive timeline component for the Salesforce platform using third party JS libraries

Dave Norris
4 min readJan 5, 2020

It’s been 10 weeks since my first article. In that time we’ve discussed taking an idea for an interactive timeline through to UI design and finally a technical design for performance and scale.

This is a sample of what I built.

An interactive timeline for the Salesforce platform

This is what I learned.

1 — Not everyone lives in Australia

I had designed a component that looked great in one locale and language — but wouldn’t be as appreciated in any other country that didn’t speak English or have their dates formatted as dd mm yyyy. This oversight would limit its reusability and usefulness for global customers.

There are 2 things that helped me change this

a) Custom Labels

I added custom labels that I used for any custom labels I needed. This allows an administrator to override the label for any language of their choice. Now when a user sets their language to be anything other than English I can provide a translated value for the string in question.

import DAYS from '@salesforce/label/c.Timeline_Label_Days'
import SHOWING from '@salesforce/label/c.Timeline_Label_Showing'
label = {
DAYS,
SHOWING,
};
<div class="timeline-summary">{label.SHOWING}</div>
Labels when language is English
Labels when language is Spanish

b) Access Internationalisation Properties

The timeline component heavily relies on dates. I had originally planned to show the dates in the format dd mm yyyy. This would have been a big mistake. Instead I changed my strategy to access the internationalisation properties made available by salesforce in a scoped module I can import.

import LOCALE from '@salesforce/i18n/locale';const dateTimeFormat = new Intl.DateTimeFormat(LOCALE);
Date formats when locale is English
Date formats when locale is German

Lightning web components have internationalisation properties that you can use to adapt your components for users worldwide, across languages, currencies, and timezones.

2— Responsiveness is more than media queries

I had added some media queries to ensure that the timeline could be resized and that the labels would function and be usable even in narrow widths.

My timeline component had 2 issues that needed to be solved on top of css media queries

a) Dynamic D3.js recalculations based on window resize

The timeline relies on the available width of the component to calculate the x axis. As the width widens we needed to recalculate the x axis to take up the available space. I did this by adding an event listener to the window resize event. Manually adding event listeners isn’t typically a good idea as you are responsible for removing them and failing to do so can lead to memory leaks — so use with caution.

window.addEventListener('resize', me.debounce(() => {
try {
//redraw logic
}
catch(error) {
//stay silent
}
}, 200));

b) Dynamic resizing based on template width

When you drop a component into the narrow section of the App Builder template in Salesforce you typically want your component to react and adjust to the available space. Using media queries does not work as they will assess the window dimensions.

To change the look and feel of your component Salesforce has a property you can include in your Lightning Web Components

@api flexipageRegionWidth        //SMALL, MEDIUM and LARGE

The above property will be assigned the value SMALL, MEDIUM or LARGE depending on which section of the App Builder template the component is dragged into. I could then use this to add a class to a specific subset of html elements that could then in turn be styled differently in the stylesheet

timeline.classList.add("<prefix>" + this.flexipageRegionWidth);

3 — Ask for help

It’ll be somewhat obvious from the GitHub repository…but I’m no JavaScript expert, or know css or Apex particularly well. What I learned was to ask for help from people who are, google extensively and never give up.

It’s also the reason I’ve shared the code.

No need to tell me that you can do better. Send me a pull request and make it better. You can help me, and others, learn from your experience.

4— Always judge a book by its GitHub README

They say never judge a book by its cover but in reality your README is your first opportunity to tell the world what your component does and how to install it. It needs to get lots of attention. I believe a compelling README will encourage others to install, review and contribute.

But. I’ll let you be the judge.

Further Reading

Review, install and contribute to the component here.

--

--

Dave Norris

Developer Advocate @ Salesforce || Interested in solving unique challenges using different cloud service providers || All opinions are mine.