7

I am attempting to follow this documentation to create a very simple bar graph, however, it seems as though Salesforce has no idea what is in my D3 static resource as it says ____ is not a function for anything I try to do with the imported D3 object.

I did exactly what the documentation said:

  • Went to D3's GitHub to download the resource files: https://github.com/d3/d3
  • Zipped the repo up
  • Created a new Static Resource and selected the d3-master.zip file as the file for the static resource.
  • Set the cache control to Public.

And then I went ahead and used this resource provided by D3 to construct a D3 Bar Chart.

I can't figure out what's wrong. I get errors for both D3.scaleLinear and D3.scaleBand functions when attempting to set y and x, respectively.

import { LightningElement } from 'lwc';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import D3 from '@salesforce/resourceUrl/D3';


export default class YtpReport extends LightningElement {
    svgWidth = 400;
    svgHeight = 400;

    d3Initialized = false;

    /**
     * Dummy Data Fillers
     */
    data = [
            {"name": "E", value: "10"},
            {"name": "A", value: "15"},
            {"name": "I", value: "25"},
            {"name": "Y", value: "9"},
            {"name": "U", value: "8"},
            {"name": "O", value: "3"}
        ]

    /**
     * Render the SVG
     */
    renderedCallback() {
        if (this.d3Initialized) {
            return;
        }
        this.d3Initialized = true;

        Promise.all([
            loadScript(this, D3 + '/d3.v5.min.js'),
            loadStyle(this, D3 + '/style.css'),
        ])
            .then(() => {
                this.initializeD3();
            })
            .catch(error => {
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Error loading D3',
                        message: error.body.message,
                        variant: 'error',
                    }),
                );
            });
    }

    /**
     * Calculations
     */
    y = D3.scaleLinear()
        .domain([0, D3.max(this.data, d => d.value)]).nice()
        .range([this.height - this.margin.bottom, this.margin.top])

    x = D3.scaleBand()
        .domain(this.data.map(d => d.name))
        .range([this.margin.left, this.width - this.margin.right])
        .paddingInner(0.1)

    xAxis = g => g
        .attr("transform", `translate(0,${this.height - this.margin.bottom})`)
        .call(D3.axisBottom(this.x).tickSizeOuter(0))

    yAxis = g => g
        .attr("transform", `translate(${this.margin.left},0)`)
        .call(D3.axisLeft(this.y))

    margin = ({top: 20, right: 0, bottom: 30, left: 40})

    /**
     * Initialize the data graph
     */
    initializeD3() {
        const svg = D3.select(this.template.querySelector('svg.d3'));
        //const width = this.svgWidth;
        //const height = this.svgHeight;

        svg.append("g")
            .attr("fill", "steelblue")
            .selectAll("rect")
            .data(this.data)
            .join("rect")
            .attr("x", d => this.x(d.name))
            .attr("y", d => this.y(d.value))
            .attr("height", d => this.y(0) - this.y(d.value))
            .attr("width", this.x.bandwidth());

        svg.append("g")
            .call(this.xAxis);

        svg.append("g")
            .call(this.yAxis);

        return svg.node();
    }

}

I even tried to copy exactly what they have in the documentation of showing a force-directed graph, and while I don't get any errors, I don't get any graph displayed.

0

4 Answers 4

5

You seem to have downloaded the source code for D3 from github. Whereas you only need the JS file and the CSS (as referenced in the documentation examples).

You can find the JS file on d3js.org, download it and then upload it as a static resource. If you also want to utilize the CSS as in the sample on documentation, then best place to download these files is on the lwc-recipe for this sample. Just download the files, zip it and upload it as static resource.

As an example, the static resource in my Org is named d3 and consists only of two files - the JS and the CSS. And based on the source code on lwc-recipes, the component is rendered perfectly fine (sample screenshot from my Dev Org).

enter image description here

12
  • So I download the d3.zip (github.com/d3/d3/releases/download/v5.9.1/d3.zip) file from D3's website, and only grab out the d3.min.js file and upload that? And if I want the css, I combine the d3.min.js with the style.css in a zip file and upload that instead?
    – BlondeSwan
    Feb 26, 2019 at 22:46
  • @BlondeSwan Yes, that's correct. You actually can utilize the one on the lwc-recipe link that I have provided. It provides you with those files.
    – Jayant Das
    Feb 26, 2019 at 22:47
  • Okay thanks. And then for a function like D3.scaleBand() that, according to this answer (stackoverflow.com/questions/38675348/…), I would need to get the d3-selection-multi.v1.min.js file and put into the zip file and re-upload the zip file into my static resources?
    – BlondeSwan
    Feb 26, 2019 at 23:00
  • @BlondeSwan I would imagine, yes. I haven't really worked with this library and know only in the context of the ones available in the samples.
    – Jayant Das
    Feb 26, 2019 at 23:01
  • Okay, so I used your link to get the right files, and I changed my code to be exactly the one that is in the documentation (both the JS and the HTML) and I don't get errors. but I don't get any graph appearing... Is there something I need to add in the HTML?
    – BlondeSwan
    Feb 26, 2019 at 23:03
3

After playing with this for a couple hours, it was the smallest thing to get it to cooperate.

I started by pulling down the entire lwc-recepies repo. Then I copied their d3 folder to my home directory and compressed (zipped) it into a .zip file, which I uploaded to Salesforce as a static resource.

I tried using the initialization routine for d3 from the lwc-recipes (here), but it did not work:

Promise.all([
  loadScript(this, D3 + '/d3.v5.min.js'),
  loadStyle(this, D3 + '/style.css')
]){... omitting the rest ... }

I found that I had to add d3 to the beginning of the file paths. Probably because the name of my zip file was d3. This is what I ended up using:

Promise.all([
  loadScript(this, D3 + 'd3/d3.v5.min.js'),
  loadStyle(this, D3 + 'd3/style.css')
]){... omitting the rest ... }
3

If you're just following the example in the Component Library documentation you will find that the D3 demo code doesn't work without some additions.

The d3.zip file from d3js.org (incorrectly called d3js.com in the documentation) only contains d3.js and d3.min.js. I copied style.css from lwc-recipes repo and added it to my component as libsD3.css. Grabbed the data.js file from the repo as well and dropped it in the component folder. I commented out the loadStyle() line in libsD3.js and changed the loadScript parameter:

loadScript(this, D3 + '/d3.min.js'

to match the content of the zip file from D3.

Added appropriate <target> tags in the component configuration file and deployed to a developer org. I was able to add the component to a record page where it worked flawlessly.

1

You may face that style file not found an error on the console just because the given zip file does not have a style file. So To resolve the problem copy the style file code given below and paste this code in a new CSS file and add it into the src folder inside the package folder of the zip file and again upload it to static resource.

svg.d3 .links line {
    stroke: black;
    stroke-width:2 px;
    
}

svg.d3 .nodes circle {
    stroke: black;
    stroke-width: 1.5px;
    fill:white;
}
svg.d3 .nodes Ellipse {
    stroke: black;
    stroke-width: 1.5px;
    fill:white;

}

Please add the proper path to load the files.

Promise.all([
                loadScript(this, D3 + '/package/dist/d3.min.js'),
                loadStyle(this, D3 + '/package/src/style.css')
            ])

there "Package" is the name of the zip file uploaded into the static resource.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .