Ways to show text on a donut chart when hovering with the mouse

I have been attempting to make adjustments to this sample. My goal is to display a word in the center of the donut chart upon mouseover, similar to this:

Although I have included code for mouseover, it seems to not be functioning properly.

Code

const eventObj = {
          'mouseover': function (d, i, j) {
              pathAnim(d3.select(this).select('path'), 1);
              centerTxt.text(function () {
                  return d.data.label;
              })
              // .call(wrap, 40);
          },
          'mouseout': function (d, i, j) {
              const thisPath = d3.select(this).select('path');
              if (!thisPath.classed('clicked')) {
                  pathAnim(thisPath, 0);
              }
              centerTxt.text(function (d) {
                  return '';
              });
          },


                'click': function(d, i, j) {


                    var thisPath = d3.select(this);
                    var clicked = thisPath.classed('clicked');
                    pathAnim(thisPath, ~~(!clicked));
                    thisPath.classed('clicked', !clicked);

                    //setCenterText(thisDonut);
                }
            };

            var pathAnim = function(path, dir) {
            switch(dir) {
                case 0:
                    path.transition()
                        .duration(500)
                        .ease('bounce')
                        .attr('d', d3.svg.arc()
                            .innerRadius((radius-100))
                            .outerRadius(radius-50)
                        );
                    break;

                case 1:
                    path.transition()
                        .attr('d', d3.svg.arc()
                            .innerRadius((radius-100))
                            .outerRadius((radius-50) * 1.08)
                        );
                    break;
            }
        }  

Answer №1

Below is the solution you are seeking:

var data = [{
    label: 'Star Wars',
    instances: 207
}, {
    label: 'Lost In Space',
    instances: 3
}, {
    label: 'the Boston Pops',
    instances: 20
}, {
    label: 'Indiana Jones',
    instances: 150
}, {
    label: 'Harry Potter',
    instances: 75
}, {
    label: 'Jaws',
    instances: 5
}, {
    label: 'Lincoln',
    instances: 1
}];

svg = d3.select("svg");
canvas = d3.select("#canvas");
art = d3.select("#art");
labels = d3.select("#labels");

canvas.append("circle")
    .attr('cx', 0)
    .attr('cy', 0)
    .attr('fill', 'pink')
    .attr('r', 48);
canvas.append("text")
    .attr("text-anchor", "middle")
    .attr('font-size', '12px')
    .attr('y', 0)
    .attr('id', 'center-text')
    .text('TEST FOR A LONG VERY TEXT');

// Wrap text in a rectangle.
d3plus.textwrap()
    .container(d3.select("#center-text"))
    .resize(true)
    .draw();

jhw_pie = d3.layout.pie()
jhw_pie.value(function(d, i) {
    return d.instances;
});

cDim = {
    height: 500,
    width: 500,
    innerRadius: 50,
    outerRadius: 150,
    labelRadius: 175
}

svg.attr({
    height: cDim.height,
    width: cDim.width
});

canvas.attr("transform", "translate(" + (cDim.width / 2) + "," + (cDim.width / 2) + ")");

pied_data = jhw_pie(data);

pied_arc = d3.svg.arc()
    .innerRadius(50)
    .outerRadius(150);


const eventObj = {
    mouseover: function(d, i, j) {
        d3.select('#center-text').text(d.data.label);
        d3plus.textwrap()
            .container(d3.select("#center-text"))
            .resize(true)
            .draw();
    },
    mouseout: function(d, i, j) {
        d3.select('#center-text').text('');
        d3plus.textwrap()
            .container(d3.select("#center-text"))
            .resize(true)
            .draw();
    },


    click: function(d, i, j) {

    }
};

enteringArcs = art.selectAll(".wedge").data(pied_data).enter();

enteringArcs.append("path")
    .attr("class", "wedge")
    .attr("d", pied_arc)
    .on('click', (d) => {
        eventObj.click(d)
    })
    .on('mouseover', (d) => {
        eventObj.mouseover(d)
    })
    .on('mouseout', (d) => {
        eventObj.mouseout(d)
    })
    .style("fill", function(d, i) {
        return color(i);
    });

enteringLabels = labels.selectAll(".label").data(pied_data).enter();
labelGroups = enteringLabels.append("g").attr("class", "label");

textLines = labelGroups.append("line").attr({...});
textLabels = labelGroups.append("text").attr({...}).text(function(d) {...});

alpha = 0.5;
spacing = 12;

function relax() {
    // Function code here
}

relax();
.label-text {
    alignment-baseline: middle;
    font-size: 12px;
    font-family: arial,helvetica,"sans-serif";
    fill: #393939;
}
.label-line {
    stroke-width: 1;
    stroke: #393939;
}
.label-circle {
    fill: #393939;
}
<svg>
    <g id="canvas">
    <g id="art" />
    <g id="labels" /></g>
</svg>

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

Frequently, cypress encounters difficulty accessing the /auth page and struggles to locate the necessary id or class

