Hiển thị dữ liệu khi di chuột qua vòng tròn


162

Tôi có một bộ dữ liệu mà tôi đang vẽ trong một phân tán. Khi tôi di chuột qua một trong các vòng tròn, tôi muốn nó xuất hiện với dữ liệu (như các giá trị x, y, có thể nhiều hơn). Đây là những gì tôi đã thử sử dụng:

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);}); });

Tôi nghi ngờ tôi cần có nhiều thông tin hơn về những dữ liệu cần nhập?


1
Tôi cũng đã thử: vis.select ALL ("circle"). Each (function (d) {vis.append ("svg: text"). Attr ("x", dx) .attr ("y", dy) .text (hàm (d) {return dx;});}); để không có than ôi.
ScottieB

Câu trả lời:


181

Tôi giả định rằng những gì bạn muốn là một tooltip. Cách dễ nhất để làm điều này là nối một svg:titlephần tử vào mỗi vòng tròn, vì trình duyệt sẽ đảm nhiệm việc hiển thị chú giải công cụ và bạn không cần sử dụng mousehandler. Mã sẽ giống như

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

Nếu bạn muốn chú giải công cụ fancier, bạn có thể sử dụng mẹo chẳng hạn. Xem ở đây cho một ví dụ.


3
Tôi thích mẹo. Vấn đề duy nhất của tôi bây giờ là nó chỉ vào góc trên bên trái của vòng tròn, thay vì cạnh như trong bản demo đó. Tôi không tìm thấy bất kỳ lý do rõ ràng tại sao. jsfiddle.net/scottieb/JwaaV ( mẹo ở dưới cùng)
ScottieB

Cái jsfiddle đó dường như không có bất kỳ chú giải công cụ nào?
Lars Kotthoff

Bạn có thể thử thêm chú giải công cụ vào một svg:glớp phủ mà bạn thực hiện với vòng tròn thực tế, nhưng cho chiều rộng và chiều cao bằng không. Hiện tại nó đang lấy hộp giới hạn và đặt tooltip ở cạnh. Chơi xung quanh với các tùy chọn của mẹo cũng có thể giúp đỡ.
Lars Kotthoff

1
Nó dường như không hoạt động nữa. Ngoài ra, tôi đã tìm thấy một ví dụ sử dụng svg: title thất bại: bl.ocks.org/ilyabo/1339996
nos

1
@nos Làm việc cho tôi.
Lars Kotthoff

144

Một cách thực sự tốt để tạo ra một chú giải công cụ được mô tả ở đây: Ví dụ về chú giải công cụ D3 đơn giản

Bạn phải nối thêm một div

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

Sau đó, bạn có thể chuyển đổi nó bằng cách sử dụng

.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 là tọa độ chuột hiện tại.

Nếu bạn muốn thay đổi văn bản, bạn có thể sử dụng tooltip.text("my tooltip text");

Ví dụ làm việc


4
Bạn có thể liên kết dữ liệu với tooltip này không?
Jorge Leitao

2
Afaik bạn có thể liên kết dữ liệu với mọi thành phần DOM.
Pwdr

để liên kết dữ liệu với điều này, chỉ cần thêm d bên trong dấu ngoặc đơn như vậy: function (d) {... và thay đổi văn bản thành những gì bạn muốn. Ví dụ: giả sử bạn có một tên, đó là: tooltip.text (d.name):
thatOneGuy

39

Có một thư viện tuyệt vời để làm điều đó mà tôi mới phát hiện ra. Cách sử dụng đơn giản và kết quả khá gọn gàng: d3-tip.

Bạn có thể xem một ví dụ ở đây :

nhập mô tả hình ảnh ở đây

Về cơ bản, tất cả những gì bạn phải làm là tải xuống ( index.js ), bao gồm tập lệnh:

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

và sau đó làm theo các hướng dẫn từ đây (cùng liên kết với ví dụ)

Nhưng đối với mã của bạn, nó sẽ là một cái gì đó như:

định nghĩa phương thức:

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>";
  })

tạo svg của bạn (như bạn đã làm)

var svg = ...

gọi phương thức:

svg.call(tip);

thêm mẹo vào đối tượng của bạn:

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

Đừng quên thêm 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 mới nhất hỗ trợ d3v4 tốt. Không rõ ràng nếu bạn google xung quanh, nhưng nó hoạt động rất tốt với tôi với d3v4.
psychboom

6

Bạn có thể truyền dữ liệu sẽ được sử dụng trong quá trình di chuột như thế này - sự kiện rê chuột sử dụng một hàm với enterdữ liệu ed trước đó của bạn làm đối số (và chỉ mục làm đối số thứ hai) vì vậy bạn không cần phải sử dụng enter()lần thứ hai.

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)); 
});

Cảm ơn. Tôi thực sự cần d3.select(this)phải sửa đổi hình dạng và không biết làm thế nào để lấy cá thể trong một lần nhập / cập nhật.
Turbo

Bạn đang sử dụng một số hàm x () và y () không được xác định trong mã của bạn. Tôi nghĩ rằng có thể được gỡ bỏ.
Robert

họ đã được đưa ra trong OP
danimal

5

Ví dụ ngắn gọn này cho thấy cách phổ biến để tạo tooltip tùy chỉnh trong 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>


Nếu bất cứ ai cần mẹo công cụ để di chuyển liên quan đến vị trí của đối tượng. Giống như trong trường hợp của một đồ thị cây. Bạn có thể muốn sử dụng return tooltip.style("top", (d.x + 40) + "px") .style("left", (d.y + 80) + "px");trong 'mousemove'thuộc tính. Ý d.xchí sẽ giúp di chuyển đầu công cụ liên quan đến đối tượng, chứ không phải toàn bộ trang
Chandra Kanth
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.