如何使D3 SVG填充以适合屏幕上的区域,并具有SVG的图形填充区域?

时间:2019-06-20 21:45:41

标签: javascript d3.js svg

D3和JS的新功能,我正在开发一个Webapp,以显示有关美国总统初选候选人的各种财务数据。

我已经复制了一些代码来创建使其具有响应能力的函数,但我不知道如何根据窗口大小来确定高度,这意味着台式机上漂亮的横向图表会变得非常小手机上的图表。

桌面看起来不错: enter image description here

手机被压缩

enter image description here

脚本附在下面,但是可能很难读。如果有人从描述和图片中了解了我的问题,并且对正确的方向提出了建议,我将万分感谢!

我的脚本:

var yLen = data.length;
    // I snagged this f(x) from https://brendansudol.com/writing/responsive-d3
    // not entirely sure how it works 
function responsivefy(svg) {
        // get container + svg aspect ratio
        var container = d3.select(svg.node().parentNode),
                width = parseInt(svg.style("width")),
                height = parseInt(svg.style("height")),
                aspect = width / height;
        // add viewBox and preserveAspectRatio properties,
        // and call resize so that svg resizes on inital page load
        svg.attr("viewBox", "0 0 " + width + " " + height)
                .attr("perserveAspectRatio", "xMinYMid")
                .call(resize);
        // to register multiple listeners for same event type,
        // you need to add namespace, i.e., 'click.foo'
        // necessary if you call invoke this function for multiple svgs
        // api docs: https://github.com/mbostock/d3/wiki/Selections#on
        d3.select(window).on("resize." + container.attr("id"), resize);
        // get width of container and resize svg to fit it
        function resize() {
                var targetWidth = parseInt(container.style("width"));
                svg.attr("width", targetWidth);
                svg.attr("height", Math.round(targetWidth / aspect));
        }
}
//set up svg using margin conventions
  //we'll need plenty of room on the left for labels

    var margin = {
        top: 15,
        right: 35,
        bottom: 15,
        left: 100
    };
    var width = 960 - margin.left - margin.right,
        height = Math.min(300, (yLen*100)) - margin.top - margin.bottom;
    var svg = d3.select("#{{contest.slug}}").append("svg")
        .attr("id", "{{ contest.slug }}"+"-svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .call(responsivefy)
                    .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    var x = d3.scale.linear()
        .range([0, width])
        .domain([0, d3.max(data, function (d) {
            return d.Amount;
        })]);
    var y = d3.scale.ordinal()
        .rangeRoundBands([height, 0], .1)
        .domain(data.map(function (d) {
            return d.Candidate;
        }));
    //make y axis to show bar names
    var yAxis = d3.svg.axis()
        .scale(y)
        //no tick marks
        .tickSize(0)
        .orient("left")
    var gy = svg.append("g")
        .attr("class", "y axis")
        .call(yAxis)
            //make x axis 
    var xAxis = d3.svg.axis()
        .scale(x)
        .tickSize(1)
        .ticks(10)
        .orient("bottom");
    var gx = svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0,"+height+")")
        .call(xAxis);
    var bars = svg.selectAll(".bar")
        .data(data)
        .enter()
        .append("g")
    //append rects
    bars.append("rect")
        .attr("class", "bar")
        .attr("y", function (d) {
            return y(d.Candidate);
        })
        .attr("height", y.rangeBand())
        .attr("x", 0)
        .attr("width", function (d) {
            return x(d.Amount);
        })
        .style("fill", "#23395d"); 
    //add a value label to the right of each bar
    bars.append("text")
        .attr("class", "label")
        //y position of the label is halfway down the bar
        .attr("y", function (d) {
            return y(d.Candidate) + y.rangeBand() / 2 + 4;
        })
        //x position is 3 pixels to the right of the bar
        .attr("x", function (d) {
            return x(d.Amount) + 3;
        })
        .text(function (d) {
            return '$'+d.Amount;
        });

            //add an image to the left of each bar
            bars.append("image")
                    .attr("class", "bar_image")
                    //y position of the image is halfway down the bar
                    .attr("y", function(d){
                            console.log(y(d.Candidate));
                            return y(d.Candidate)+margin["top"];
                    })
                    //x position to left of bar
                    .attr("x", function(d) {
                            return -100;
                    })  
                    .attr('xlink:href', function(d){
                            return "/static/images/candidate_images/"+d.Candidate+".png";
                    })
                    .attr("height", (y.rangeBand() - (y.rangeBand() * .4)))
                    .attr("width", (y.rangeBand() - (y.rangeBand() * .4)))
                    console.log(y.rangeBand);
d3.select("#dem-2020-prim").classed("active", true).classed("in", true)

0 个答案:

没有答案