Datacrawler
Datacrawler

Reputation: 2886

Set max height to an already responsive D3 donut chart

I have created a donut chart and I am trying to make it responsive. I want the height to have a maximum value. If the window size changes, the donut changes attributes (width and height). Now, I want to set a maximum height value and off course I need the ratio to remain the same. Note that I want the donut chart to be horizontally aligned (same margin from the right and left of the screen).

I have tried changing the values in the width by using the window.innerWidth and innerHeight with no success. I have also tried adding a max attribute for the height in the D3 part of my code.

var dataset = {
    numbers: [3200, 5400, 8600]
};

var width = 500,
  height = 500,
  radius = Math.min(width, height) / 2;

var enterClockwise = {
    startAngle: 0,
    endAngle: 0
};

var enterAntiClockwise = {
    startAngle: Math.PI * 2,
    endAngle: Math.PI * 2
};

//var color = d3.scale.category20();
var color = d3.scale.ordinal().range([d3.rgb("#c7003b"), d3.rgb('#000'), d3.rgb('#ccc'),d3.rgb('transparent')])

var pie = d3.layout.pie()
  .sort(null);

var arc = d3.svg.arc()
  .innerRadius(radius - 80)
  .outerRadius(radius - 40);
  
var arcThin = d3.svg.arc()
  .innerRadius(radius - 65)
  .outerRadius(radius - 55);

var svg = d3.select('#Donut-chart').append('svg')
     .attr('id', 'Donut-chart-render')
     .attr("width", '100%')
     .attr("height", '100%')
     .attr('viewBox', (-width / 2) + ' ' + (-height / 2) + ' ' + width + ' ' + height)
     .attr('preserveAspectRatio', 'xMinYMin').append("g").attr("class", "parent");

var angleData = pie(dataset.numbers);
angleData[1].startAngle = 0;
angleData[1].endAngle = -angleData[1].endAngle + angleData[0].endAngle;
angleData[2].startAngle = angleData[0].endAngle;
angleData[2].endAngle = (2*Math.PI) + angleData[1].endAngle;
	 
var path = svg.selectAll("path")
  .data(angleData)
  .enter().append("path")
    .attr("fill", function (d, i) { return color(i); })
    .attr("d", function(d){
      	return arc(enterClockwise);
    })
    .each(function (d) {
        this._current = {
            data: d.data,
            value: d.value,
            startAngle: enterClockwise.startAngle,
            endAngle: enterClockwise.endAngle
        } 
    });

path.transition()
    .duration(750)
    .attrTween("d", arcTween);


	
function createChart() {
    path = path.data(pie(dataset[this.value]));
    path.enter().append("path")
        .attr("fill", function (d, i) {
            return color(i);
        })
        .attr("d", arc(enterAntiClockwise))
        .each(function (d) {
            this._current = {
                data: d.data,
                value: d.value,
                startAngle: enterAntiClockwise.startAngle,
                endAngle: enterAntiClockwise.endAngle
            };
        });

}

function arcTween(a, j) {
    var i = d3.interpolate(this._current, a);
    this._current = i(0);
    return function (t) {
        return (j === (dataset.numbers.length - 1)) ? arcThin(i(t)) : arc(i(t));
    };
}

function type(d) {
    d.value = +d.value;
    return d;
}
@import url(https://fonts.googleapis.com/css?family=Karla);body{font-family:Karla,sans-serif;margin:auto;position:relative}.text{text-anchor:middle;color:#000;font-size:1.7em;font-weight:700;text-transform:uppercase}#legend{align-items:center;border-radius:5px;display:flex;height:0%;justify-content:space-around;width:95%;font-size:25px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script>

<div id="Donut-chart"></div>

Upvotes: 1

Views: 958

Answers (1)

Teo Dragovic
Teo Dragovic

Reputation: 3518

Remove width, height and preserveAspectRatio attributes from SVG element and set max-height on it via CSS. Like so:

var dataset = {
    numbers: [3200, 5400, 8600]
};

var width = 500,
  height = 500,
  radius = Math.min(width, height) / 2;

var enterClockwise = {
    startAngle: 0,
    endAngle: 0
};

var enterAntiClockwise = {
    startAngle: Math.PI * 2,
    endAngle: Math.PI * 2
};

//var color = d3.scale.category20();
var color = d3.scale.ordinal().range([d3.rgb("#c7003b"), d3.rgb('#000'), d3.rgb('#ccc'),d3.rgb('transparent')])

var pie = d3.layout.pie()
  .sort(null);

var arc = d3.svg.arc()
  .innerRadius(radius - 80)
  .outerRadius(radius - 40);
  
var arcThin = d3.svg.arc()
  .innerRadius(radius - 65)
  .outerRadius(radius - 55);

var svg = d3.select('#Donut-chart').append('svg')
     .attr('id', 'Donut-chart-render')
     // .attr("width", '100%')
     // .attr("height", '100%')
     .attr('viewBox', (-width / 2) + ' ' + (-height / 2) + ' ' + width + ' ' + height)
     //.attr('preserveAspectRatio', 'xMinYMin')
.append("g").attr("class", "parent");

var angleData = pie(dataset.numbers);
angleData[1].startAngle = 0;
angleData[1].endAngle = -angleData[1].endAngle + angleData[0].endAngle;
angleData[2].startAngle = angleData[0].endAngle;
angleData[2].endAngle = (2*Math.PI) + angleData[1].endAngle;
	 
var path = svg.selectAll("path")
  .data(angleData)
  .enter().append("path")
    .attr("fill", function (d, i) { return color(i); })
    .attr("d", function(d){
      	return arc(enterClockwise);
    })
    .each(function (d) {
        this._current = {
            data: d.data,
            value: d.value,
            startAngle: enterClockwise.startAngle,
            endAngle: enterClockwise.endAngle
        } 
    });

path.transition()
    .duration(750)
    .attrTween("d", arcTween);


	
function createChart() {
    path = path.data(pie(dataset[this.value]));
    path.enter().append("path")
        .attr("fill", function (d, i) {
            return color(i);
        })
        .attr("d", arc(enterAntiClockwise))
        .each(function (d) {
            this._current = {
                data: d.data,
                value: d.value,
                startAngle: enterAntiClockwise.startAngle,
                endAngle: enterAntiClockwise.endAngle
            };
        });

}

function arcTween(a, j) {
    var i = d3.interpolate(this._current, a);
    this._current = i(0);
    return function (t) {
        return (j === (dataset.numbers.length - 1)) ? arcThin(i(t)) : arc(i(t));
    };
}

function type(d) {
    d.value = +d.value;
    return d;
}
#Donut-chart svg {
  max-height: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script>

<div id="Donut-chart"></div>

Upvotes: 0

Related Questions