Angular directive for D3 chart not displaying on the page

While working on a D3-based angular directive inspired by this code pen

Here is my implementation. Check out the Codepen link

angular.module('myApp', []).
    directive('barsChart', function ($parse) {
      
    
    var directiveDefinitionObject = {
            restrict: 'E',
            replace: false,
            scope: {data: '=chartData'},
            link: function (scope, element, attrs) {
                var chords, h, strings, w;
                w = 32;
                h = 32;
                strings = ['E', 'B', 'G', 'D', 'A', 'E'];
                console.log('----------****',d3.select(element[0]));
                
                d3.select(element[0]).selectAll('div').data(scope.data).enter().append('div').groups
                
                .each(function(chord, c) {
                    d3.select(this).append('h3').attr({
                        'class': 'chord-name'
                    }).text(function(d) {
                        return d.name;
                    });
                    return d3.select(this).append('div').attr({
                        'class': 'strings'
                    }).selectAll('div').data(chord.strings).enter().append('div').attr({
                        'class': 'string'
                    }).each(function(string, s) {
                        var _, frets;
                        d3.select(this).append('strong').attr({
                            'class': 'string-name'
                        }).text(function(d, i) {
                            return strings[s];
                        });
                        frets = (function() {
                            var j, results;
                            results = [];
                            for (_ = j = 0; j <= 5; _ = ++j) {
                                results.push(false);
                            }
                            return results;
                        })();
                        frets[chord.strings[s]] = true;
                        console.debug(s, frets);
                        return d3.select(this).append('span').attr({
                            'class': 'frets'
                        }).selectAll('span').data(frets).enter().append('span').attr({
                            'class': 'fret'
                        }).append('span').attr({
                            'class': function(fret, f) {
                                return fret != false ? 'finger' : 'empty';
                            }
                        }).html(function(fret, f) {
                            return fret != false ? f : '&mdash;';
                        });
                    });
                });
            }
        };
        return directiveDefinitionObject;
    
    
    });

function Ctrl($scope) {
    $scope.chords = [
        {
            name: 'C',
            strings: [0, 1, 0, 2, 3, null]
        }, {
            name: 'D',
            strings: [2, 3, 2, 0, null, null]
        }, {
            name: 'E',
            strings: [0, 0, 1, 2, 2, 0]
        }, {
            name: 'F',
            strings: [1, 1, 2, 3, 3, 1]
        }, {
            name: 'G',
            strings: [3, 3, 0, null, 2, 3]
        }, {
            name: 'A',
            strings: [0, 2, 2, 2, 0, null]
        }, {
            name: 'B',
            strings: [2, 3, 4, 4, 2, null]
        }, {
            name: 'C#',
            strings: [3, 4, 5, 5, 3, null]
        }, {
            name: 'Bm',
            strings: [2, 2, 4, 4, 2, null]
        }, {
            name: 'Bb',
            strings: [1, 3, 3, 3, 1, null]
        }
    ];
}
.chord {
    float: left;
    padding: 1.2em;
    margin: .6em 0 0 .6em;
    font-family: monospace;
    background-color: #F0F0F0;
}
/* CSS styling omitted for brevity */
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<div ng-app="myApp" ng-controller="Ctrl">
    <bars-chart chart-data="chords"  ></bars-chart>
</div>

Although everything seems fine, I encountered an error message stating "accessing each of undefined". Any suggestions?

Answer №1

I successfully integrated the functional code pen into your directive after compiling the coffee. The main issue was accessing the groups property, which turned out to be non-existent. Groups should be derived from the g sub-element of svg, but since this chart is comprised solely of div and span elements, there is no svg element present.

