如何将钢筋与自定义y轴域对齐?

时间:2018-08-15 05:50:55

标签: javascript d3.js

我有一个缩放功能,可以更改条形图y轴的最小值和最大值。条形和数据标签似乎并没有使其自身适应新的比例。如何将其设置为y轴的新比例尺?

enter image description here

enter image description here

更改Y轴比例功能

function changeYAxisScale() {
        var min = document.getElementById("min").value;
        var max = document.getElementById("max").value;


        y.domain([min, max]);

        innerChart.select(".y.axis").transition().duration(300).call(yAxis);

        innerChart.selectAll(".bar").data(jsdata)
            .transition()
            .duration(500)
            .attr("y", function (jsdata) {
                return y(jsdata.value);
            })
            .attr("height", function (jsdata) {
                return height - y(jsdata.value);
            });

        innerChart.selectAll(".label").data(jsdata)
            .transition()
            .duration(500)
            .attr("y", function (jsdata) {
                return y(jsdata.value) - 20;
            })
            .attr("dy", ".75em")
            .attr("text-anchor", "middle")
            .text(function (jsdata) {
                return jsdata.value;
            });

        innerChart.select(".y.axis").transition().duration(300).call(yAxis);

        innerChart.selectAll(".bar").data(jsObjectsArray)
            .transition()
            .duration(500)
            .attr("y", function (d) {
                return y(d.value);
            })
            .attr("height", function (d) {
                return height - y(d.value);
            })

        innerChart.selectAll(".label").data(jsObjectsArray)
            .transition()
            .duration(500)
            .attr("y", (function (d) {
                return y(d.value) - 20;
            }))
            .attr("dy", ".75em")
            .attr("text-anchor", "middle")
            .text(function (d) {
                return d.value;
            });
    }

基本上,我只是重设y域,然后重绘条形图和数据标签。如何设置数据标签像条一样经过x轴后消失。并且如果条形的高度大于y刻度的最大高度,如何将其高度设置为刻度的最大高度?

<!DOCTYPE html>

<body>
    <style>
        .bar {
            font: 10px sans-serif;
            text-align: right;
            padding: 3px;
            margin: 1px;
            color: white;

        }

    .axis text {
        font: 10px sans-serif;
    }

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

    .x.axis path {
        display: none;
    }

    .legend rect {
        fill: white;
        stroke: black;
        opacity: 0.8;
    }

    .toolTip {
        position: absolute;
        display: none;
        min-width: 80px;
        height: auto;
        background: none repeat scroll 0 0 #ffffff;
        border: 1px solid #6F257F;
        padding: 14px;
        text-align: center;
    }

    .switch {
        position: relative;
        display: inline-block;
        width: 60px;
        height: 34px;
    }

    .switch input {
        display: none;
    }


    .slider {
        position: absolute;
        cursor: pointer;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: #ccc;
        -webkit-transition: .4s;
        transition: .4s;
    }

    .slider:before {
        position: absolute;
        content: "";
        height: 26px;
        width: 26px;
        left: 4px;
        bottom: 4px;
        background-color: white;
        -webkit-transition: .4s;
        transition: .4s;
    }

    input:checked+.slider {
        background-color: #2196F3;
    }

    input:focus+.slider {
        box-shadow: 0 0 1px #2196F3;
    }

    input:checked+.slider:before {
        -webkit-transform: translateX(26px);
        -ms-transform: translateX(26px);
        transform: translateX(26px);
    }

    /* Rounded sliders */

    .slider.round {
        border-radius: 34px;
    }

    .slider.round:before {
        border-radius: 50%;
    }


    div {
        display: inline-block;
        position: relative;
    }


    #colorize {
        position: relative;
        bottom: 10px;
        right: 81px;
    }

    #scale {
        top: -119px;
        height: 40px;
    }



    #userData {
        top: -3px;
    }

    #submitData {
        position: absolute;
        bottom: 10px;
        right: 10px;
    }

    #toggle {
        width: 445px;
    }
