2016-07-09 3 views
0

Ich bin neu zu d3.js bekam den folgenden Code von Stack-Überlauf. Ich hatte es nach meinen Bedürfnissen angepasst. Beim Hinzufügen der QuickInfo bewegt es sich jedoch nicht entsprechend der Mausbewegung und auch nur das Datum wird oben auf der y-Achse angezeigt. Ich muss Tooltip in der Reihenfolge anzeigen Datum: Datum -newline- OP: ein Wert -newline- IP: ein Wert -newline- Apotheke: ein Wert -newline- Gesamt: OP + IP + Apotheke, wo die Maus auf der Linie schwebt .d3.js - Multi-Serie Liniendiagramm Tool-Tipp Ausgabe

TSV-Datei und Code ist wie folgt. Danke im Voraus.

html-Datei

</!DOCTYPE html> 
<html> 
<head> 

<style> 

body { 
    font: 10px sans-serif; 
} 

.axis path, 
.axis line { 
    fill: none; 
    stroke: #000; 
    shape-rendering: crispEdges; 
} 


.line { 
    fill: none; 
    stroke: steelblue; 
    stroke-width: 1.5px; 
} 

</style> 
<script type="text/javascript" src="assets/js/plugins/visualization/d3/d3.min.js"></script> 
</head> 
<body> 
<div id="revenueStati"></div> 
<script> 
linchart(); 
function linchart(){ 
var margin = {top: 20, right: 80, bottom: 30, left: 50}, 
    width = 960 - margin.left - margin.right, 
    height = 500 - margin.top - margin.bottom; 

var parseDate = d3.time.format("%Y%m%d").parse; 
var formatDate = d3.time.format("%d-%b") 
var bisectDate = d3.bisector(function(d) { return d.date; }).left 
var x = d3.time.scale() 
    .range([0, width]); 

var y = d3.scale.linear() 
    .range([height-10, 0]); 

var color = d3.scale.category10(); 

var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("bottom").ticks(7); 

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("#revenueStati").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 + ")"); 





d3.tsv("data.tsv", function(error, data) { 
    if (error) throw error; 

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

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

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

     //// - tooltip 


city = svg.append("g") 
    .style("display", "none"); 
     // append the x line 
    city.append("line") 
     .attr("class", "x") 
     .style("stroke", "blue") 
     .style("stroke-dasharray", "3,3") 
     .style("opacity", 0.5) 
     .attr("y1", 0) 
     .attr("y2", height); 

    // append the y line 
    city.append("line") 
     .attr("class", "y") 
     .style("stroke", "blue") 
     .style("stroke-dasharray", "3,3") 
     .style("opacity", 0.5) 
     .attr("x1", width) 
     .attr("x2", width); 

    // append the circle at the intersection 
    city.append("circle") 
     .attr("class", "y") 
     .style("fill", "none") 
     .style("stroke", "blue") 
     .attr("r", 4); 

    // place the value at the intersection 
    city.append("text") 
     .attr("class", "y1") 
     .style("stroke", "white") 
     .style("stroke-width", "3.5px") 
     .style("opacity", 0.8) 
     .attr("dx", 8) 
     .attr("dy", "-.3em"); 
    city.append("text") 
     .attr("class", "y2") 
     .attr("dx", 8) 
     .attr("dy", "-.3em"); 

    // place the date at the intersection 
    city.append("text") 
     .attr("class", "y3") 
     .style("stroke", "white") 
     .style("stroke-width", "3.5px") 
     .style("opacity", 0.8) 
     .attr("dx", 8) 
     .attr("dy", "1em"); 
    city.append("text") 
     .attr("class", "y4") 
     .attr("dx", 8) 
     .attr("dy", "1em"); 

    // append the rectangle to capture mouse 
    svg.append("rect") 
     .attr("width", width) 
     .attr("height", height) 
     .style("fill", "none") 
     .style("pointer-events", "all") 
     .on("mouseover", function() { city.style("display", null); }) 
     .on("mouseout", function() { city.style("display", "none"); }) 
     .on("mousemove", mousemove); 

    function mousemove() { 
    var x0 = x.invert(d3.mouse(this)[0]), 
     i = bisectDate(data, x0, 1), 
     d0 = data[i - 1], 
     d1 = data[i], 
     d = x0 - d0.date > d1.date - x0 ? d1 : d0; 

    city.select("circle.y") 
     .attr("transform", 
       "translate(" + x(d.date) + "," + 
          y(d.close) + ")"); 

    city.select("text.y1") 
     .attr("transform", 
       "translate(" + x(d.date) + "," + 
          y(d.close) + ")") 
     .text(d.close); 

    city.select("text.y2") 
     .attr("transform", 
       "translate(" + x(d.date) + "," + 
          y(d.close) + ")") 
     .text(d.close); 

    city.select("text.y3") 
     .attr("transform", 
       "translate(" + x(d.date) + "," + 
          y(d.close) + ")") 
     .text(formatDate(d.date)); 

    city.select("text.y4") 
     .attr("transform", 
       "translate(" + x(d.date) + "," + 
          y(d.close) + ")") 
     .text(formatDate(d.date)); 

    city.select(".x") 
     .attr("transform", 
       "translate(" + x(d.date) + "," + 
          y(d.close) + ")") 
        .attr("y2", height - y(d.close)); 

    city.select(".y") 
     .attr("transform", 
       "translate(" + width * -1 + "," + 
          y(d.close) + ")") 
        .attr("x2", width + width); 
    } 

}); 
} 