angular.module('myApp', []).
    //camel cased directive name
    //in your HTML, this will be named as bars-chart
    directive('barsChart', function ($parse) {

        var directiveDefinitionObject = {
            restrict: 'E',
            replace: false,
            scope: {
                data: '=chartData'
            },
            link: function (scope, element, attrs) {
                var chords, h, strings, w;
                w = 32;
                h = 32;
                strings = ['E', 'B', 'G', 'D', 'A', 'E'];
                   d3.select(element[0]).selectAll('div').data(scope.data).enter().append('div').attr({
                    'class': 'chord'
                }).each(function (chord, c) {
                    d3.select(this).append('h3').attr({
                        'class': 'chord-name'
                    }).text(function (d) {
                        return d.name;
                    });
                    return d3.select(this).append('div').attr({
                        'class': 'strings'
                    }).selectAll('div').data(chord.strings).enter().append('div').attr({
                        'class': 'string'
                    }).each(function (string, s) {
                        var _, frets;
                        d3.select(this).append('strong').attr({
                            'class': 'string-name'
                        }).text(function (d, i) {
                            return strings[s];
                        });
                        frets = function () {
                            var j, results;
                            results = [];
                            for (_ = j = 0; j <= 5; _ = ++j) {
                                if (window.CP.shouldStopExecution(1)) {
                                    break;
                                }
                                results.push(false);
                            }
                            window.CP.exitedLoop(1);
                            return results;
                        } ();
                        frets[chord.strings[s]] = true;
                        console.debug(s, frets);
                        return d3.select(this).append('span').attr({
                            'class': 'frets'
                        }).selectAll('span').data(frets).enter().append('span').attr({
                            'class': 'fret'
                        }).append('span').attr({
                            'class': function (fret, f) {
                                return fret != false ? 'finger' : 'empty';
                            }
                        }).html(function (fret, f) {
                            return fret != false ? f : '&mdash;';
                        });
                    });
                });
            }
        }

        return directiveDefinitionObject;
    });

    function Ctrl($scope) {
      $scope.chords = [{
        name: 'C',
        strings: [0, 1, 0, 2, 3, null]
      }, {
        name: 'D',
        strings: [2, 3, 2, 0, null, null]
      }, {
        name: 'E',
        strings: [0, 0, 1, 2, 2, 0]
      }, {
        name: 'F',
        strings: [1, 1, 2, 3, 3, 1]
      }, {
        name: 'G',
        strings: [3, 3, 0, null, 2, 3]
      }, {
        name: 'A',
        strings: [0, 2, 2, 2, 0, null]
      }, {
        name: 'B',
        strings: [2, 3, 4, 4, 2, null]
      }, {
        name: 'C#',
        strings: [3, 4, 5, 5, 3, null]
      }, {
        name: 'Bm',
        strings: [2, 2, 4, 4, 2, null]
      }, {
        name: 'Bb',
        strings: [1, 3, 3, 3, 1, null]
      }];
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am uncertain about whether it would be better to utilize URL path parameters or query parameters for filtering on the back-end of the application

Suppose I am trying to retrieve all car models from a specific brand. This can be achieved by utilizing URL path parameters or query parameters as shown below: router.get('/modelsByBrand', modelController.getModelsByBrand); To make the GET reque ...

Updating subdata in an array using Reactjs handleChange

I am facing an issue with my handleChange function. While I can easily change data in the same directory without any problem, I'm struggling to update sub-data. I would like to find a clean solution for this without having to add extra functions withi ...

when successful, refresh the page

I am currently utilizing the following javascript code to load recrefresh.php when the page first loads. Upon executing the ajaxvote function, I aim for the subsequent div to be refreshed: <div class="recrefresh"></div> After attempting to ad ...

JavaScript error: Resource could not be loaded

When I have a js function called by an onclick event in a radio button, it doesn't work if the function is placed in the same ascx file where the radio button is defined. To resolve this issue, I moved the function to the ascx that includes the ascx w ...

Unraveling the intricacies of extracting data from nested object properties

Why do my variables stop being reactive after unwrapping from props? I have three components - a parent component, a second component for display, and a third component for updating data based on input (simplified code here). The third component updates ...

Adjusting the alignment of Bootstrap navbar items upon clicking the toggle button

When I click the toggle button on a small screen, my navbar items appear below the search bar instead of aligning with the home and about elements. Below is an image depicting this issue: https://i.stack.imgur.com/4rabW.png Below is the HTML code structu ...

Iterating through elements to set the width of a container

I am currently working on a function that dynamically adjusts the width of an element using JavaScript. Here is my JavaScript code: <script> $('.progress-fill span').each(function(){ var percent = $(this).html(); if(per ...

Is it advisable to hold off until the document.onload event occurs?

I'm working with a basic HTML file where I need to generate SVGs based on data retrieved through an AJAX call. Do I need to ensure the document is fully loaded by enclosing my code within a document.onload = function() { ... } block, or can I assume ...

Blending ASP.NET Core 2.0 Razor with Angular 4 for a Dynamic Web Experience

I am currently running an application on ASP.NET Core 2.0 with the Razor Engine (.cshtml) and I am interested in integrating Angular 4 to improve data binding from AJAX calls, moving away from traditional jQuery methods. What are the necessary steps I need ...

Ways to successfully pass multiple parameters in Nuxt

Within Nuxt.js, when working with the code in pages/posts/_id.vue, it looks like this: <template> ...

Retrieving the latest entry from the MySQL database

I am encountering an issue with a code that involves fetching data from MySQL into an array. I have a form with color and size select boxes, and when an onclick javascript function is triggered it creates two additional select boxes. I have successfully re ...

How can I verify if an unsupported parameter has been passed in a GET request using Express/Node.js?

Within my node.js backend, there is a method that I have: app.get('/reports', function(req, res){ var amount = req.param('amount'); var longitude = req.param('long'); var latitude = req.param('lat'); var di ...

ReactJS - When a child component's onClick event triggers a parent method, the scope of the parent method may not behave as anticipated

In my current setup, I have a parent component and a child component. The parent component contains a method within its class that needs to be triggered when the child component is clicked. This particular method is responsible for updating the store. Howe ...

What steps are needed to link my Javascript application with Amazon Keyspaces?

I am a beginner looking for assistance with extracting data from Amazon keyspaces tables on a small demo website with 4 categories and 4 subcategories. I have created the tables but can't find a tutorial, please help. The goal is to display database ...

How to stop a component template in Angular from displaying both conditional statements simultaneously?

I want to prevent my component template from briefly displaying both conditional statements when the condition changes after the component has been initialized. My application receives a token, and depending on its validity, it shows the appropriate conte ...

The animation in Material UI does not smoothly transition with the webkit scrollbar

I've been experimenting with CSS animations in Material UI's sx property to achieve a webkit scrollbar that eases in and out. However, instead of the desired effect, the scrollbar appears and disappears instantly. Whether I define the keyframes ...

Enhance Your Search Experience with Angular

I recently developed an Angular app that searches through a database of objects. However, a problem arises with the search filters as they match any part of the string, resulting in irrelevant search results. For example, when searching for the name "Stev ...

Issues with audio and video playback intermittently occurring on Sencha Touch 2

As a beginner with Sencha Touch 2, I am currently working on uploading images onto an iPad using Xcode. My app has audio playing on the home screen, and I want the video to start playing and the audio to stop when a specific tab is selected. However, the ...

Solving the challenge of converting images to text using react-native and the @react-native-ml-kit/text-recognition package

As I work on my react native project, I have encountered a challenge. I am trying to implement a feature that allows users to either take a photo or select one from their library. Once the image is chosen, I want to extract all the text from it and display ...

Ways to retrieve sorted and updated items in ngx-datatable post-sorting

I am currently utilizing the swimlane/ngx-datatable library to display a list. Within each row of the list, I have implemented an action menu that pops up upon clicking an icon, with dynamically generated items. Challenge: Following sorting, the items app ...