-1

I'm using Matt Kohl's animated donut chart for use in an element on my site, I've restyled it but cannot figure out how to reposition it to anywhere I want on the page. It's fixed within the middle of the browser window.

Rather than place all of the code in here I'll give you a link to the code in his tutorial:

https://bl.ocks.org/mattkohl/9f3a283813cf0226311f41595582c9eb

I have tried everything within the HTML and CSS to manipulate the size of the container svg and the positioning of the chart but to no avail.

It's clearly somethinhg that needs to be changed in the JavaScript but I'm no expert so thought I'd ask in here.

Anas
  • 971
  • 13
  • 28
Marc
  • 348
  • 1
  • 3
  • 9

1 Answers1

0

Here is the relevant code to look at. The width and height variables will control the svg size as they are passed in with .attr("width", width) and .attr("height", height). Now to position the svg better, I would give it either a class or id as shown below. You can then use css positioning to position the svg where you want.

var duration = 1500,
transition = 200,
percent = 45,
width = window.innerWidth - 20,
height = window.innerHeight - 20;

var dataset = {
        lower: calcPercent(0),
        upper: calcPercent(percent)
    },
    radius = Math.min(width, height) / 3,
    pie = d3.layout.pie().sort(null),
    format = d3.format(".0%");

var arc = d3.svg.arc()
    .innerRadius(radius * .8)
    .outerRadius(radius);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("id", "yourid")
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

#yourid{position: absolute;top:50%;}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Animated Donut with Percentage</title>
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
body {
    width: 100%;
    height: 100%;
    font-family: Lora,"Helvetica Neue",Helvetica,Arial,sans-serif;
    color: #fff;
    background-color: #000;
}
path.color0 {
    fill: #fff;
}
path.color1 {
    fill: rgba(255,255,255,.3);
}
text {
    font-size: 7em;
    font-weight: 400;
    line-height: 16em;
    fill: #fff;
}

</style>
</head>
<body>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="text/javascript">
var duration = 1500,
    transition = 200,
    percent = 45,
    width = 300,
    height = 300;

var dataset = {
            lower: calcPercent(0),
            upper: calcPercent(percent)
        },
        radius = Math.min(width, height) / 3,
        pie = d3.layout.pie().sort(null),
        format = d3.format(".0%");

var arc = d3.svg.arc()
        .innerRadius(radius * .8)
        .outerRadius(radius);

var svg = d3.select("body").append("svg")
        .attr("id", "yourid")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var path = svg.selectAll("path")
                .data(pie(dataset.lower))
                .enter().append("path")
                .attr("class", function (d, i) {
                    return "color" + i
                })
                .attr("d", arc)
                .each(function (d) {
                    this._current = d;
                });

var text = svg.append("text")
        .attr("text-anchor", "middle")
        .attr("dy", ".3em");

var progress = 0;

var timeout = setTimeout(function () {
    clearTimeout(timeout);
    path = path.data(pie(dataset.upper));
    path.transition().duration(duration).attrTween("d", function (a) {
        var i = d3.interpolate(this._current, a);
        var i2 = d3.interpolate(progress, percent)
        this._current = i(0);
        return function (t) {
            text.text(format(i2(t) / 100));
            return arc(i(t));
        };
    });
}, 200);

function calcPercent(percent) {
    return [percent, 100 - percent];
};
</script>

The attached snippet puts the changes together with dummy values for size and positioning.

pmkro
  • 2,542
  • 2
  • 17
  • 25
  • Hi, Thanks for your answer, I really appreciate it. I've managed to get get the stroke of the chart to the correct size as it looks on browser full width on my iMac, but when I drag the width of the browser inwards to smaller screen sizes and refresh, the radius of the chart diminishes and therefore squashes inwards on the percentage number. Is there any way to lock the radial width of the chart strokes so it is maintained across all viewport sizes. I'm guessing it is responsive by default which is why the width changes on smaller screens? Thanks Marc – Marc Mar 17 '18 at 06:34
  • If you are have set your height and width to px values instead of percentages it shouldn't change size. – pmkro Mar 17 '18 at 14:14
  • There are two width and height parameters: var duration = 1500, transition = 200, percent = 80, width = window.innerWidth - 20, height = window.innerHeight - 20; and: var svg = d3.select("body").append("svg") .attr("width", 185) .attr("height", 245) .append("g") .attr("transform", "translate(" + 103 + "," + 100 + ")"); The first set is different to yours since it declares "window.innerWidth" and "window.innerHeight". And I was assuming both measurements in both blocks of code state figures in pixels not percentages? – Marc Mar 18 '18 at 06:58
  • Window.innerWidth and height are what you want to change. Those will return the current window size in px. Which is why the chart circle gets smaller. Make them a set px amount like 1920 width by 980 or whatever takes up tour screen nicely. – pmkro Mar 18 '18 at 14:08