</script> 
</body> 

</html> 

data.tsv Datei

date OP IP Pharmacy 
20160406 46905.00 10360.00 52558.00 
20160407 45415.00 10910.00 46665.00 
20160408 69770.00 10935.00 46377.00 
20160409 58455.00 29900.00 37352.00 
20160410 10345.00 7200.00 22971.00 
20160411 48680.00 14535.00 46482.00 
20160412 42452.00 16270.00 34859.00 

demo graph

+1

Wo definierst du 'd.close'. Sie erhalten NaN als y-Position. Könnte dein Post-Beispiel verlinken? – Klaujesi

+0

@Klaujesi Ich hatte den ganzen Code und die tsv-Datei gepostet, momentan ist es für mich nicht möglich, es online zu machen. Freundlich helfen. – JavDev

Antwort

1

Sie Code ist aus den Beispielen mit einem Daten-Serie nehmen und mehrere Serien haben:

Der wichtige Start hier:

var x0 = x.invert(d3.mouse(this)[0]), 
    i = bisectDate(data, x0, 1), 
    d0 = data[i - 1], 
    d1 = data[i], 
    d = x0 - d0.date > d1.date - x0 ? d1 : d0; 

city.select("circle.y") 
    .attr("transform", 
      "translate(" + x(d.date) + "," + // based on date 
         y(d.close) + ")"); // you need find y value 
              // d.close is not defined 

Sie haben 3-Serie. Sie könnten den Maximalwert zu einem bestimmten Zeitpunkt in Anspruch nehmen und den Kreis zeichnen:

var ymax = d3.max([+d["OP"],+d["IP"],+d["Pharmacy"]]) 
var xm = x(d.date); 
var ym = y(ymax); 

city.select("circle.y") 
    .attr("transform", 
      "translate(" + xm + "," + 
         ym + ")"); 

Oder drei Kreise ziehen, eine für jede Serie:

city.select("circle.y") 
    .attr("transform", 
      "translate(" + xm + "," + 
         y(+d["OP"]) + ")"); 

city.select("circle.y") 
    .attr("transform", 
      "translate(" + xm + "," + 
         y(+d["IP"]) + ")"); 

city.select("circle.y") 
    .attr("transform", 
      "translate(" + xm + "," + 
         y(+d["Pharmacy"]) + ")"); 

Jetzt wissen Sie, wie man calulate (x, y) Sie können die horizontalen & vertikalen gestrichelten Linien mit Beschriftungen machen.

Here's s psudoworking code. Ich habe es als Hausaufgabe abgeschlossen :)