Linking data to each element using an HTML text field

I am trying to implement annotation functionality on my spread that I created with d3.js v3. When I click on each data point, a text box appears where I enter the text. Once the text has been added, it will appear as a tooltip for that particular data point. The way I do this is:

eventGroup.select("circle")
    .attr("class", "dot")
    .attr("r", 4)
    .attr("cx", 10)
    .attr("cy", 10)
    .attr("fill", function(d) {
        return d.evtColor ? d.evtColor : "#229ae5";
    })
    .attr("stroke", function(d) {
        return d.evtColor ? d.evtColor : "#229ae5";
    })
    .attr("stroke-width", 2)
    .on("contextmenu", function() {
        var position = d3.mouse(this.parentNode);
        d3.select("#context-menu")
            .style("position", "absolute")
            .style("left", (d3.event.pageX - 220) + "px")
            .style("top", (d3.event.pageY - 70) + "px")
            .style("display", "inline-block")
            .on("click", function() {
                d3.select("#context-menu").style("display", "none");
                d3.select("#annotateBox")
                    .style("position", "absolute")
                    .style("left", (d3.event.pageX - 220) + "px")
                    .style("top", (d3.event.pageY - 70) + "px")
                    .style("display", "inline-block");
            });
    });

And in the HTML file, I define the button addAnnotationand textarea, where I will add the text:

<ul id="context-menu" class="menu" style="display:none;">
    <li class="addAnnotation"><a href="">Add Annotation</a></li>
</ul>
<div id="annotateBox" style="display:none;">
   <div class="annotateInput" style="display:table-caption">
        <textarea rows="3" cols="50" maxlength="100" style="color:black" ng-model="vm.annotateText" autofocus></textarea>
        <button type="button" class="btn btn-primary pull-right" ng-click="vm.removeButton()">Done</button>
    </div>
</div>

, , - , , , , , . , , . , , .

+4
1

:

  • ;
  • ( v4, ).

, D3, , . , v3, , :

1:

, , . , D3 ( DDD) Data-Driven Documents.

: , , , d ( "datum" ):

selection.on("contextmenu", function(d) {
//first argument here ---------------^

, textArea:

d3.select("textarea").node().value = d.textArea || "";
d3.select("button").on("click", function() {
    d.textArea = d3.select("textarea").node().value;
});

: datum .

, . , - "done". , : , .

var svg = d3.select("svg");
var color = d3.scaleOrdinal(d3.schemeCategory10);
var data = d3.range(5).map(function(d) {
  return {
    name: "foo"
  }
});
var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("r", 15)
  .attr("cy", 50)
  .attr("cx", function(_, i) {
    return 50 + 50 * i
  })
  .style("fill", function(_, i){
    return color(i);
  });
circles.on("contextmenu", function(d) {
  d3.event.preventDefault();
  d3.select("#annotateBox")
    .style("position", "absolute")
    .style("left", (d3.event.pageX - 50) + "px")
    .style("top", (d3.event.pageY + 20) + "px")
    .style("display", "inline-block");
  d3.select("textarea").node().value = d.textArea || "";
  d3.select("button").on("click", function() {
    d.textArea = d3.select("textarea").node().value;
  })
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="annotateBox" style="display:none;">
  <div class="annotateInput" style="display:table-caption">
    <textarea rows="3" cols="50" maxlength="100" style="color:black" autofocus></textarea>
    <button type="button">Done</button>
  </div>
</div>
<svg></svg>
Hide result

D3 v3, ( v4 , , ). , DOM, :

2:

D3 v4 . , ...

var local = d3.local();

... :

var thisCircle = this;
d3.select("textarea").node().value = local.get(thisCircle) || "";
d3.select("button").on("click", function() {
    local.set(thisCircle, d3.select("textarea").node().value);
});

:

var svg = d3.select("svg");
var color = d3.scaleOrdinal(d3.schemeCategory10);
var local = d3.local();
var data = d3.range(5).map(function(d) {
  return {
    name: "foo"
  }
});
var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("r", 15)
  .attr("cy", 50)
  .attr("cx", function(_, i) {
    return 50 + 50 * i
  })
  .style("fill", function(_, i) {
    return color(i);
  });
circles.on("contextmenu", function(d) {
  var thisCircle = this;
  d3.event.preventDefault();
  d3.select("#annotateBox")
    .style("position", "absolute")
    .style("left", (d3.event.pageX - 50) + "px")
    .style("top", (d3.event.pageY + 20) + "px")
    .style("display", "inline-block");
  d3.select("textarea").node().value = local.get(thisCircle) || "";
  d3.select("button").on("click", function() {
    local.set(thisCircle, d3.select("textarea").node().value);
  })

});
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="annotateBox" style="display:none;">
  <div class="annotateInput" style="display:table-caption">
    <textarea rows="3" cols="50" maxlength="100" style="color:black" autofocus></textarea>
    <button type="button">Done</button>
  </div>
</div>
<svg></svg>
Hide result
+2
source

Source: https://habr.com/ru/post/1691574/


All Articles