</style>
<svg class="chart"></svg>
<div class="row">
    <div class="col-sm-6" id="toggle">
        <h3>Toggle Data Label</h3>
        <label class="switch">
            <input type="checkbox" onclick="togglePressed(this)" id="dataLabel" checked>
            <span class="slider round"></span>
        </label>
        <h3>Toggle Data Legend</h3>
        <label class="switch">
            <input type="checkbox" onclick="togglePressed(this)" id="dataLegend" checked>
            <span class="slider round"></span>
        </label>
        <h3>Toggle Data Legend Position</h3>
        <select id="legendpos" onchange="changeLegendPosition(this)">
            <option value="right" selected>Right</option>
            <option value="bottom">Bottom</option>
            <option value="left">Left</option>
            <option value="top">Top</option>
        </select>
    </div>
    <div class="col-sm-6" id="scale">
        <h3>Change Y-axis Scale</h3>
        Min :
        <input type="number" id="min"> Max :
        <input type="number" id="max">
        <button onclick="changeYAxisScale()">Change</button>
    </div>
</div>
<div class="row" id="inputData">
    <div class="col-sm-12">
        <h3>Enter your desired colors in hexadecimal value</h3>
        <textarea rows="6" cols="60" id="colorInput"></textarea>
        <button id="colorize" onclick="colorize()">Colorize</button>
        <h3>Enter your data in JSON Object Array format</h3>
        X:
        <input type="text" id="xvalue" required> Y:
        <input type="text" id="yvalue" required>
        <textarea rows="6" cols="60" id="jstextarea"></textarea>
        <button id="submitData" onclick="addjsObjectArray()">Submit</button>
    </div>
