Creating scrollbars with SVG and d3.js

2019-04-07 13:26发布

问题:

Right now I've used d3 to create several "boxes" that are merely SVG rectangles with text:

var canvas = d3.select("body").append("svg")
    .attr("width", 800)
    .attr("height", 500);


//specifies drawing area for each box
var boxes = canvas.selectAll("rect")
    .data(classData)
    .enter();

boxes.append("rect")
        .attr("width", boxWidth)
        .attr("height", boxHeight)
        .attr("fill", boxColor)
        .attr("x", function (d, i) { return i * 2 * boxWidth });


text.append("text")
        .attr("fill", textColor)
        .attr("x", function (d, i) 
              { return i * 2 * boxWidth + 5 })
        .attr("y", 20)
        .style("width", "20px")
        .style("overflow-x", "scroll")
        .text(function(d) {return d.name});

Now what I'd like to do is add scrollbars to each box when the text is outside the bounds of the box. I've seen a couple examples that created a div and used CSS to handle the overflow. However, I will have multiple (variable) boxes and I'm not sure how to go about this.

Any suggestions?

-- UPDATE --

I was able to get scrollbars to appear by appending svg elements to a div that controls scrolling with CSS styles.

.container {
    height: 225px;
    width: 175px;
    border:2px solid #000;
    overflow-y: scroll;
    overflow-x: hidden;
}

svg {
    display: block;
    width: 200%;
    height: 200%;
}

However, the scrolling seems to be affected only by the width and height percentages of the svg element rather than the rect element that is drawn in the div. In other words, if the rectangle is too large, you still can not scroll to see all of it, unless you increase the width and height of the svg element.

Is there a way I can have the div scroll based on what is drawn inside of it? Or should I try to somehow calculate and change the width and height attributes of the svg element?

view the code here

回答1:

Try to add the viewBox svg property:

var rectangle = container.append("svg")
    .attr("viewBox", "0,0,150,420")
    .append("rect")
    .attr("width", 150)
    .attr("height", 420)
    .attr("fill", "steelblue")
    .attr("x", 0)
    .attr("y", 0);

jsfiddle