D3 js中的直线条形图

时间:2017-02-02 12:34:43

标签: javascript d3.js

我一直在尝试实施Line-Bar组合图表,但我没有太大成功。 这是我的代码



function renderNormalizedStackBarChart(inputData,dom_element_to_append_to, path_to_data) {
            var margin = {top: 20, right: 231, bottom: 140, left: 40}, 
            width = $(dom_element_to_append_to).width() - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;

            var xscale = d3.scale.ordinal()
            .rangeRoundBands([0, width], .1);

            var yScaleLeft = d3.scale.linear()
            .rangeRound([height, 0]);

            var yScaleRight = d3.scale.linear()
            .rangeRound([height, 0]);

            var colors = d3.scale.ordinal()
            .range(["#63c172", "#ee9952", "#46d6c4", "#fee851", "#98bc9a"]);

            var xaxis = d3.svg.axis()
            .scale(xscale)
            .orient("bottom");

            var yAxisLeft = d3.svg.axis()
            .scale(yScaleLeft)
            .orient("left")
            .tickFormat(d3.format(".0%")); 

            var yAxisRight = d3.svg.axis()
            .scale(yScaleRight)
            .orient("right")
            .tickFormat(d3.format(".0%"));

            var x = d3.time.scale()
            .range([0, width - 25]);


            /*category.selectAll("rect")
            .data(function(d) { return d.responses; })
            .enter().append("rect")
            .attr("width", xscale.rangeBand())
            .attr("y", function(d) { return yScaleLeft(d.yp1); })
            .attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); })
            .style("fill", function(d) { return colors(d.response); });*/
            var temp  = 0;
            var line = d3.svg.line()
            .x(function(d, i) {
                console.log(temp);
                var temp2 = temp;
                temp += xscale.rangeBand();
                return temp2;
            })
            .y(function(d) {
                console.log(yScaleRight(d.value));
                return yScaleRight(d.value);
            })
            .interpolate("linear")
            ;

            var svg = d3.select(dom_element_to_append_to).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(path_to_data, function(error, data) {
                //data = inputData;
               
                var categories = d3.keys(data[0]).filter(function(key) { return key !== "CategoryNames"; });
                var parsedata = categories.map(function(name) { return { "CategoryNames": name }; });
                data.forEach(function(d) {
                    parsedata.forEach(function(pd) {
                        pd[d["CategoryNames"]] = d[pd["CategoryNames"]];
                    });
                });

              
                colors.domain(d3.keys(parsedata[0]).filter(function(key) { return key !== "CategoryNames" && key !== "Base"; }));


                parsedata.forEach(function(pd) {
                    var y0 = 0;

                    pd.responses = colors.domain().map(function(response) {
                        var responseobj = {response: response, y0: y0, yp0: y0};
                        y0 += +pd[response];
                        responseobj.y1 = y0;
                        responseobj.yp1 = y0;
                        return responseobj;
                    });

                    pd.responses.forEach(function(d) { d.yp0 /= y0; d.yp1 /= y0; });

                    pd.totalresponses = pd.responses[pd.responses.length - 1].y1;
                });
                console.log(parsedata);
                xscale.domain(parsedata.map(function(d) { return d.CategoryNames; }));


                svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xaxis)
                .selectAll("text")
                .attr("y", 5)
                .attr("x", 7)
                .attr("dy", ".35em")
                .attr("transform", "rotate(65)")
                .style("text-anchor", "start");


                svg.append("g")
                .attr("class", "y axisLeft")
                .call(yAxisLeft);

                svg.append("g")
                .attr("class", "y axisRight")
                .attr("transform", function() { return "translate(" + width + "," + 0 + ")"; })
                .call(yAxisRight);

                var category = svg.selectAll(".category")
                .data(parsedata)
                .enter().append("g")
                .attr("class", "category")
                .attr("transform", function(d) { return "translate(" + xscale(d.CategoryNames) + ",0)"; });


                category.selectAll("rect")
                .data(function(d) { return d.responses; })
                .enter().append("rect")
                .attr("width", xscale.rangeBand())
                .attr("y", function(d) { return yScaleLeft(d.yp1); })
                .attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); })
                .style("fill", function(d) { return colors(d.response); });
                
                var convertedData = [];
                parsedata.forEach(function(item) {
                    convertedData.push({response: item.CategoryNames, value: item.responses[0].yp1})
                });
                temp = xscale.rangeBand()/2;
                console.log(convertedData);
                svg.append("path")
                .data(convertedData)
                .attr("class", "line")
                
                .attr("d", line(convertedData));

                var legend = svg.selectAll(".legend")
                .data(colors.domain())
                .enter().append("g")
                .attr("class", "legend")
                .attr("transform", function(d, i) { return "translate(82," + ((height - 18) - (i * 20)) + ")"; });

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

                legend.append("text")
                .attr("x", width + 10)
                .attr("y", 9)
                .attr("dy", ".35em")
                .style("text-anchor", "start")
                .text(function(d) { return d; });


                d3.selectAll("input").on("change", handleFormClick);

                function handleFormClick() {
                    if (this.value === "bypercent") {
                        transitionPercent();
                    } else {
                        transitionCount();
                    }
                }


                function transitionPercent() {

                    yScaleLeft.domain([0, 1]);


                    var trans = svg.transition().duration(250);


                    var categories = trans.selectAll(".category");
                    categories.selectAll("rect")
                    .attr("y", function(d) { return yScaleLeft(d.yp1); })
                    .attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); });


                    yAxisLeft.tickFormat(d3.format(".0%"));
                    svg.selectAll(".y.axisLeft").call(yAxisLeft);
                }


                function transitionCount() {

                    yScaleLeft.domain([0, d3.max(parsedata, function(d) { return d.totalresponses; })]);


                    var transone = svg.transition()
                    .duration(100);


                    var categoriesone = transone.selectAll(".category");
                    categoriesone.selectAll("rect")
                    .attr("y", function(d) { return this.getBBox().y + this.getBBox().height - (yScaleLeft(d.y0) - yScaleLeft(d.y1)) })
                    .attr("height", function(d) { return yScaleLeft(d.y0) - yScaleLeft(d.y1); });


                    var transtwo = transone.transition()
                    .delay(150)
                    .duration(200)
                    .ease("bounce");

                    var categoriestwo = transtwo.selectAll(".category");
                    categoriestwo.selectAll("rect")
                    .attr("y", function(d) { return yScaleLeft(d.y1); });


                    yAxisLeft.tickFormat(d3.format(".2s"));
                    svg.selectAll(".y.axisLeft").call(yAxisLeft);
                }
            });

