4

I am creating a number of charts with D3, each of which is contained within a bootstrap tab element. I have no problem creating data-rich mouseovers/tooltips for the chart elements which incorporate elements of the D3.csv imported dataset. However when I create a bootstrap modal dialog that launches when a user clicks on a chart element, I get the dialog but am unable to pass D3 data to it. The base modal dialog looks like:

<div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title"></h4>
            </div>
            <div class="modal-body">
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

which is picked up in the javascript with

// open modal dialogue on click
$('#myModal').on('show.bs.modal', function(d) {
    let modalTitle = d3.selectAll("h4.modal-title");
    modalTitle.text("test");
    let modalBody = d3.selectAll(".modal-body");
    modalBody.html("Country should be: " + d.Country + "<br>" + "Operator should be: " + d.Operator);
    console.log("operator: " + d.Operator + "   Country: " + d.Country);
})

I can push text into elements of the modal dialogue but I can't access the csv array of values e.g. d.Country, d.Operator that I could with the mouseover. I suspect it is because I am not using d3.selectAll to select the #myModal ID of the dialogue but I can't seem to get it to recognise the show.bs.modal with any sort of d3.selectAll statement. Do I have to pass all the data to the modal via data-id assignments in the div as in this problem? I have tried but bootstrap doesn't appear to pick up the data when it is attached to SVG element as opposed to an HTML element.

Here is a Plunker of the problem.

SteveSong
  • 311
  • 3
  • 15

1 Answers1

3

You can do it like this:

Step1

In your mouseover function, add datum and a class for selection.

    h.append("rect")
        .style("stroke", "black")
        .style("stroke-width", "4")
        .style("fill", "none")
        .style("stroke-linecap", "round")
        .style("stroke-linejoin", "round")
        .attr("class", "infoLine info")<---add class info
        .datum(d)<---add datum to the rect.

Step2

In your click function, get datum using class info.

$('#myModal').on('show.bs.modal', function(d) {
    var d = d3.select(".info").data().pop(); <--- get the data from group having class info
    let modalTitle = d3.selectAll("h4.modal-title");
    modalTitle.text("test");
    let modalBody = d3.selectAll(".modal-body");
    modalBody.html("Country should be: " + d.Country + "<br>" + "Operator should be: " + d.Operator);
    console.log(d, "operator: " + d.Operator + "   Country: " + d.Country);
})

working code here

Cyril Cherian
  • 32,177
  • 7
  • 46
  • 55