2017-05-11 3 views
0

Ich baue nach gruppierten Balkendiagramm und es funktioniert gut. Jetzt muss ich dem Diagramm eine einzelne Zeile hinzufügen, die einen Prozentsatz der Betriebsstunden gegenüber den geleisteten Stunden darstellt. Meine Daten werden von JSON gesendet:d3 - Fügen Sie eine einzelne Zeile zum gruppierten Balkendiagramm hinzu

[{"SORT_NAME":"WEEMS, AMY", 
"Service":118.0, 
"Available":40.0, 
"Timesheet":28.0, 
"Month":3, 
"MonthName":"Mar", 
"Year":2017}, 
{"SORT_NAME":"WEEMS, AMY", 
"Service":119.0, 
"Available":80.0, 
"Timesheet":70.0, 
"Month":4, 
"MonthName":"Apr", 
"Year":2017}] 

und verarbeitet d3 in HTML:

<script src="http://d3js.org/d3.v3.min.js"></script> 

<script> 
    // set the dimensions of the canvas 
    var margin = { top: 20, right: 20, bottom: 70, left: 40 }, 
     width = 1000 - margin.left - margin.right, 
     height = 500 - margin.top - margin.bottom; 


    // set the ranges 
    var x0 = d3.scale.ordinal().rangeRoundBands([0, width], .05); 
    var x1 = d3.scale.ordinal(); 
    var xl = d3.scale.linear().range([0,width]); 
    var y = d3.scale.linear().range([height, 0]); 
    var z = d3.scale.ordinal().range(["#0b4a72", "#ad1a2c", "#7aa74d"]); 

    // define the axis 
    var xAxis = d3.svg.axis() 
     .scale(x0) 
     .orient("bottom") 


    var yAxis = d3.svg.axis() 
     .scale(y) 
     .orient("left") 
     .ticks(10); 

    // add the SVG element 
    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 + ")"); 

    // load the data 
    d3.json("http://lrssrs/LRCS/EmpHours/GraphData", function (error, data) { 

     var seriesNames = d3.keys(data[0]).filter(function (key) { return (key !== "SORT_NAME") && (key !== "Year") && (key !== "Month") && (key !== "MonthName"); }); 

     data.forEach(function (d) { d.Hours = seriesNames.map(function (name) { return { name: name, value: +d[name] }; }); }); 

     // scale the range of the data 
     x0.domain(data.map(function (d) { return d.MonthName + " " + d.Year; })); 
     x1.domain(seriesNames).rangeRoundBands([0, x0.rangeBand()]); 
     xl.domain(data.map(function (d) { return d.MonthName + " " + d.Year; })); 
     y.domain([0, (10 + d3.max(data, function (d) { return d3.max(d.Hours, function (d) { return d.value; }); }))]); 
     var line = d3.svg.line() 
      .x(function (d) { 
       return xl(d.Available); 
      }) 
      .y(function (d) { 
       return y(d.Service/d.Timesheet); 
      });  

     svg.append("path") 
      .attr("d", line(data)); 

     // add axis 
     svg.append("g") 
      .attr("class", "x axis") 
      .attr("transform", "translate(0," + height + ")") 
      .call(xAxis) 
      .selectAll("text") 
      .style("text-anchor", "end") 
      .attr("dx", "-.8em") 
      .attr("dy", "-.55em") 
      .attr("transform", "rotate(-90)"); 

     svg.append("g") 
      .attr("class", "y axis") 
      .call(yAxis) 
      .append("text") 
      .attr("transform", "rotate(-90)") 
      .attr("y", 5) 
      .attr("dy", ".71em") 
      .style("text-anchor", "end") 
      .text("Hours"); 

     var state = svg.selectAll(".state") 
      .data(data) 
      .enter().append("g") 
      .attr("class", "g") 
      .attr("transform", function (d) { return "translate(" + x0(d.MonthName + " " + d.Year) + ",0)"; }); 

     // Add bar chart 
     state.selectAll("bar") 
      .data(function (d) { return d.Hours; }) 
      .enter().append("rect") 
      .attr("class", "bar") 
      .attr("x", function (d) { return x1(d.name); }) 
      .attr("width", x1.rangeBand()) 
      .attr("y", function (d) { return y(d.value); }) 
      .attr("height", function (d) { return height - y(d.value); }) 
      .style("fill", function (d) { return z(d.name); }); 

     state.selectAll("text") 
      .data(function (d) { return d.Hours; }) 
      .enter().append("text") 
      .text(function (d) { return d.value; }) 
      .attr("width", x1.rangeBand()) 
      .attr("x", function (d) { return x1(d.name) + (x1.rangeBand()/2); }) 
      .attr("y", function (d) { return y(d.value) + 20; }) 
      .attr("text-anchor", "middle") 
      .attr("font-family", "sans-serif") 
      .attr("font-size", "11px") 
      .attr("fill", "white"); 

     var legend = svg.selectAll(".legend") 
      .data(seriesNames.slice().reverse()) 
      .enter().append("g") 
      .attr("class", "legend") 
      .attr("transform", function (d, i) { return "translate(0," + (i * 20) + ")"; }); 

     legend.append("rect") 
      .attr("x", width - 18) 
      .attr("width", 18) 
      .attr("height", 18) 
      .style("fill", z); 

     legend.append("text") 
      .attr("x", width - 24) 
      .attr("y", 9) 
      .attr("dy", ".35em") 
      .style("text-anchor", "end") 
      .text(function (d) { return d; }) 
      .on("click", function (d) { alert(d); }); 

    }); 

</script> 

Allerdings kann ich nicht über die Linie zu bekommen scheinen zu erzeugen, und ich erhalte einen Pfad Attributfehler (Erwartete Anzahl). Wie richte ich die Zeilendaten ein? Wenn mir jemand in die richtige Richtung zeigen kann, würde ich das schätzen!

+0

Sie benötigen lineare Skalen für Linien. Erstellen Sie eine weitere x-Skala, die linear ist. –

+0

Hinzugefügt zu meinem Code oben. Ich habe es getestet, aber ich bekomme immer noch nicht die Linie. –

Antwort

Verwandte Themen