แสดงข้อมูลการวางเมาส์ของวงกลม


162

ฉันมีชุดข้อมูลที่ฉันวางแผนในการกระจาย เมื่อฉันวางเมาส์บนวงกลมใดวงหนึ่งฉันต้องการให้ป๊อปอัปมีข้อมูล (เช่นค่า x, y อาจจะมากกว่า) นี่คือสิ่งที่ฉันพยายามใช้:

vis.selectAll("circle")
   .data(datafiltered).enter().append("svg:circle")
   .attr("cx", function(d) { return x(d.x);})
   .attr("cy", function(d) {return y(d.y)})
   .attr("fill", "red").attr("r", 15)
   .on("mouseover", function() {
        d3.select(this).enter().append("text")
            .text(function(d) {return d.x;})
            .attr("x", function(d) {return x(d.x);})
            .attr("y", function (d) {return y(d.y);}); });

ฉันสงสัยว่าฉันจะต้องให้ข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลที่จะป้อน?


1
ฉันเคยลองแล้ว: vis.selectAll ("วงกลม") แต่ละอัน (ฟังก์ชั่น (d) {vis.append ("svg: ข้อความ"). attr ("x", dx) .attr ("y", dy) .text (ฟังก์ชัน (d) {return dx;});}); ไม่มีประโยชน์อนิจจา
ScottieB

คำตอบ:


181

ฉันคิดว่าสิ่งที่คุณต้องการคือคำแนะนำเครื่องมือ วิธีที่ง่ายที่สุดในการทำเช่นนี้คือการผนวกsvg:titleองค์ประกอบให้กับแต่ละแวดวงเนื่องจากเบราว์เซอร์จะดูแลการแสดงคำแนะนำเครื่องมือและคุณไม่จำเป็นต้องใช้ mousehandler รหัสจะเป็นสิ่งที่ต้องการ

vis.selectAll("circle")
   .data(datafiltered).enter().append("svg:circle")
   ...
   .append("svg:title")
   .text(function(d) { return d.x; });

หากคุณต้องการคำแนะนำเครื่องมือนักเล่นคุณสามารถใช้คำแนะนำที่ยุ่งยาก ดูที่นี่สำหรับตัวอย่าง


3
ฉันชอบมึนเมา ปัญหาเดียวของฉันตอนนี้คือมันชี้ไปที่มุมซ้ายบนของวงกลมแทนที่จะเป็นขอบเหมือนในการสาธิตนั้น ฉันไม่พบเหตุผลที่ชัดเจนว่าทำไม jsfiddle.net/scottieb/JwaaV (มึนเมาที่ก้นมาก)
ScottieB

jsfiddle นั้นไม่มีคำแนะนำเครื่องมือใด ๆ เลยเหรอ?
Lars Kotthoff

คุณสามารถลองเพิ่มคำแนะนำเครื่องมือลงsvg:gในวงกลมที่ซ้อนทับกับวงกลมจริง แต่ให้ความกว้างและความสูงเป็นศูนย์ ขณะนี้กำลังใช้กล่องขอบเขตและวางคำแนะนำเครื่องมือไว้ที่ขอบ การเล่นกับตัวเลือกต่างๆของ Tipsy อาจช่วยได้เช่นกัน
Lars Kotthoff

1
ดูเหมือนจะไม่ทำงานอีกต่อไป นอกจากนี้ฉันพบตัวอย่างโดยใช้ svg: title ซึ่งล้มเหลว: bl.ocks.org/ilyabo/1339996
nos

1
@nos ทำงานให้ฉัน
Lars Kotthoff

145

วิธีที่ดีในการสร้างคำแนะนำเครื่องมือที่นี่: ตัวอย่างเครื่องมือคำแนะนำ D3 แบบง่าย

คุณต้องผนวก div

var tooltip = d3.select("body")
    .append("div")
    .style("position", "absolute")
    .style("z-index", "10")
    .style("visibility", "hidden")
    .text("a simple tooltip");

จากนั้นคุณสามารถสลับโดยใช้