d3.select(self.frameElement).style("height", (height + margin.top + margin.bottom) + "px");
}
var inputData = [];
renderNormalizedStackBarChart(inputData,"#normalizedChart", "data/normalizedChart.tsv");

 rect.bordered {
            stroke: #E6E6E6;
            stroke-width: 2px;
        }

        body {
            font-size: 9pt;
            font-family: Consolas, courier;
        }

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

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

        .bar {
            fill: steelblue;
        }
       
        .x.axis path {
            display: none;
        }
        
        .legend line {
            stroke: #000;
            shape-rendering: crispEdges;
        }
        path .line {
            stroke: #000;
            shape-rendering: crispEdges;
        }

        form {
            position: absolute;
            right: 10px;
            top: 10px;
        }

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<div class="row">
        <form>
          <label><input type="radio" name="mode" value="bypercent" checked> Percent</label>
          <label><input type="radio" name="mode" value="bycount"> Number of Respondants</label>
        </form>
                
        <div id="normalizedChart"></div>
        </div>
&#13;
&#13;
&#13;

但我得到的只是下图所示的图表。如何使路径显示为line.Here在代码中InputData变量没有用,因为我通过tsv文件读取数据。 enter image description here

1 个答案:

答案 0 :(得分:1)

您必须将样式添加到fill : none到您的路径

svg.append("path")
    .data(convertedData)
    .attr("class", "line")
    .attr("d", line(convertedData));
    .attr("stroke", "blue")
    .attr("stroke-width", 2)
    .attr("fill", "none");