簡體   English   中英

在D3堆疊面積圖中顯示div內的工具提示

[英]Show the tooltip inside a div in a D3 stacked area chart

 <!DOCTYPE html> <html> <head> <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .x.axis path { display: none; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } </style> </head> <body> <script> var myData = "date New York San Francisco Austin\\n\\ 20111001 63.4 62.7 72.2\\n\\ 20111002 58.0 59.9 67.7\\n\\ 20111003 53.3 59.1 69.4\\n\\ 20111004 55.7 58.8 68.0\\n\\ 20111005 64.2 58.7 72.4\\n\\ 20111006 58.8 57.0 77.0\\n\\ 20111007 57.9 56.7 82.3\\n\\ 20111008 61.8 56.8 78.9\\n\\ 20111009 69.3 56.7 68.8\\n\\ 20111010 71.2 60.1 68.7\\n\\ 20111011 68.7 61.1 70.3\\n\\ 20111012 61.8 61.5 75.3\\n\\ 20111013 63.0 64.3 76.6\\n\\ 20111014 66.9 67.1 66.6\\n\\ 20111015 61.7 64.6 68.0\\n\\ 20111016 61.8 61.6 70.6\\n\\ 20111017 62.8 61.1 71.1\\n\\ 20111018 60.8 59.2 70.0\\n\\ 20111019 62.1 58.9 61.6\\n\\ 20111020 65.1 57.2 57.4\\n\\ 20111021 55.6 56.4 64.3\\n\\ 20111022 54.4 60.7 72.4\\n"; var margin = { top: 20, right: 80, bottom: 30, left: 50 }, width = 500 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y%m%d").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var color = d3.scale.category20(); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .interpolate("basis") .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.temperature); }); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var data = d3.tsv.parse(myData); color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; })); data.forEach(function(d) { d.date = parseDate(d.date); }); var cities = color.domain().map(function(name) { return { name: name, values: data.map(function(d) { return { date: d.date, temperature: +d[name] }; }) }; }); x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([ d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }), d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); }) ]); var legend = svg.selectAll('g') .data(cities) .enter() .append('g') .attr('class', 'legend'); legend.append('rect') .attr('x', width - 20) .attr('y', function(d, i) { return i * 20; }) .attr('width', 10) .attr('height', 10) .style('fill', function(d) { return color(d.name); }); legend.append('text') .attr('x', width - 8) .attr('y', function(d, i) { return (i * 20) + 9; }) .text(function(d) { return d.name; }); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Temperature (ºF)"); var city = svg.selectAll(".city") .data(cities) .enter().append("g") .attr("class", "city"); city.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", function(d) { return color(d.name); }); city.append("text") .datum(function(d) { return { name: d.name, value: d.values[d.values.length - 1] }; }) .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; }) .attr("x", 3) .attr("dy", ".35em") .text(function(d) { return d.name; }); var mouseG = svg.append("g") .attr("class", "mouse-over-effects"); mouseG.append("path") // this is the black vertical line to follow mouse .attr("class", "mouse-line") .style("stroke", "black") .style("stroke-width", "1px") .style("opacity", "0"); var lines = document.getElementsByClassName('line'); var mousePerLine = mouseG.selectAll('.mouse-per-line') .data(cities) .enter() .append("g") .attr("class", "mouse-per-line"); mousePerLine.append("circle") .attr("r", 7) .style("stroke", function(d) { return color(d.name); }) .style("fill", "none") .style("stroke-width", "1px") .style("opacity", "0"); mousePerLine.append("text") .attr("transform", "translate(10,3)"); mouseG.append('svg:rect') // append a rect to catch mouse movements on canvas .attr('width', width) // can't catch mouse events on ag element .attr('height', height) .attr('fill', 'none') .attr('pointer-events', 'all') .on('mouseout', function() { // on mouse out hide line, circles and text d3.select(".mouse-line") .style("opacity", "0"); d3.selectAll(".mouse-per-line circle") .style("opacity", "0"); d3.selectAll(".mouse-per-line text") .style("opacity", "0"); }) .on('mouseover', function() { // on mouse in show line, circles and text d3.select(".mouse-line") .style("opacity", "1"); d3.selectAll(".mouse-per-line circle") .style("opacity", "1"); d3.selectAll(".mouse-per-line text") .style("opacity", "1"); }) .on('mousemove', function() { // mouse moving over canvas var mouse = d3.mouse(this); d3.select(".mouse-line") .attr("d", function() { var d = "M" + mouse[0] + "," + height; d += " " + mouse[0] + "," + 0; return d; }); d3.selectAll(".mouse-per-line") .attr("transform", function(d, i) { console.log(width / mouse[0]) var xDate = x.invert(mouse[0]), bisect = d3.bisector(function(d) { return d.date; }).right; idx = bisect(d.values, xDate); var beginning = 0, end = lines[i].getTotalLength(), target = null; while (true) { target = Math.floor((beginning + end) / 2); pos = lines[i].getPointAtLength(target); if ((target === end || target === beginning) && pos.x !== mouse[0]) { break; } if (pos.x > mouse[0]) end = target; else if (pos.x < mouse[0]) beginning = target; else break; //position found } d3.select(this).select('text') .text(y.invert(pos.y).toFixed(2)); return "translate(" + mouse[0] + "," + pos.y + ")"; }); }); </script> </body> </html> 