</div>
<script src="https://d3js.org/d3.v3.js"></script>
<script src="d3legend.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    var jsdata = [{
        name: "Locke",
        value: 4
    },
    {
        name: "Reyes",
        value: 8
    },
    {
        name: "Ford",
        value: 15
    },
    {
        name: "Jarrah",
        value: 16
    },
    {
        name: "Shephard",
        value: 23
    },
    {
        name: "Kwon",
        value: 52
    }
    ];

    var jsObjectsArray;
    var colorCodes = ["#6b486b", "#a05d56", "#d0743c", "#ff8c00"];
    var color = d3.scale.ordinal().range(colorCodes);
    //Set the margins for the bar chart. 
    var margin = {
        top: 130,
        right: 100,
        bottom: 170,
        left: 130
    },
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    //Encoding ordinal data. rangeRoundBands is used to snap each position to the exact pixel boundary for crisp edges
    var x = d3.scale.ordinal()
        .rangeRoundBands([0, width], .1);

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

    var tooltip = d3.select("body").append("div").attr("class", "toolTip");
    //Adding the axes
    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");

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

    //Declaring the chart container
    var mainChart = d3.select(".chart")
        .attr("width", width + margin.left + margin.right)
        .data(jsdata)
        .attr("height", height + margin.top + margin.bottom)

    var innerChart = mainChart.append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");



    x.domain(jsdata.map(function (jsdata) {
        return jsdata.name;
    }));
    y.domain([0, d3.max(jsdata, function (jsdata) {
        return jsdata.value;
    })]);

    innerChart.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
        .selectAll(".tick text")
        .call(wrap, x.rangeBand());
    innerChart.append("text")      // text label for the x axis
        .attr("x", width / 2)
        .attr("y", height + 30)
        .attr("id", "xAxistext")
        .style("text-anchor", "middle")
        .text(function (jsdata) {
            return Object.keys(jsdata)[0];
        });


    innerChart.append("g")
        .attr("class", "y axis")
        .call(yAxis);
    innerChart.append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 0 - 40)
        .attr("x", 0 - (height / 2) + 3)
        .attr("id", "yAxistext")
        .attr("dy", ".5em")
        .style("text-anchor", "middle")
        .text(function (jsdata) {
            return Object.keys(jsdata)[1];
        });
    var bars = innerChart.selectAll(".bar")
        .data(jsdata) // Using the data join pattern
        .enter().append("rect") //Selecting the innerChart container then append the width and height for new nodes
        .style("fill", function (jsdata, i) {
            return color(i);
        })
        .style("color", function () {
            return '#FFFFFF';
        })
        .on("mousemove", function (jsdata) {
            tooltip
                .style("left", d3.event.pageX - 50 + "px")
                .style("top", d3.event.pageY - 70 + "px")
                .style("display", "inline-block")
                .html((jsdata.name) + "<br>" + "£" + (jsdata.value));
        })
        .on("mouseout", function (jsdata) {
            tooltip.style("display", "none");
        })
        .attr("class", "bar")
        .attr("data-legend", function (jsdata) {
            return jsdata.name
        })
        .attr("x", function (jsdata) {
            return x(jsdata.name);
        })
        .attr("id", "sampledata")
        .attr("y", function (jsdata) {
            return y(jsdata.value);
        })
        .attr("height", function (jsdata) {
            return height - y(jsdata.value);
        })
        .attr("width", x.rangeBand());

    innerChart.selectAll(".text")
        .data(jsdata)
        .enter()
        .append("text")
        .attr("text-anchor", "middle")
        .attr("class", "label")
        .attr("x", (function (jsdata, i) {
            return x(jsdata.name) + (x.rangeBand() / 2);
        }))
        .attr("y", function (jsdata) {
            return y(jsdata.value) - 20;
        })

        .attr("dy", ".75em")
        .text(function (jsdata) {
            return jsdata.value;
        })

    //Converting the column from string to integer
    function type(jsdata) {
        jsdata.value = +jsdata.value;
        return jsdata;
    }

    function togglePressed(identity) {
        var id = identity.id;
        if (id == "dataLabel") {
            $(".label").toggle();
        }
        else if (id = "dataLegend") {
            $("#dataLegend").toggle();
        }

    }

    function colorize() {
        var colorInput = document.getElementById("colorInput").value;
        var newColors = JSON.parse(colorInput);
        color = d3.scale.ordinal().range(newColors);


        innerChart.selectAll(".bar")
            .style('fill', function (jsdata, i) {
                return color(i);
            })
            .attr("height", function (jsdata) {
                return height - y(jsdata.value);
            })
            .attr("width", x.rangeBand())


    }
    function wrap(text, width) {
        text.each(function () {
            var text = d3.select(this),
                words = text.text().split(/\s+/).reverse(),
                word,
                line = [],
                lineNumber = 0,
                lineHeight = 1.1, // ems
                y = text.attr("y"),
                dy = parseFloat(text.attr("dy")),
                tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
            while (word = words.pop()) {
                line.push(word);
                tspan.text(line.join(" "));
                if (tspan.node().getComputedTextLength() > width) {
                    line.pop();
                    tspan.text(line.join(" "));
                    line = [word];
                    tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
                }
            }
        });
    }
    function changeYAxisScale() {
        var min = document.getElementById("min").value;
        var max = document.getElementById("max").value;


        y.domain([min, max]);

        innerChart.select(".y.axis").transition().duration(300).call(yAxis);

        innerChart.selectAll(".bar").data(jsdata)
            .transition()
            .duration(500)
            .attr("y", function (jsdata) {
                return (jsdata.value);
            })
            .attr("height", function (jsdata) {
                return height - y(jsdata.value);
            });

        innerChart.selectAll(".label").data(jsdata)
            .transition()
            .duration(500)
            .attr("y", function (jsdata) {
                return y(jsdata.value) - 20;
            })
            .attr("dy", ".75em")
            .attr("text-anchor", "middle")
            .text(function (jsdata) {
                return jsdata.value;
            });

        innerChart.select(".y.axis").transition().duration(300).call(yAxis);

        innerChart.selectAll(".bar").data(jsObjectsArray)
            .transition()
            .duration(500)
            .attr("y", function (d) {
                return y(d.value);
            })
            .attr("height", function (d) {
                return height - y(d.value);
            })

        innerChart.selectAll(".label").data(jsObjectsArray)
            .transition()
            .duration(500)
            .attr("y", (function (d) {
                return y(d.value) - 20;
            }))
            .attr("dy", ".75em")
            .attr("text-anchor", "middle")
            .text(function (d) {
                return d.value;
            });
    }
    function changeLegendPosition(position) {
        var value = position.value;
        if (value == "bottom") {
            d3.select("#dataLegend").attr('transform', "translate(460,390)");
        }
        else if (value == "right") {
            d3.select("#dataLegend").attr('transform', "translate(" + (margin.left + width) + ",35)")
        }
        else if (value == "left") {
            d3.select("#dataLegend").attr('transform', "translate(15,25)")
        }
        else if (value == "top") {
            d3.select("#dataLegend").attr('transform', "translate(460,25)")
        }
    }

    function addjsObjectArray() {

        var xname = document.getElementById("xvalue").value;
        var yname = document.getElementById("yvalue").value;

        if (xname && yname != null) {
            var jsObjects = document.getElementById("jstextarea").value;
            jsObjectsArray = eval(jsObjects);
            jsObjectsArray = jsObjectsArray.map(function (d) { return { key: d[xname], value: d[yname] }; });

            x.domain(jsObjectsArray.map(function (d) {
                return d.key;
            }));
            y.domain([0, d3.max(jsObjectsArray, function (d) {
                return d.value;
            })]);
            console.log(jsObjectsArray);
            innerChart.select('.x.axis').transition().duration(300).call(xAxis);
            innerChart.select(".y.axis").transition().duration(300).call(yAxis);
            innerChart.data(jsObjectsArray);
            innerChart.select("#xAxistext").text(function (d) {
                return xname;
            });

            innerChart.select("#yAxistext").text(function () {
                return yname;
            });

            innerChart.selectAll("#sampledata").remove();
            innerChart.selectAll("#jsondata").remove();
            innerChart.selectAll(".label").remove();
            var bars = innerChart.selectAll(".bar").data(jsObjectsArray);

            bars.enter().append("rect")
                .attr("x", function (d) {
                    return x(d.key);
                })
                .attr("y", function (d) {
                    return y(d.value);
                })
                .attr("height", function (d) {
                    return height - y(d.value);
                })
                .attr("width", x.rangeBand())
                .attr("id", "jsondata")
                .attr("class", "bar")
                .style("fill", function (d, i) {
                    return color(i);
                })
                .style("color", function () {
                    return '#FFFFFF';
                })
                .on("mousemove", function (d) {
                    tooltip
                        .style("left", d3.event.pageX - 50 + "px")
                        .style("top", d3.event.pageY - 70 + "px")
                        .style("display", "inline-block")
                        .html((d.key) + "<br>" + (d.value));
                })
                .on("mouseout", function (d) {
                    tooltip.style("display", "none");
                })
                .attr("data-legend", function (d) {
                    return d.key
                });


            var texts = innerChart.selectAll(".label")
                .data(jsObjectsArray);

            texts.enter()
                .append("text")
                .attr("class", "label");

            texts.attr("x", (function (d) {
                return x(d.key) + (x.rangeBand() / 2);
            }))
                .attr("y", (function (d) {
                    return y(d.value) - 20;
                }))
                .attr("dy", ".75em")
                .attr("text-anchor", "middle")
                .text(function (d) {
                    return d.value;
                });

            mainChart.select("#dataLegend").call(d3.legend);
        }
        else {
            alert("Please enter your X and Y axes");
        }



    }

    var legend = mainChart.append("g")
        .attr("class", "legend")
        .attr('transform', "translate(" + (margin.left + width) + ",35)")
        .attr("data-legend-pos", "top")
        .attr("id", "dataLegend")
        .style("font-size", "15px")
        .call(d3.legend);

</script>
</body>

0 个答案:

没有答案