When trying to navigate to the /auth path and log in with Cypress, I am using the following code: Cypress.Commands.add('login', (email, password) => { cy.get('.auth').find('.login').should(($login) => { expect($log ...

Formatting Date and Time in the Gridview of my Asp.net Application

I have been using this format to display the date and time in a grid. The issue I am facing is that I cannot retrieve the exact HH:MM from the database. Even though the database shows 11:11, my grid is displaying 11:03 instead. Here is the value stored in ...

"Uncaught Error: Unable to retrieve null properties" encountered while utilizing regex match in cheerio web scraping

Extracting text from brackets in HTML using regex: <dl class="ooa-1o0axny ev7e6t84"> <dd class="ooa-16w655c ev7e6t83"> <p class="ooa-gmxnzj">Cekcyn (Kujawsko-pomorskie)</p> </dd> <dd class="ooa-16w655c ev7e6t ...

What is the best way to display values from a Localstorage array in a tabular format using a looping structure

I have set up a local storage key 'fsubs' to store form submissions as an array. Here is how I am doing it: var fsubs = JSON.parse(localStorage.getItem('fsubs') || "[]"); var fcodes = {"barcodeno" : this.form.value.barcode, "reelno" : ...

When the down key is pressed in a textarea, choose the list item

I have HTML similar to the following <div class="row"> <textarea id="txtArea" ng-model="input" ng-change="handleOnChange(input);getSearchField(input);" ng-click="search(input)" ng-focus="search(input);" ...

Is the jquery autocomeplete plugin malfunctioning when using numbers in the input?

I encountered a requirement to display stock number suggestions within a search box. To achieve this, I decided to implement the Jquery autocomplete plugin. Through an ajax call to a function in my cfc, I was able to retrieve all the stock numbers and stor ...

The Angular model finally refreshes its values after a console.log() is executed

UPDATE After further investigation, I discovered that the issue was not related to Angular itself, but rather a mistake in the update function within the node server controller. I have provided the fix below for reference, and decided to keep this questio ...

Ensuring that a group of items adhere to a specific guideline using JavaScript promises

I need to search through a series of titles that follow the format: <div class='items'> * Some | Text * </div> or <div class='items'> * Some more | Text * </div> There are multiple blocks on the page wit ...

Creating a range using v-for directive in Vue

For example: range(3, 5) -> [3, 4] range(5, 10) -> [5, 6, 7, 8, 9] I am aware that we can generate range(1, x) using v-for, so I decided to experiment with it like this: // To achieve the numbers in range(5, 10), I set (10 - 5) on `v-for` // and t ...

Unable to locate module - relative file path

I'm currently running a test with the following code and encountering an error message: Failed: cannot find module '../page/home_page.js The main page consists of: describe("login to website",function(){ var employeeId; var employee ...

What are the steps for utilizing JSON data retrieved from an ajax response?

After successfully making an ajax request and receiving JSON data, I am struggling with how to use it effectively. The response I am getting looks like this: [{ "id": "5", "reviewID": "2389", "serviceID": "50707", "title": "well d ...

Issue: Failed to locate module @angular/core

When attempting to run an Angular 4 application, I consistently encounter the following error: ERROR in Could not resolve module @angular/core There are no additional errors present. There are no dependency issues whatsoever as @angular/core is located i ...

To include a Material Icon in your React-Toastify notification

This is an example of code located in a specific folder. While trying to incorporate a material Icon, an error has been encountered. 'React' must be in scope when using JSX import { toast } from 'react-toastify'; import ErrorIcon from ...

Adjust the translateX value and element size based on either the parent element's size or the window's dimensions

Is this question specific enough to relate to others' problems? My issue involves two elements, a child and a parent, with the child element rotating around the parent using CSS animations. <div class="planet"> <div class="moon"></di ...

Reactjs, encountering a hitch in utilizing material UI: Incompatible hook call detected

As a newcomer to React, I decided to incorporate Material UI components into my project. After installing the components locally using npm install and importing them into my project, I encountered an error when trying to run start: Error: Invalid hook call ...

What are the ways to utilize vue-i18n setup within and beyond Vue components when working with Quasar?

Hello, fellow developers. I am currently working on implementing internationalization in Quasar, using Vue 3 (Composition API) and vue-i18n. My goal is to make internationalization available throughout the entire application, not just within Vue components ...

Vue: Implement out-in transition where the incoming element appears before the outgoing element has completely disappeared

Check out my code on Codepen: here In this scenario, I have set up two div elements: Block 1 and Block 2. The functionality I am looking for is when a button is clicked, Block 1 smoothly translates to the left until it goes out of view. Once that happens ...

The error message "TypeError ".deploy" is not a function in your Hardhat environment."

Currently, I'm in the process of developing a page for minting NFTs called astro-mint. To move forward, I need to deploy my contract using hardhat. However, when I execute this command npx hardhat run scripts/deploy.js --network dexitTestnet An erro ...

Introducing the new and improved SweetAlert 2.0, the ultimate solution for

I am currently utilizing SweetAlert2.0, known as "This One" <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script> It is functioning properly; however, I would like to display a table, div, or HTML element within this swe ...

Is there a way in JavaScript or jQuery to display text from an array and switch to the next piece of text in the array with the click of a button?

I currently have an array containing 13 items, all of which are text. To display the text from the array, I am using: document.write(arrayname["0"]); However, I would like to implement a functionality where users can click a button to fade out the curren ...