你好。 我是D3的新手,如果我問一些愚蠢的事情,請原諒我。 我一直試圖在矩形div內懸停顯示堆積面積圖的工具提示,而不是在每條線旁邊顯示。 到目前為止,我已經理解並實現了這一點,但是我無法在工具提示中添加一個矩形div來顯示我將數據懸停在其內部的情況。 請幫我。 感謝您的任何幫助。

 <!DOCTYPE html> <html> <head> <script data-require="d3@3.5.3" data-semver="3.5.3" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .x.axis path { display: none; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } </style> </head> <body> <script> var myData = "date New York San Francisco Austin\\n\\ 20111001 63.4 62.7 72.2\\n\\ 20111002 58.0 59.9 67.7\\n\\ 20111003 53.3 59.1 69.4\\n\\ 20111004 55.7 58.8 68.0\\n\\ 20111005 64.2 58.7 72.4\\n\\ 20111006 58.8 57.0 77.0\\n\\ 20111007 57.9 56.7 82.3\\n\\ 20111008 61.8 56.8 78.9\\n\\ 20111009 69.3 56.7 68.8\\n\\ 20111010 71.2 60.1 68.7\\n\\ 20111011 68.7 61.1 70.3\\n\\ 20111012 61.8 61.5 75.3\\n\\ 20111013 63.0 64.3 76.6\\n\\ 20111014 66.9 67.1 66.6\\n\\ 20111015 61.7 64.6 68.0\\n\\ 20111016 61.8 61.6 70.6\\n\\ 20111017 62.8 61.1 71.1\\n\\ 20111018 60.8 59.2 70.0\\n\\ 20111019 62.1 58.9 61.6\\n\\ 20111020 65.1 57.2 57.4\\n\\ 20111021 55.6 56.4 64.3\\n\\ 20111022 54.4 60.7 72.4\\n"; var margin = { top: 20, right: 80, bottom: 30, left: 50 }, width = 500 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y%m%d").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var color = d3.scale.category20(); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .interpolate("basis") .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.temperature); }); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var data = d3.tsv.parse(myData); color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; })); data.forEach(function(d) { d.date = parseDate(d.date); }); var cities = color.domain().map(function(name) { return { name: name, values: data.map(function(d) { return { date: d.date, temperature: +d[name] }; }) }; }); x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([ d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }), d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); }) ]); var legend = svg.selectAll('g') .data(cities) .enter() .append('g') .attr('class', 'legend'); legend.append('rect') .attr('x', width - 20) .attr('y', function(d, i) { return i * 20; }) .attr('width', 10) .attr('height', 10) .style('fill', function(d) { return color(d.name); }); legend.append('text') .attr('x', width - 8) .attr('y', function(d, i) { return (i * 20) + 9; }) .text(function(d) { return d.name; }); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Temperature (ºF)"); var city = svg.selectAll(".city") .data(cities) .enter().append("g") .attr("class", "city"); city.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", function(d) { return color(d.name); }); city.append("text") .datum(function(d) { return { name: d.name, value: d.values[d.values.length - 1] }; }) .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; }) .attr("x", 3) .attr("dy", ".35em") .text(function(d) { return d.name; }); var mouseG = svg.append("g") .attr("class", "mouse-over-effects"); mouseG.append("path") // this is the black vertical line to follow mouse .attr("class", "mouse-line") .style("stroke", "black") .style("stroke-width", "1px") .style("opacity", "0"); var lines = document.getElementsByClassName('line'); var mousePerLine = mouseG.selectAll('.mouse-per-line') .data(cities) .enter() .append("g") .attr("class", "mouse-per-line"); mousePerLine.append("rect") .attr("width", width / 2) .attr("height", 30) .style("padding", "5px") .style("stroke", function(d) { return color(d.name); }) .style("fill", function(d) { return color(d.name); }) .style("stroke-width", "1px") .style("opacity", "0") .attr('x', 10); mousePerLine.append("circle") .attr("r", 5) .style("stroke", function(d) { return color(d.name); }) .style("fill", function(d) { return color(d.name); }) .style("stroke-width", "1px") .style("opacity", "0"); mousePerLine.append("text") .attr("transform", "translate(15,13)"); mouseG.append('svg:rect') // append a rect to catch mouse movements on canvas .attr('width', width) // can't catch mouse events on ag element .attr('height', height) .attr('fill', 'none') .attr('pointer-events', 'all') .on('mouseout', function() { // on mouse out hide line, circles and text d3.select(".mouse-line") .style("opacity", "0"); d3.selectAll(".mouse-per-line rect") .style("opacity", "0"); d3.selectAll(".mouse-per-line circle") .style("opacity", "0"); d3.selectAll(".mouse-per-line text") .style("opacity", "0"); }) .on('mouseover', function() { // on mouse in show line, circles and text d3.select(".mouse-line") .style("opacity", "1"); d3.selectAll(".mouse-per-line rect") .style("opacity", "0.5"); d3.selectAll(".mouse-per-line circle") .style("opacity", "1"); d3.selectAll(".mouse-per-line text") .style("opacity", "1"); }) .on('mousemove', function() { // mouse moving over canvas var mouse = d3.mouse(this); d3.select(".mouse-line") .attr("d", function() { var d = "M" + mouse[0] + "," + height; d += " " + mouse[0] + "," + 0; return d; }); d3.selectAll(".mouse-per-line") .attr("transform", function(d, i) { console.log(width / mouse[0]) var xDate = x.invert(mouse[0]), bisect = d3.bisector(function(d) { return d.date; }).right; idx = bisect(d.values, xDate); var beginning = 0, end = lines[i].getTotalLength(), target = null; while (true) { target = Math.floor((beginning + end) / 2); pos = lines[i].getPointAtLength(target); if ((target === end || target === beginning) && pos.x !== mouse[0]) { break; } if (pos.x > mouse[0]) end = target; else if (pos.x < mouse[0]) beginning = target; else break; //position found } d3.select(this).select('text') .text(y.invert(pos.y).toFixed(2)); return "translate(" + mouse[0] + "," + pos.y + ")"; }); }); </script> </body> </html> 

 <!DOCTYPE html> <html> <head> <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .x.axis path { display: none; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } </style> </head> <body> <script> var myData = "date New York San Francisco Austin\\n\\ 20111001 63.4 62.7 72.2\\n\\ 20111002 58.0 59.9 67.7\\n\\ 20111003 53.3 59.1 69.4\\n\\ 20111004 55.7 58.8 68.0\\n\\ 20111005 64.2 58.7 72.4\\n\\ 20111006 58.8 57.0 77.0\\n\\ 20111007 57.9 56.7 82.3\\n\\ 20111008 61.8 56.8 78.9\\n\\ 20111009 69.3 56.7 68.8\\n\\ 20111010 71.2 60.1 68.7\\n\\ 20111011 68.7 61.1 70.3\\n\\ 20111012 61.8 61.5 75.3\\n\\ 20111013 63.0 64.3 76.6\\n\\ 20111014 66.9 67.1 66.6\\n\\ 20111015 61.7 64.6 68.0\\n\\ 20111016 61.8 61.6 70.6\\n\\ 20111017 62.8 61.1 71.1\\n\\ 20111018 60.8 59.2 70.0\\n\\ 20111019 62.1 58.9 61.6\\n\\ 20111020 65.1 57.2 57.4\\n\\ 20111021 55.6 56.4 64.3\\n\\ 20111022 54.4 60.7 72.4\\n"; var margin = { top: 20, right: 80, bottom: 30, left: 50 }, width = 500 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y%m%d").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var color = d3.scale.category20(); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .interpolate("basis") .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.temperature); }); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var data = d3.tsv.parse(myData); color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; })); data.forEach(function(d) { d.date = parseDate(d.date); }); var cities = color.domain().map(function(name) { return { name: name, values: data.map(function(d) { return { date: d.date, temperature: +d[name] }; }) }; }); x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([ d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }), d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); }) ]); var legend = svg.selectAll('g') .data(cities) .enter() .append('g') .attr('class', 'legend'); legend.append('rect') .attr('x', width - 20) .attr('y', function(d, i) { return i * 20; }) .attr('width', 10) .attr('height', 10) .style('fill', function(d) { return color(d.name); }); legend.append('text') .attr('x', width - 8) .attr('y', function(d, i) { return (i * 20) + 9; }) .text(function(d) { return d.name; }); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Temperature (ºF)"); var city = svg.selectAll(".city") .data(cities) .enter().append("g") .attr("class", "city"); city.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", function(d) { return color(d.name); }); city.append("text") .datum(function(d) { return { name: d.name, value: d.values[d.values.length - 1] }; }) .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; }) .attr("x", 3) .attr("dy", ".35em") .text(function(d) { return d.name; }); var mouseG = svg.append("g") .attr("class", "mouse-over-effects"); mouseG.append("path") // this is the black vertical line to follow mouse .attr("class", "mouse-line") .style("stroke", "black") .style("stroke-width", "1px") .style("opacity", "0"); var lines = document.getElementsByClassName('line'); var mousePerLine = mouseG.selectAll('.mouse-per-line') .data(cities) .enter() .append("g") .attr("class", "mouse-per-line"); mousePerLine.append("circle") .attr("r", 7) .style("stroke", function(d) { return color(d.name); }) .style("fill", "none") .style("stroke-width", "1px") .style("opacity", "0"); mousePerLine.append("text") .attr("transform", "translate(10,3)"); mouseG.append('svg:rect') // append a rect to catch mouse movements on canvas .attr('width', width) // can't catch mouse events on ag element .attr('height', height) .attr('fill', 'none') .attr('pointer-events', 'all') .on('mouseout', function() { // on mouse out hide line, circles and text d3.select(".mouse-line") .style("opacity", "0"); d3.selectAll(".mouse-per-line circle") .style("opacity", "0"); d3.selectAll(".mouse-per-line text") .style("opacity", "0"); }) .on('mouseover', function() { // on mouse in show line, circles and text d3.select(".mouse-line") .style("opacity", "1"); d3.selectAll(".mouse-per-line circle") .style("opacity", "1"); d3.selectAll(".mouse-per-line text") .style("opacity", "1"); }) .on('mousemove', function() { // mouse moving over canvas var mouse = d3.mouse(this); d3.select(".mouse-line") .attr("d", function() { var d = "M" + mouse[0] + "," + height; d += " " + mouse[0] + "," + 0; return d; }); d3.selectAll(".mouse-per-line") .attr("transform", function(d, i) { console.log(width / mouse[0]) var xDate = x.invert(mouse[0]), bisect = d3.bisector(function(d) { return d.date; }).right; idx = bisect(d.values, xDate); var beginning = 0, end = lines[i].getTotalLength(), target = null; while (true) { target = Math.floor((beginning + end) / 2); pos = lines[i].getPointAtLength(target); if ((target === end || target === beginning) && pos.x !== mouse[0]) { break; } if (pos.x > mouse[0]) end = target; else if (pos.x < mouse[0]) beginning = target; else break; //position found } d3.select(this).select('text') .text(y.invert(pos.y).toFixed(2)); return "translate(" + mouse[0] + "," + pos.y + ")"; }); }); </script> </body> </html> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM