> For the complete documentation index, see [llms.txt](https://docs.acho.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.acho.io/app-builder/popular-use-cases/create-a-chart-with-code-block-and-d3-library.md).

# Create a Chart with Code Block and D3 Library

Beside the [Chart](/app-builder/app-construction/elements/table-and-chart/chart.md) element that you can use to build charts, you can also use a combination of  [Code Block](/app-builder/app-construction/elements/advanced-elements/code-block.md) and javascript d3 library to create more customized data visualization.

The following link <https://d3-graph-gallery.com/graph/barplot_horizontal.html> showcases a basic horizontal bar chart from D3.js Graph Gallery, this tutorial will guide you on how can you use **Code block** to create a same plot in app builder.&#x20;

1. Load D3.js:
   * The Code Block element requires manually adding the D3 library to the document body using `$script=document.createElement("script")` and `document.body.appendChild($script)`.
   * To ensure that the dependent code runs after the library is loaded, place the code inside `$script.onload = function () { }`.
2. Set root ID and select by ID:
   * In the D3 gallery example, a div was created to contain the chart. However, in the **Code Block** element, we typically want the chart to be placed at the position of the **Code Block** element itself, allowing us to arrange it within the app builder. In order to do that, set the ID of the current **Code Block** element to "`my_dataviz`" using `root.id = "my_dataviz".`&#x20;
   * When creating the SVG, use the same ID to select the Code Block element and create the SVG inside it: `var svg = d3.select("#my_dataviz")`
   * Remember to replace "`my_dataviz`" with your desired ID name.
3. Write the remaining code in `$script.onload = function () { }`.
   * Within this block, you can write the custom code using the D3.js library to generate the desired chart.
   * Utilize the rich D3.js API and functions to create interactive and visually appealing data visualizations within the **Code Block** element.

Following these steps, we could create a chart in **Code Block** element same as the one in D3 gallary. Click preview to see the final result.

<div align="left"><figure><img src="/files/fWgKHs9ut1TCVXLyOADK" alt=""><figcaption><p>The chart in preview mode</p></figcaption></figure></div>

4. Define event to enhance interaction(Optional).
   * Customized events allow you to pass data from within a Code Block to app or trigger other actions.
   * Using defineEvent() function, fill title, name and event to define an event in Code Block. Note that it should be defined outside render function
   * Setup trigger to emit the event.
   * The new defined event will appear in the Code Block's interaction panel. Use it to create [Interactions](/app-builder/app-construction/interactions.md)
   * To be more specific, if you want to define a barclick event, try:

     ```javascript
     defineEvent(/* event definition */ {
         title: "Click",
         name: "barclick",
         payload: [
             {
                 name: "Country",
                 field: "country",
                 type: "string"
             },
             {
                 name: "Value",
                 field: "value",
                 type: "number"
             }
         ]
     })
     ```
   * And add `add .on("click", function (event, d) { console.log([event,d]) emit('barclick', { country: d.Country, value: d.Value}); });` at the end of the svg.append command.&#x20;

<figure><img src="/files/pCANsZW0WFO9x1ZU668L" alt=""><figcaption><p>Add interaction using customized event</p></figcaption></figure>

Source code in **Code Block**

```javascript
function setupCode({ emit, defineEvent, defineMethod, console }, dependencies) {
    function render(data, { root, rendered, props, getThemeValue }) {
        // Set the ID of the current Code Block element to 'my_dataviz'
        root.id = "my_dataviz"

        // Load d3.js library
        const $script = document.createElement('script');
        document.body.appendChild($script);
        $script.src = "https://d3js.org/d3.v6.min.js";

        // When the D3.js script has loaded, execute the following code.
        $script.onload = function () {
            {
                d3.select('#my_dataviz').selectAll('svg').remove();
                // Select current Code Block by its id 'my_dataviz', then create a new SVG element with a width and height of 400
                // set the dimensions and margins of the graph
                // set the dimensions and margins of the graph
                const margin = { top: 20, right: 30, bottom: 40, left: 90 },
                    width = 400 - margin.left - margin.right,
                    height = 400 - margin.top - margin.bottom;

                // append the svg object to the body of the page
                const svg = d3.select("#my_dataviz")
                    .append("svg")
                    .attr("width", width + margin.left + margin.right)
                    .attr("height", height + margin.top + margin.bottom)
                    .append("g")
                    .attr("transform", `translate(${margin.left}, ${margin.top})`);

                // Parse the Data
                d3.csv("https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/7_OneCatOneNum_header.csv").then(function (data) {

                    // Add X axis
                    const x = d3.scaleLinear()
                        .domain([0, 13000])
                        .range([0, width]);
                    svg.append("g")
                        .attr("transform", `translate(0, ${height})`)
                        .call(d3.axisBottom(x))
                        .selectAll("text")
                        .attr("transform", "translate(-10,0)rotate(-45)")
                        .style("text-anchor", "end");

                    // Y axis
                    const y = d3.scaleBand()
                        .range([0, height])
                        .domain(data.map(d => d.Country))
                        .padding(0.1);
                    svg.append("g")
                        .call(d3.axisLeft(y))

                    //Bars
                    svg.selectAll("myRect")
                        .data(data)
                        .join("rect")
                        .attr("x", x(0))
                        .attr("y", d => y(d.Country))
                        .attr("width", d => x(d.Value))
                        .attr("height", y.bandwidth())
                        .attr("fill", "#69b3a2")
                        .on("click", function (event, d) {
                            console.log([event, d])
                            emit('barclick', { country: d.Country, value: d.Value });
                        });

                })

            }
        }
    }

    defineEvent(/* event definition */ {
        title: "Bar Click",
        name: "barclick",
        payload: [
            {
                name: "Country",
                field: "country",
                type: "string"
            },
            {
                name: "Value",
                field: "value",
                type: "number"
            }
        ]
    })

    return { render };
}
```
