2016-07-13 3 views
0

Показать всплывающую подсказку внутри DIV в D3 сложенных гистограмме

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" 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 \t New York \t San Francisco \t Austin\n\ 
 
20111001 \t 63.4 \t 62.7 \t 72.2\n\ 
 
20111002 \t 58.0 \t 59.9 \t 67.7\n\ 
 
20111003 \t 53.3 \t 59.1 \t 69.4\n\ 
 
20111004 \t 55.7 \t 58.8 \t 68.0\n\ 
 
20111005 \t 64.2 \t 58.7 \t 72.4\n\ 
 
20111006 \t 58.8 \t 57.0 \t 77.0\n\ 
 
20111007 \t 57.9 \t 56.7 \t 82.3\n\ 
 
20111008 \t 61.8 \t 56.8 \t 78.9\n\ 
 
20111009 \t 69.3 \t 56.7 \t 68.8\n\ 
 
20111010 \t 71.2 \t 60.1 \t 68.7\n\ 
 
20111011 \t 68.7 \t 61.1 \t 70.3\n\ 
 
20111012 \t 61.8 \t 61.5 \t 75.3\n\ 
 
20111013 \t 63.0 \t 64.3 \t 76.6\n\ 
 
20111014 \t 66.9 \t 67.1 \t 66.6\n\ 
 
20111015 \t 61.7 \t 64.6 \t 68.0\n\ 
 
20111016 \t 61.8 \t 61.6 \t 70.6\n\ 
 
20111017 \t 62.8 \t 61.1 \t 71.1\n\ 
 
20111018 \t 60.8 \t 59.2 \t 70.0\n\ 
 
20111019 \t 62.1 \t 58.9 \t 61.6\n\ 
 
20111020 \t 65.1 \t 57.2 \t 57.4\n\ 
 
20111021 \t 55.6 \t 56.4 \t 64.3\n\ 
 
20111022 \t 54.4 \t 60.7 \t 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 a g 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 в всплывающую подсказку, чтобы показывать мои данные в режиме наведения внутри него. Пожалуйста, помогите мне. Спасибо за любую дополнительную помощь.

+0

Рейч, вы пытаетесь отобразить границу значений при наведении ?? –

+0

Ваш вопрос непонятен ... всплывающие подсказки приходят, может быть снимок экрана того, чего вы хотите достичь. – Cyril

+0

Извините за неудобства. На самом деле, я хочу отображать все значения, которые отображаются при наведении на строку внутри конкретного прямоугольного окна, а не печать на границе области, которая на данный момент происходит. Условие состоит в том, что должен быть один прямоугольный прямоугольник, чтобы отображать все значения диаграммы с разбивкой по областям, а не создавать отдельные поля для каждого значения. – Rach

ответ

0

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" 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 \t New York \t San Francisco \t Austin\n\ 
 
20111001 \t 63.4 \t 62.7 \t 72.2\n\ 
 
20111002 \t 58.0 \t 59.9 \t 67.7\n\ 
 
20111003 \t 53.3 \t 59.1 \t 69.4\n\ 
 
20111004 \t 55.7 \t 58.8 \t 68.0\n\ 
 
20111005 \t 64.2 \t 58.7 \t 72.4\n\ 
 
20111006 \t 58.8 \t 57.0 \t 77.0\n\ 
 
20111007 \t 57.9 \t 56.7 \t 82.3\n\ 
 
20111008 \t 61.8 \t 56.8 \t 78.9\n\ 
 
20111009 \t 69.3 \t 56.7 \t 68.8\n\ 
 
20111010 \t 71.2 \t 60.1 \t 68.7\n\ 
 
20111011 \t 68.7 \t 61.1 \t 70.3\n\ 
 
20111012 \t 61.8 \t 61.5 \t 75.3\n\ 
 
20111013 \t 63.0 \t 64.3 \t 76.6\n\ 
 
20111014 \t 66.9 \t 67.1 \t 66.6\n\ 
 
20111015 \t 61.7 \t 64.6 \t 68.0\n\ 
 
20111016 \t 61.8 \t 61.6 \t 70.6\n\ 
 
20111017 \t 62.8 \t 61.1 \t 71.1\n\ 
 
20111018 \t 60.8 \t 59.2 \t 70.0\n\ 
 
20111019 \t 62.1 \t 58.9 \t 61.6\n\ 
 
20111020 \t 65.1 \t 57.2 \t 57.4\n\ 
 
20111021 \t 55.6 \t 56.4 \t 64.3\n\ 
 
20111022 \t 54.4 \t 60.7 \t 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 a g 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="[email protected]" 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 \t New York \t San Francisco \t Austin\n\ 
 
20111001 \t 63.4 \t 62.7 \t 72.2\n\ 
 
20111002 \t 58.0 \t 59.9 \t 67.7\n\ 
 
20111003 \t 53.3 \t 59.1 \t 69.4\n\ 
 
20111004 \t 55.7 \t 58.8 \t 68.0\n\ 
 
20111005 \t 64.2 \t 58.7 \t 72.4\n\ 
 
20111006 \t 58.8 \t 57.0 \t 77.0\n\ 
 
20111007 \t 57.9 \t 56.7 \t 82.3\n\ 
 
20111008 \t 61.8 \t 56.8 \t 78.9\n\ 
 
20111009 \t 69.3 \t 56.7 \t 68.8\n\ 
 
20111010 \t 71.2 \t 60.1 \t 68.7\n\ 
 
20111011 \t 68.7 \t 61.1 \t 70.3\n\ 
 
20111012 \t 61.8 \t 61.5 \t 75.3\n\ 
 
20111013 \t 63.0 \t 64.3 \t 76.6\n\ 
 
20111014 \t 66.9 \t 67.1 \t 66.6\n\ 
 
20111015 \t 61.7 \t 64.6 \t 68.0\n\ 
 
20111016 \t 61.8 \t 61.6 \t 70.6\n\ 
 
20111017 \t 62.8 \t 61.1 \t 71.1\n\ 
 
20111018 \t 60.8 \t 59.2 \t 70.0\n\ 
 
20111019 \t 62.1 \t 58.9 \t 61.6\n\ 
 
20111020 \t 65.1 \t 57.2 \t 57.4\n\ 
 
20111021 \t 55.6 \t 56.4 \t 64.3\n\ 
 
20111022 \t 54.4 \t 60.7 \t 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 a g 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>

+0

Подумав много, теперь я могу показать данные о наведении мыши внутри прямоугольника для отдельных данных, но я хочу показать все данные внутри одного прямоугольника, а не несколько прямоугольников для каждой информации. Пожалуйста, помогите мне с некоторыми советами или предложениями. – Rach

Смежные вопросы