Updating Donut Graph Using D3.js
I've been working for a few hours now and I can't get my donut graph drawn with d3.js to update to new data. My HTML is, <
Solution 1:
As you know, you are only updating the data, which will not change the chart. You also know that, for changing the chart, you'll have to set an "update" selection.
Right now, you just have an "enter" selection:
var path = svg.selectAll("path")
.data(pie(data)).enter().append("path")
.attr("fill", function(d, i) { return color[i]; })
.attr("d", arc);
So, every time you change the dataset
, nothing happens in your chart because your "enter" selection is empty. You could just select something that doesn't exist:
var path = svg.selectAll(".foo")
But this is a terrible solution, because you'll have a bunch of paths piling up in your SVG.
So, the best solution is creating an "enter" and an "update" selection:
//this binds the data:
var path = svg.selectAll("path")
.data(pie(data));
//this is the "enter" selection:
var pathEnter = path.enter().append("path")
.attr("fill", function(d, i) { return color[i]; })
.attr("d", arc);
//this is the "update" selection:
var pathUpdate = path.attr("d", arc);
Check this demo:
var dataset = [40, 20];
var width = 300,
height = 200,
radius = 150;
var color = ['#222', '#EEE'];
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
functionrender(data) {
var pie = d3.pie()
.sort(null);
var arc = d3.arc()
.innerRadius(radius - 100)
.outerRadius(radius - 50);
var path = svg.selectAll("path")
.data(pie(data));
var pathEnter = path.enter().append("path")
.attr("fill", function(d, i) {
return color[i];
})
.attr("d", arc);
var pathUpdate = path.attr("d", arc);
}
render(dataset);
setInterval(function() {
update();
}, 2000);
functionupdate() {
dataset = [Math.random() * 50, Math.random() * 50];
render(dataset);
}
<scriptsrc="https://d3js.org/d3.v4.min.js"></script><divid="pie"></div>
Solution 2:
https://github.com/naveenrk/d3-donut-sanky-chart
[![Updated the donut chart with text displaying the center
const result = {
'fleetView': [
{
'VesselName': 'MOL Emissary',
'IMO': '07158',
'QS': 'Good',
'SeaState': 'Under Way using engine',
'STW': '12.4/11.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '123',
'Speed': '11.7 km',
'CurrentDraught': '10 m',
'Start': '2019-02-18T00:42:55Z',
'End': '0001-01-01T00:00:00Z'
},
{
'VesselName': 'Gulf Baynunah',
'IMO': '9362',
'QS': 'No connection',
'SeaState': 'Under Way using engine',
'STW': '7.0/7.6',
'DepPort': 'No OSL',
'ArrPort': 'No OSL',
'Course': '180',
'Speed': '20 km',
'CurrentDraught': '20 m',
'Start': '2019-02-18T01:48:03Z',
'End': '2019-02-21T00:00:00Z'
},
{
'VesselName': 'Desert Oasis',
'IMO': '9782',
'QS': 'Good',
'SeaState': 'Contrained by her draught',
'STW': '10/11',
'DepPort': 'DK ANB',
'ArrPort': 'DK ANB',
'Course': '155',
'Speed': '15 km',
'CurrentDraught': '10 m',
'Status': 'Good',
'Start': '2019-02-18T01:48:49Z',
'End': '2019-02-23T00:00:00Z'
},
{
'VesselName': 'Maersk Montana',
'IMO': '9312',
'QS': 'Good',
'SeaState': 'At anchor',
'STW': '0/0',
'DepPort': 'EN LND',
'ArrPort': 'EN LND',
'Course': '144',
'Speed': '19 km',
'CurrentDraught': '17 m',
'Start': '2019-02-18T01:20:45Z',
'End': '2019-02-21T00:00:00Z'
},
{
'VesselName': 'New Elias',
'IMO': '90',
'QS': 'Bad',
'SeaState': 'Contrained by her draught',
'STW': '17.4/18.6',
'DepPort': 'SE STK',
'ArrPort': 'SE STK',
'Course': '165',
'Speed': '20 km',
'CurrentDraught': '15 m',
'Start': '2019-02-18T01:49:06Z',
'End': '2019-02-21T00:00:00Z'
},
{
'VesselName': 'MSC Bremen',
'IMO': '',
'QS': 'Good',
'SeaState': 'Under Way using engine',
'STW': '14.4/15.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '175',
'Speed': '16 km',
'CurrentDraught': '11 m',
'Start': '2019-02-18T01:48:05Z',
'End': '2019-02-20T00:00:00Z'
},
{
'VesselName': 'Cornelia Maersk',
'IMO': '',
'QS': 'Poor',
'SeaState': 'Under Way using engine',
'STW': '4.0/4.0',
'DepPort': 'ES MAD',
'ArrPort': 'ES MAD',
'Course': '111',
'Speed': '21 km',
'CurrentDraught': '10 m',
'Start': '2019-02-18T01:50:10Z',
'End': '2019-02-21T00:00:00Z'
},
{
'VesselName': 'Elandra Oak',
'IMO': '',
'QS': 'Good',
'SeaState': 'Under Way using engine',
'STW': '10.4/11.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '180',
'Speed': '20 km',
'CurrentDraught': '11 m',
'Start': '2019-02-18T01:49:21Z',
'End': '2019-02-24T00:00:00Z'
},
{
'VesselName': 'Pinza',
'IMO': '',
'QS': 'Good',
'SeaState': 'Under Way using engine',
'STW': '12.4/11.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '265',
'Speed': '14 km',
'CurrentDraught': '11 m',
'Status': 'Good',
'Start': '2019-02-18T01:49:37Z',
'End': '2019-02-28T00:00:00Z'
},
{
'VesselName': 'Mahadah Silver',
'IMO': '',
'QS': 'Good',
'SeaState': 'Under Way using engine',
'STW': '22.4/24.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '214',
'Speed': '16 km',
'CurrentDraught': '6 m',
'Status': 'Good',
'Start': '2019-02-18T01:47:51Z',
'End': '2019-02-18T00:00:00Z'
},
{
'VesselName': 'Atlantic Breeze',
'IMO': '',
'QS': 'Good',
'SeaState': 'Under Way using engine',
'STW': '14.4/16.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '178',
'Speed': '18 km',
'CurrentDraught': '12 m',
'Status': 'Good',
'Start': '2019-02-18T01:47:15Z',
'End': '2019-02-25T00:00:00Z'
},
{
'VesselName': 'Kronviken',
'IMO': '',
'QS': 'Good',
'SeaState': 'Under Way using engine',
'STW': '20.4/21.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '198',
'Speed': '15 km',
'CurrentDraught': '11 m',
'Status': 'Good',
'Start': '2019-02-18T01:45:54Z',
'End': '2019-02-21T00:00:00Z'
},
{
'VesselName': 'NS Stream',
'IMO': '',
'QS': 'Bad',
'SeaState': 'Under Way using engine',
'STW': '11.4/11.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '159',
'Speed': '16 km',
'CurrentDraught': '9 m',
'Status': 'Good',
'Start': '2019-02-17T22:56:15Z',
'End': '2019-02-19T00:00:00Z'
},
{
'VesselName': 'Maersk Shenzhen',
'IMO': '',
'QS': 'Poor',
'SeaState': 'Under Way using engine',
'STW': '15.4/16.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '256',
'Speed': '21 km',
'CurrentDraught': '20 m',
'Status': 'Good',
'Start': '2019-02-18T01:49:24Z',
'End': '2019-02-23T00:00:00Z'
},
{
'VesselName': 'Lambi',
'IMO': '',
'QS': 'Good',
'SeaState': 'Under Way using engine',
'STW': '25.5/26.6',
'DepPort': 'DK RNN',
'ArrPort': 'DK RNN',
'Course': '297',
'Speed': '21 km',
'CurrentDraught': '11 m',
'Status': 'Good',
'Start': '2019-02-18T01:47:03Z',
'End': '2019-02-28T00:00:00Z'
}
]
};
functiongroupingBy(data, groupby) {
return _.groupBy(data, groupby);
}
functiongetObjectKeys(groupByData) {
returnObject.keys(groupByData);
}
const newGroupValue = groupingBy(result.fleetView, 'SeaState');
const newKeys = getObjectKeys(newGroupValue);
const dataset = [];
// tslint:disable-next-line: forinfor (const k in newGroupValue) {
const kk = { name: k, value: newGroupValue[k].length };
dataset.push(kk);
}
const userSelectedColors = ['value'];
const totalCount = _.sumBy(userSelectedColors, _.partial(_.sumBy, dataset));
console.log(totalCount);
const color = d3.scaleOrdinal()
.domain(newKeys)
.range(['#8BC2CA', '#5CAAB5', '#B9DADF']);
const pie = d3.pie()
.value(function (d: any) { return d.value; })
.sort(null)
.padAngle(.03);
const w = 250, h = 200;
// donut sizeconst outerRadius = 60;
const innerRadius = 100;
const arc = d3.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius);
const svg = d3.select('#chart')
.append('svg')
.attr('width', w)
.attr('height', h + 100)
.attr('class', 'shadow')
.append('g')
.attr('transform', 'translate(' + w / 2 + ',' + h / 2 + ')');
const path = svg.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', (d: any, i: any) =>color(d.data.name));
path.transition()
.duration(1000)
.attrTween('d', function (d) {
const interpolate = d3.interpolate({ startAngle: 0, endAngle: 0 }, d);
returnfunction (t) {
returnarc(interpolate(t));
};
});
const restOfTheData = function () {
const text = svg.selectAll('text')
.data(pie(dataset))
.enter()
.append('text')
.attr('transform', function (d: any) {
const _d = arc.centroid(d);
_d[0] *= 1; // multiply by a constant factor
_d[1] *= 1; // multiply by a constant factorreturn'translate(' + _d + ')';
})
.attr('dy', '.50em')
.attr('text-anchor', 'middle')
.style('text-anchor', 'middle')
.text((d: any) => {
return d.data.value;
});
svg.append('text')
.attr('text-anchor', 'middle')
.attr('font-size', '2.5em')
.attr('y', 8)
.text(totalCount);
svg.append('text')
.attr('text-anchor', 'middle')
.attr('font-size', '1.5em')
.attr('y', 25)
.text('vessel');
const legendRectSize = 20;
const legendSpacing = 7;
const legendHeight = legendRectSize + legendSpacing;
const legend = svg.selectAll('.legend')
.data(color.domain())
.enter()
.append('g')
.attr('class', '.legend')
.attr('transform', (d: any, i: any) =>'translate(-95,' + ((i * legendHeight) + 110) + ')');
legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.attr('rx', 20)
.attr('ry', 20)
.style('fill', color);
legend.append('text')
.attr('x', 30)
.attr('y', 15)
.text(function (d) {
return d;
})
.attr('fill', '#152935')
.attr('font-size', '1.2em');
};
setTimeout(restOfTheData, 1000);
/*
Prerequisite -
"d3": "5.7.0",
"d3-sankey": "^0.7.1",
"lodash": "^4.17.11"
*/
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
// For Donut chart
<divid="chart"class="chart-container">
Post a Comment for "Updating Donut Graph Using D3.js"