.on("mouseover", function(){return tooltip.style("visibility", "visible");})
.on("mousemove", function(){return tooltip.style("top",
    (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});

d3.event.pageX/ d3.event.pageYคือพิกัดเมาส์ปัจจุบัน

หากคุณต้องการเปลี่ยนข้อความที่คุณสามารถใช้ได้ tooltip.text("my tooltip text");

ตัวอย่างการทำงาน


4
คุณสามารถผูกข้อมูลกับคำแนะนำเครื่องมือนี้ได้หรือไม่
Jorge Leitao

2
Afaik คุณสามารถผูกข้อมูลกับทุกองค์ประกอบ DOM
Pwdr

หากต้องการผูกข้อมูลกับสิ่งนี้เพียงเพิ่ม d ในวงเล็บดังนี้: function (d) {... และเปลี่ยนข้อความเป็นสิ่งที่คุณต้องการ ตัวอย่างเช่นสมมติว่าคุณมีชื่อที่จะเป็น: tooltip.text (d.name):
thatOneGuy

39

มีห้องสมุดที่ยอดเยี่ยมสำหรับการทำสิ่งที่ฉันเพิ่งค้นพบ มันใช้งานง่ายและผลลัพธ์ค่อนข้างเรียบร้อย: d3-tip

คุณสามารถดูตัวอย่างได้ที่นี่ :

ป้อนคำอธิบายรูปภาพที่นี่

โดยทั่วไปสิ่งที่คุณต้องทำคือดาวน์โหลด ( index.js ) รวมถึงสคริปต์:

<script src="index.js"></script>

จากนั้นทำตามคำแนะนำจากที่นี่ (ลิงก์เดียวกับตัวอย่าง)

แต่สำหรับโค้ดของคุณมันจะเป็นดังนี้:

กำหนดวิธีการ:

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
  })

สร้าง svg ของคุณ (ตามที่คุณทำอยู่แล้ว)

var svg = ...

เรียกวิธีการ:

svg.call(tip);

เพิ่มเคล็ดลับกับวัตถุของคุณ:

vis.selectAll("circle")
   .data(datafiltered).enter().append("svg:circle")
...
   .on('mouseover', tip.show)
   .on('mouseout', tip.hide)

อย่าลืมเพิ่ม CSS:

<style>
.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
</style>

2
d3-tipล่าสุดรองรับ d3v4 ได้ดี ไม่ชัดเจนถ้าคุณใช้ google แต่มันใช้งานได้ดีสำหรับฉันด้วย d3v4
moodboom

6

คุณสามารถส่งผ่านข้อมูลที่จะใช้ใน mouseover เช่นนี้ - เหตุการณ์ mouseover ใช้ฟังก์ชันที่มีข้อมูลentered ของคุณก่อนหน้านี้เป็นอาร์กิวเมนต์ (และดัชนีเป็นอาร์กิวเมนต์ที่สอง) ดังนั้นคุณไม่จำเป็นต้องใช้enter()ครั้งที่สองอีก

vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
.attr("cx", function(d) { return x(d.x);})
.attr("cy", function(d) {return y(d.y)})
.attr("fill", "red").attr("r", 15)
.on("mouseover", function(d,i) {
    d3.select(this).append("text")
        .text( d.x)
        .attr("x", x(d.x))
        .attr("y", y(d.y)); 
});

ขอบคุณ ฉันจำเป็นต้องใช้d3.select(this)เพื่อปรับเปลี่ยนรูปร่างและไม่รู้วิธีรับอินสแตนซ์ในการป้อน / อัปเดต
เทอร์โบ

คุณกำลังใช้ฟังก์ชั่นบางอย่าง x () และ y () ที่ไม่ได้กำหนดไว้ในรหัสของคุณ ฉันคิดว่าสามารถลบออกได้
Robert

พวกเขาได้รับใน OP
danimal

5

ตัวอย่างย่อนี้แสดงวิธีทั่วไปในการสร้างคำแนะนำเครื่องมือแบบกำหนดเองใน d3

var w = 500;
var h = 150;

var dataset = [5, 10, 15, 20, 25];

// firstly we create div element that we can use as
// tooltip container, it have absolute position and
// visibility: hidden by default

var tooltip = d3.select("body")
  .append("div")
  .attr('class', 'tooltip');

var svg = d3.select("body")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

// here we add some circles on the page

var circles = svg.selectAll("circle")
  .data(dataset)
  .enter()
  .append("circle");

circles.attr("cx", function(d, i) {
    return (i * 50) + 25;
  })
  .attr("cy", h / 2)
  .attr("r", function(d) {
    return d;
  })
  
  // we define "mouseover" handler, here we change tooltip
  // visibility to "visible" and add appropriate test
  
  .on("mouseover", function(d) {
    return tooltip.style("visibility", "visible").text('radius = ' + d);
  })
  
  // we move tooltip during of "mousemove"
  
  .on("mousemove", function() {
    return tooltip.style("top", (event.pageY - 30) + "px")
      .style("left", event.pageX + "px");
  })
  
  // we hide our tooltip on "mouseout"
  
  .on("mouseout", function() {
    return tooltip.style("visibility", "hidden");
  });
.tooltip {
    position: absolute;
    z-index: 10;
    visibility: hidden;
    background-color: lightblue;
    text-align: center;
    padding: 4px;
    border-radius: 4px;
    font-weight: bold;
    color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>


หากใครต้องการคำแนะนำเครื่องมือเพื่อย้ายสัมพันธ์กับตำแหน่งของวัตถุ เช่นเดียวกับในกรณีของกราฟต้นไม้ คุณอาจต้องการใช้return tooltip.style("top", (d.x + 40) + "px") .style("left", (d.y + 80) + "px");ใน'mousemove'แอตทริบิวต์ d.xจะช่วยย้ายเคล็ดลับเครื่องมือเทียบกับวัตถุที่ไม่ได้ทั้งหน้า
จันทรา Kanth
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.