Horizontal stacked bar: one tick not displaying - d3.js

Please can somebody tell me why the bar in top right corner is more elevated than all the others? When I use larger data-set it actually creates a stacked bar with multiple parts that seems not to be part of the chart and there is no right y axis tick value for it.
var dataset = [
{
"stopId": "165",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "10:53:00",
"stopId": "165",
"passengers": 12
},
{
"yValue": "101000018",
"xValue": 5,
"time": "11:23:00",
"stopId": "165",
"passengers": 22
},
{
"yValue": "101000019",
"xValue": 5,
"time": "11:53:00",
"stopId": "165",
"passengers": 6
},
{
"yValue": "101000020",
"xValue": 5,
"time": "12:23:00",
"stopId": "165",
"passengers": 14
},
{
"yValue": "101000021",
"xValue": 5,
"time": "12:51:00",
"stopId": "165",
"passengers": 13
},
{
"yValue": "101000022",
"xValue": 5,
"time": "13:24:00",
"stopId": "165",
"passengers": 21
},
{
"yValue": "101000023",
"xValue": 5,
"time": "13:54:00",
"stopId": "165",
"passengers": 28
},
{
"yValue": "101000024",
"xValue": 5,
"time": "14:24:00",
"stopId": "165",
"passengers": 28
},
{
"yValue": "101000025",
"xValue": 5,
"time": "14:54:00",
"stopId": "165",
"passengers": 4
},
{
"yValue": "101000026",
"xValue": 5,
"time": "15:23:00",
"stopId": "165",
"passengers": 18
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:55:00",
"stopId": "165",
"passengers": 5
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:10:00",
"stopId": "165",
"passengers": 27
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:25:00",
"stopId": "165",
"passengers": 6
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:38:00",
"stopId": "165",
"passengers": 18
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:55:00",
"stopId": "165",
"passengers": 26
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:10:00",
"stopId": "165",
"passengers": 29
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:25:00",
"stopId": "165",
"passengers": 24
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:40:00",
"stopId": "165",
"passengers": 29
}
],
"name": "Passengers"
},
{
"stopId": "65",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "10:54:00",
"stopId": "65",
"passengers": 20
},
{
"yValue": "101000018",
"xValue": 5,
"time": "11:24:00",
"stopId": "65",
"passengers": 22
},
{
"yValue": "101000019",
"xValue": 5,
"time": "11:54:00",
"stopId": "65",
"passengers": 8
},
{
"yValue": "101000020",
"xValue": 5,
"time": "12:24:00",
"stopId": "65",
"passengers": 27
},
{
"yValue": "101000021",
"xValue": 5,
"time": "12:52:00",
"stopId": "65",
"passengers": 26
},
{
"yValue": "101000022",
"xValue": 5,
"time": "13:25:00",
"stopId": "65",
"passengers": 24
},
{
"yValue": "101000023",
"xValue": 5,
"time": "13:55:00",
"stopId": "65",
"passengers": 25
},
{
"yValue": "101000024",
"xValue": 5,
"time": "14:25:00",
"stopId": "65",
"passengers": 28
},
{
"yValue": "101000025",
"xValue": 5,
"time": "14:55:00",
"stopId": "65",
"passengers": 7
},
{
"yValue": "101000026",
"xValue": 5,
"time": "15:24:00",
"stopId": "65",
"passengers": 23
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:56:00",
"stopId": "65",
"passengers": 18
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:11:00",
"stopId": "65",
"passengers": 4
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:26:00",
"stopId": "65",
"passengers": 29
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:39:00",
"stopId": "65",
"passengers": 19
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:56:00",
"stopId": "65",
"passengers": 28
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:11:00",
"stopId": "65",
"passengers": 21
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:26:00",
"stopId": "65",
"passengers": 26
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:41:00",
"stopId": "65",
"passengers": 19
}
],
"name": "Passengers"
},
{
"stopId": "63",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "10:55:00",
"stopId": "63",
"passengers": 10
},
{
"yValue": "101000018",
"xValue": 5,
"time": "11:25:00",
"stopId": "63",
"passengers": 9
},
{
"yValue": "101000019",
"xValue": 5,
"time": "11:55:00",
"stopId": "63",
"passengers": 21
},
{
"yValue": "101000020",
"xValue": 5,
"time": "12:25:00",
"stopId": "63",
"passengers": 28
},
{
"yValue": "101000021",
"xValue": 5,
"time": "12:53:00",
"stopId": "63",
"passengers": 8
},
{
"yValue": "101000022",
"xValue": 5,
"time": "13:26:00",
"stopId": "63",
"passengers": 13
},
{
"yValue": "101000023",
"xValue": 5,
"time": "13:56:00",
"stopId": "63",
"passengers": 29
},
{
"yValue": "101000024",
"xValue": 5,
"time": "14:26:00",
"stopId": "63",
"passengers": 28
},
{
"yValue": "101000025",
"xValue": 5,
"time": "14:56:00",
"stopId": "63",
"passengers": 14
},
{
"yValue": "101000026",
"xValue": 5,
"time": "15:25:00",
"stopId": "63",
"passengers": 30
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:57:00",
"stopId": "63",
"passengers": 21
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:12:00",
"stopId": "63",
"passengers": 10
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:27:00",
"stopId": "63",
"passengers": 16
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:40:00",
"stopId": "63",
"passengers": 24
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:57:00",
"stopId": "63",
"passengers": 3
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:12:00",
"stopId": "63",
"passengers": 15
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:27:00",
"stopId": "63",
"passengers": 23
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:42:00",
"stopId": "63",
"passengers": 21
}
],
"name": "Passengers"
},
{
"stopId": "47",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "10:56:00",
"stopId": "47",
"passengers": 13
},
{
"yValue": "101000018",
"xValue": 5,
"time": "11:26:00",
"stopId": "47",
"passengers": 7
},
{
"yValue": "101000019",
"xValue": 5,
"time": "11:56:00",
"stopId": "47",
"passengers": 21
},
{
"yValue": "101000020",
"xValue": 5,
"time": "12:26:00",
"stopId": "47",
"passengers": 22
},
{
"yValue": "101000021",
"xValue": 5,
"time": "12:54:00",
"stopId": "47",
"passengers": 28
},
{
"yValue": "101000022",
"xValue": 5,
"time": "13:27:00",
"stopId": "47",
"passengers": 30
},
{
"yValue": "101000023",
"xValue": 5,
"time": "13:57:00",
"stopId": "47",
"passengers": 20
},
{
"yValue": "101000024",
"xValue": 5,
"time": "14:27:00",
"stopId": "47",
"passengers": 17
},
{
"yValue": "101000025",
"xValue": 5,
"time": "14:57:00",
"stopId": "47",
"passengers": 14
},
{
"yValue": "101000026",
"xValue": 5,
"time": "15:26:00",
"stopId": "47",
"passengers": 11
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:58:00",
"stopId": "47",
"passengers": 28
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:13:00",
"stopId": "47",
"passengers": 7
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:28:00",
"stopId": "47",
"passengers": 24
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:41:00",
"stopId": "47",
"passengers": 29
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:58:00",
"stopId": "47",
"passengers": 19
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:13:00",
"stopId": "47",
"passengers": 23
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:28:00",
"stopId": "47",
"passengers": 19
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:43:00",
"stopId": "47",
"passengers": 12
}
],
"name": "Passengers"
},
{
"stopId": "185",
"data": [
{
"yValue": "101000026",
"xValue": 5,
"time": "15:27:00",
"stopId": "185",
"passengers": 23
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:59:00",
"stopId": "185",
"passengers": 11
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:14:00",
"stopId": "185",
"passengers": 24
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:29:00",
"stopId": "185",
"passengers": 16
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:42:00",
"stopId": "185",
"passengers": 22
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:59:00",
"stopId": "185",
"passengers": 23
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:14:00",
"stopId": "185",
"passengers": 27
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:29:00",
"stopId": "185",
"passengers": 29
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:44:00",
"stopId": "185",
"passengers": 24
},
{
"yValue": "101000035",
"xValue": 5,
"time": "17:59:00",
"stopId": "185",
"passengers": 19
},
{
"yValue": "101000036",
"xValue": 5,
"time": "18:14:00",
"stopId": "185",
"passengers": 23
},
{
"yValue": "101000037",
"xValue": 5,
"time": "18:29:00",
"stopId": "185",
"passengers": 6
},
{
"yValue": "101000038",
"xValue": 5,
"time": "18:44:00",
"stopId": "185",
"passengers": 24
},
{
"yValue": "101000039",
"xValue": 5,
"time": "18:59:00",
"stopId": "185",
"passengers": 26
},
{
"yValue": "101000040",
"xValue": 5,
"time": "19:29:00",
"stopId": "185",
"passengers": 21
},
{
"yValue": "101000041",
"xValue": 5,
"time": "19:59:00",
"stopId": "185",
"passengers": 23
},
{
"yValue": "101000042",
"xValue": 5,
"time": "20:25:00",
"stopId": "185",
"passengers": 20
},
{
"yValue": "101000043",
"xValue": 5,
"time": "21:25:00",
"stopId": "185",
"passengers": 29
}
],
"name": "Passengers"
}
];
var margins = {
top: 12,
left: 100,
right: 50,
bottom: 34
};
var numberOfRecords = 0;
var dataset = dataset.map(function(d) {
numberOfRecords = 0;
return d.data.map(function(o, i) {
numberOfRecords++;
return {
y: o.xValue,
x: o.yValue,
name: d.name,
stopId: o.stopId,
passengers: o.passengers,
time: o.time
};
});
});
d3.select(window).on("resize", throttle);
var stack = d3.layout.stack();
stack(dataset);
var dataset = dataset.map(function(group) {
return group.map(function(d) {
// Invert the x and y values, and y0 becomes x0
return {
x: d.y,
y: d.x,
x0: d.y0,
name: d.name,
stopId: d.stopId,
passengers: d.passengers,
time: d.time
};
});
});
var yValuesTripId = dataset[0].map(function(d) {
return d.y;
});
var yValuesFirstStopTimes = dataset[0].map(function(d) {
// return (d.time.slice(0, -3) + (Math.floor(Math.random() * (20000 - 1 + 1)) + 1));
return removeSecondsFromHHMMSS(d.time);
});
var yValuesLastStopTimes = dataset[dataset.length - 1].map(function(d) {
// return (d.time.slice(0, -3) + (Math.floor(Math.random() * (20000 - 1 + 1)) + 1));
return removeSecondsFromHHMMSS(d.time);
});
var xMax = d3.max(dataset, function(group) {
return d3.max(group, function(d) {
return d.x + d.x0;
});
});
var tooltip = d3.select("#chartDiv")
.append('div')
.attr('id', 'tooltip')
.attr('class', 'hidden');
const chartArea = $("#chartDiv");
var width = chartArea.innerWidth() - margins.left - margins.right;
var barHeight = 10;
var height = (numberOfRecords * 15) - margins.top - margins.bottom;
var svg, xScale, yScaleLeft, yScaleRight, rects;
draw(width, height);
function draw(width, height) {
svg = d3.select("#chartDiv")
.append('svg')
.attr('width', width + margins.left + margins.right)
.attr('height', height + margins.top + margins.bottom)
.append('g')
.attr('transform', 'translate(' + margins.left + ',' + margins.top + ')');
xScale = d3.scale.linear()
.domain([0, xMax])
.range([0, width - margins.right]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(0);
yScaleLeft = d3.scale.ordinal()
.domain(yValuesTripId)
.rangeRoundBands([0, height], .1);
var yAxisLeft = d3.svg.axis()
.scale(yScaleLeft)
.orient('left')
.tickFormat(function(d, i) {
return yValuesFirstStopTimes[i];
});
yScaleRight = d3.scale.ordinal()
.domain(yValuesTripId)
.rangeRoundBands([0, height], .1);
var yAxisRight = d3.svg.axis()
.scale(yScaleRight)
.orient('right')
.tickPadding(-25)
.tickFormat(function(d, i) {
return yValuesLastStopTimes[i];
});
var groups = svg.selectAll('g')
.data(dataset)
.enter()
.append('g');
rects = groups.selectAll('rect')
.data(function(d) {
return d;
})
.enter()
.append('rect')
.attr('x', function(d) {
return xScale(d.x0);
})
.attr('y', function(d, i) {
return yScaleLeft(d.y);
})
.attr('height', function(d) {
return barHeight;
})
.attr('width', function(d) {
return xScale(d.x);
})
.attr('fill', function(d) {
return getColor(d.passengers);
})
.attr('stroke', 'white')
.on('mouseover', function(d) {
var xPos = d3.event.pageX - 310;
var yPos = d3.event.pageY - 110;
d3.select('#tooltip')
.style("left", xPos + "px")
.style("top", yPos + "px")
.style('width', '250px')
.text("Trip " + d.y + '|Passengers:' + d.passengers + '|Stop ' + d.stopId + '|time ' + removeSecondsFromHHMMSS(d.time));
d3.select('#tooltip').classed('hidden', false);
})
.on('mouseout', function() {
d3.select('#tooltip').classed('hidden', true);
});
svg.append('g')
.attr('class', 'axis')
.attr('id','busOccupancyChartXAxis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
svg.append('g')
.attr('class', 'axis')
.call(yAxisLeft);
svg.append("text")
.attr("x", 0 - margins.left)
.attr("y", 0)
.text("Departure Time");
const newWidth = width - 20;
svg.append('g')
.attr('class', 'axis')
.attr("transform", "translate(" + newWidth + ",0)")
.call(yAxisRight);
svg.append("text")
.attr("x", width - margins.right + 10)
.attr("y", 0)
.text("Arrival Time");
}
function redraw() {
width = chartArea.innerWidth() - margins.left - margins.right;
d3.select('svg').remove();
d3.select('#legend').remove();
draw(width, height);
}
var throttleTimer;
function throttle() {
window.clearTimeout(throttleTimer);
throttleTimer = window.setTimeout(function() {
redraw();
}, 200);
}
function getColor(numberOfPassengers) {
cellColor = "";
if (numberOfPassengers < 10) {
cellColor = "#585858";
} else if (numberOfPassengers < 20) {
cellColor = "#FFCC00";
} else if (numberOfPassengers < 25) {
cellColor = "#FF3300";
} else {
cellColor = "#A00000";
}
return cellColor;
}
function removeSecondsFromHHMMSS (time) {
return time.slice(0, -3)
}
#chartDiv #xaxis .domain {
fill: none;
stroke: #000;
}
#chartDiv #xaxis text,
#yaxis text {
font-size: 12px;
}
#chartDiv .axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
display: none;
}
#chartDiv .axis text {
font-family: sans-serif;
font-size: 11px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chartDiv">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chartDiv">
</div>

If you inspect the DOM, you're gonna see that this rectangle is actually a bunch of rectangles, all in the same position. They are there, sitting on the top, because they have no y attribute.
The problem is not your code: the problem is actually your data. For each bus stop, you have a yValue starting at 101000017...
"yValue": "101000017"
... and ending at 101000034:
"yValue": "101000034"
Which are used for the ordinal scale. So, each bus stop should have the same y values, since they use the same ordinal scale.
However, for the last group, the yValues starts at 101000026 and ends at 101000043. When you use those values with the y scale, the last ones (from 101000034 on) return undefined and the rectangles end up in the top corner.
Solution: audit your data.
In the following snippet, I just changed the yValues of the last group to match the other groups.
Here is the working code:
var dataset = [
{
"stopId": "165",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "10:53:00",
"stopId": "165",
"passengers": 12
},
{
"yValue": "101000018",
"xValue": 5,
"time": "11:23:00",
"stopId": "165",
"passengers": 22
},
{
"yValue": "101000019",
"xValue": 5,
"time": "11:53:00",
"stopId": "165",
"passengers": 6
},
{
"yValue": "101000020",
"xValue": 5,
"time": "12:23:00",
"stopId": "165",
"passengers": 14
},
{
"yValue": "101000021",
"xValue": 5,
"time": "12:51:00",
"stopId": "165",
"passengers": 13
},
{
"yValue": "101000022",
"xValue": 5,
"time": "13:24:00",
"stopId": "165",
"passengers": 21
},
{
"yValue": "101000023",
"xValue": 5,
"time": "13:54:00",
"stopId": "165",
"passengers": 28
},
{
"yValue": "101000024",
"xValue": 5,
"time": "14:24:00",
"stopId": "165",
"passengers": 28
},
{
"yValue": "101000025",
"xValue": 5,
"time": "14:54:00",
"stopId": "165",
"passengers": 4
},
{
"yValue": "101000026",
"xValue": 5,
"time": "15:23:00",
"stopId": "165",
"passengers": 18
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:55:00",
"stopId": "165",
"passengers": 5
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:10:00",
"stopId": "165",
"passengers": 27
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:25:00",
"stopId": "165",
"passengers": 6
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:38:00",
"stopId": "165",
"passengers": 18
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:55:00",
"stopId": "165",
"passengers": 26
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:10:00",
"stopId": "165",
"passengers": 29
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:25:00",
"stopId": "165",
"passengers": 24
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:40:00",
"stopId": "165",
"passengers": 29
}
],
"name": "Passengers"
},
{
"stopId": "65",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "10:54:00",
"stopId": "65",
"passengers": 20
},
{
"yValue": "101000018",
"xValue": 5,
"time": "11:24:00",
"stopId": "65",
"passengers": 22
},
{
"yValue": "101000019",
"xValue": 5,
"time": "11:54:00",
"stopId": "65",
"passengers": 8
},
{
"yValue": "101000020",
"xValue": 5,
"time": "12:24:00",
"stopId": "65",
"passengers": 27
},
{
"yValue": "101000021",
"xValue": 5,
"time": "12:52:00",
"stopId": "65",
"passengers": 26
},
{
"yValue": "101000022",
"xValue": 5,
"time": "13:25:00",
"stopId": "65",
"passengers": 24
},
{
"yValue": "101000023",
"xValue": 5,
"time": "13:55:00",
"stopId": "65",
"passengers": 25
},
{
"yValue": "101000024",
"xValue": 5,
"time": "14:25:00",
"stopId": "65",
"passengers": 28
},
{
"yValue": "101000025",
"xValue": 5,
"time": "14:55:00",
"stopId": "65",
"passengers": 7
},
{
"yValue": "101000026",
"xValue": 5,
"time": "15:24:00",
"stopId": "65",
"passengers": 23
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:56:00",
"stopId": "65",
"passengers": 18
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:11:00",
"stopId": "65",
"passengers": 4
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:26:00",
"stopId": "65",
"passengers": 29
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:39:00",
"stopId": "65",
"passengers": 19
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:56:00",
"stopId": "65",
"passengers": 28
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:11:00",
"stopId": "65",
"passengers": 21
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:26:00",
"stopId": "65",
"passengers": 26
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:41:00",
"stopId": "65",
"passengers": 19
}
],
"name": "Passengers"
},
{
"stopId": "63",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "10:55:00",
"stopId": "63",
"passengers": 10
},
{
"yValue": "101000018",
"xValue": 5,
"time": "11:25:00",
"stopId": "63",
"passengers": 9
},
{
"yValue": "101000019",
"xValue": 5,
"time": "11:55:00",
"stopId": "63",
"passengers": 21
},
{
"yValue": "101000020",
"xValue": 5,
"time": "12:25:00",
"stopId": "63",
"passengers": 28
},
{
"yValue": "101000021",
"xValue": 5,
"time": "12:53:00",
"stopId": "63",
"passengers": 8
},
{
"yValue": "101000022",
"xValue": 5,
"time": "13:26:00",
"stopId": "63",
"passengers": 13
},
{
"yValue": "101000023",
"xValue": 5,
"time": "13:56:00",
"stopId": "63",
"passengers": 29
},
{
"yValue": "101000024",
"xValue": 5,
"time": "14:26:00",
"stopId": "63",
"passengers": 28
},
{
"yValue": "101000025",
"xValue": 5,
"time": "14:56:00",
"stopId": "63",
"passengers": 14
},
{
"yValue": "101000026",
"xValue": 5,
"time": "15:25:00",
"stopId": "63",
"passengers": 30
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:57:00",
"stopId": "63",
"passengers": 21
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:12:00",
"stopId": "63",
"passengers": 10
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:27:00",
"stopId": "63",
"passengers": 16
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:40:00",
"stopId": "63",
"passengers": 24
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:57:00",
"stopId": "63",
"passengers": 3
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:12:00",
"stopId": "63",
"passengers": 15
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:27:00",
"stopId": "63",
"passengers": 23
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:42:00",
"stopId": "63",
"passengers": 21
}
],
"name": "Passengers"
},
{
"stopId": "47",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "10:56:00",
"stopId": "47",
"passengers": 13
},
{
"yValue": "101000018",
"xValue": 5,
"time": "11:26:00",
"stopId": "47",
"passengers": 7
},
{
"yValue": "101000019",
"xValue": 5,
"time": "11:56:00",
"stopId": "47",
"passengers": 21
},
{
"yValue": "101000020",
"xValue": 5,
"time": "12:26:00",
"stopId": "47",
"passengers": 22
},
{
"yValue": "101000021",
"xValue": 5,
"time": "12:54:00",
"stopId": "47",
"passengers": 28
},
{
"yValue": "101000022",
"xValue": 5,
"time": "13:27:00",
"stopId": "47",
"passengers": 30
},
{
"yValue": "101000023",
"xValue": 5,
"time": "13:57:00",
"stopId": "47",
"passengers": 20
},
{
"yValue": "101000024",
"xValue": 5,
"time": "14:27:00",
"stopId": "47",
"passengers": 17
},
{
"yValue": "101000025",
"xValue": 5,
"time": "14:57:00",
"stopId": "47",
"passengers": 14
},
{
"yValue": "101000026",
"xValue": 5,
"time": "15:26:00",
"stopId": "47",
"passengers": 11
},
{
"yValue": "101000027",
"xValue": 5,
"time": "15:58:00",
"stopId": "47",
"passengers": 28
},
{
"yValue": "101000028",
"xValue": 5,
"time": "16:13:00",
"stopId": "47",
"passengers": 7
},
{
"yValue": "101000029",
"xValue": 5,
"time": "16:28:00",
"stopId": "47",
"passengers": 24
},
{
"yValue": "101000030",
"xValue": 5,
"time": "16:41:00",
"stopId": "47",
"passengers": 29
},
{
"yValue": "101000031",
"xValue": 5,
"time": "16:58:00",
"stopId": "47",
"passengers": 19
},
{
"yValue": "101000032",
"xValue": 5,
"time": "17:13:00",
"stopId": "47",
"passengers": 23
},
{
"yValue": "101000033",
"xValue": 5,
"time": "17:28:00",
"stopId": "47",
"passengers": 19
},
{
"yValue": "101000034",
"xValue": 5,
"time": "17:43:00",
"stopId": "47",
"passengers": 12
}
],
"name": "Passengers"
},
{
"stopId": "185",
"data": [
{
"yValue": "101000017",
"xValue": 5,
"time": "15:27:00",
"stopId": "185",
"passengers": 23
},
{
"yValue": "101000018",
"xValue": 5,
"time": "15:59:00",
"stopId": "185",
"passengers": 11
},
{
"yValue": "101000019",
"xValue": 5,
"time": "16:14:00",
"stopId": "185",
"passengers": 24
},
{
"yValue": "101000020",
"xValue": 5,
"time": "16:29:00",
"stopId": "185",
"passengers": 16
},
{
"yValue": "101000021",
"xValue": 5,
"time": "16:42:00",
"stopId": "185",
"passengers": 22
},
{
"yValue": "101000022",
"xValue": 5,
"time": "16:59:00",
"stopId": "185",
"passengers": 23
},
{
"yValue": "101000023",
"xValue": 5,
"time": "17:14:00",
"stopId": "185",
"passengers": 27
},
{
"yValue": "101000024",
"xValue": 5,
"time": "17:29:00",
"stopId": "185",
"passengers": 29
},
{
"yValue": "101000025",
"xValue": 5,
"time": "17:44:00",
"stopId": "185",
"passengers": 24
},
{
"yValue": "101000026",
"xValue": 5,
"time": "17:59:00",
"stopId": "185",
"passengers": 19
},
{
"yValue": "101000027",
"xValue": 5,
"time": "18:14:00",
"stopId": "185",
"passengers": 23
},
{
"yValue": "101000028",
"xValue": 5,
"time": "18:29:00",
"stopId": "185",
"passengers": 6
},
{
"yValue": "101000029",
"xValue": 5,
"time": "18:44:00",
"stopId": "185",
"passengers": 24
},
{
"yValue": "101000030",
"xValue": 5,
"time": "18:59:00",
"stopId": "185",
"passengers": 26
},
{
"yValue": "101000031",
"xValue": 5,
"time": "19:29:00",
"stopId": "185",
"passengers": 21
},
{
"yValue": "101000032",
"xValue": 5,
"time": "19:59:00",
"stopId": "185",
"passengers": 23
},
{
"yValue": "101000033",
"xValue": 5,
"time": "20:25:00",
"stopId": "185",
"passengers": 20
},
{
"yValue": "101000034",
"xValue": 5,
"time": "21:25:00",
"stopId": "185",
"passengers": 29
}
],
"name": "Passengers"
}
];
var margins = {
top: 12,
left: 100,
right: 50,
bottom: 34
};
var numberOfRecords = 0;
var dataset = dataset.map(function(d) {
numberOfRecords = 0;
return d.data.map(function(o, i) {
numberOfRecords++;
return {
y: o.xValue,
x: o.yValue,
name: d.name,
stopId: o.stopId,
passengers: o.passengers,
time: o.time
};
});
});
d3.select(window).on("resize", throttle);
var stack = d3.layout.stack();
stack(dataset);
var dataset = dataset.map(function(group) {
return group.map(function(d) {
// Invert the x and y values, and y0 becomes x0
return {
x: d.y,
y: d.x,
x0: d.y0,
name: d.name,
stopId: d.stopId,
passengers: d.passengers,
time: d.time
};
});
});
var yValuesTripId = dataset[0].map(function(d) {
return d.y;
});
var yValuesFirstStopTimes = dataset[0].map(function(d) {
// return (d.time.slice(0, -3) + (Math.floor(Math.random() * (20000 - 1 + 1)) + 1));
return removeSecondsFromHHMMSS(d.time);
});
var yValuesLastStopTimes = dataset[dataset.length - 1].map(function(d) {
// return (d.time.slice(0, -3) + (Math.floor(Math.random() * (20000 - 1 + 1)) + 1));
return removeSecondsFromHHMMSS(d.time);
});
var xMax = d3.max(dataset, function(group) {
return d3.max(group, function(d) {
return d.x + d.x0;
});
});
var tooltip = d3.select("#chartDiv")
.append('div')
.attr('id', 'tooltip')
.attr('class', 'hidden');
const chartArea = $("#chartDiv");
var width = chartArea.innerWidth() - margins.left - margins.right;
var barHeight = 10;
var height = (numberOfRecords * 15) - margins.top - margins.bottom;
var svg, xScale, yScaleLeft, yScaleRight, rects;
draw(width, height);
function draw(width, height) {
svg = d3.select("#chartDiv")
.append('svg')
.attr('width', width + margins.left + margins.right)
.attr('height', height + margins.top + margins.bottom)
.append('g')
.attr('transform', 'translate(' + margins.left + ',' + margins.top + ')');
xScale = d3.scale.linear()
.domain([0, xMax])
.range([0, width - margins.right]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(0);
yScaleLeft = d3.scale.ordinal()
.domain(yValuesTripId)
.rangeRoundBands([0, height], .1);
var yAxisLeft = d3.svg.axis()
.scale(yScaleLeft)
.orient('left')
.tickFormat(function(d, i) {
return yValuesFirstStopTimes[i];
});
yScaleRight = d3.scale.ordinal()
.domain(yValuesTripId)
.rangeRoundBands([0, height], .1);
var yAxisRight = d3.svg.axis()
.scale(yScaleRight)
.orient('right')
.tickPadding(-25)
.tickFormat(function(d, i) {
return yValuesLastStopTimes[i];
});
var groups = svg.selectAll('g')
.data(dataset)
.enter()
.append('g');
rects = groups.selectAll('rect')
.data(function(d) {
return d;
})
.enter()
.append('rect')
.attr('x', function(d) {
return xScale(d.x0);
})
.attr('y', function(d, i) {
return yScaleLeft(d.y);
})
.attr('height', function(d) {
return barHeight;
})
.attr('width', function(d) {
return xScale(d.x);
})
.attr('fill', function(d) {
return getColor(d.passengers);
})
.attr('stroke', 'white')
.on('mouseover', function(d) {
var xPos = d3.event.pageX - 310;
var yPos = d3.event.pageY - 110;
d3.select('#tooltip')
.style("left", xPos + "px")
.style("top", yPos + "px")
.style('width', '250px')
.text("Trip " + d.y + '|Passengers:' + d.passengers + '|Stop ' + d.stopId + '|time ' + removeSecondsFromHHMMSS(d.time));
d3.select('#tooltip').classed('hidden', false);
})
.on('mouseout', function() {
d3.select('#tooltip').classed('hidden', true);
});
svg.append('g')
.attr('class', 'axis')
.attr('id','busOccupancyChartXAxis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
svg.append('g')
.attr('class', 'axis')
.call(yAxisLeft);
svg.append("text")
.attr("x", 0 - margins.left)
.attr("y", 0)
.text("Departure Time");
const newWidth = width - 20;
svg.append('g')
.attr('class', 'axis')
.attr("transform", "translate(" + newWidth + ",0)")
.call(yAxisRight);
svg.append("text")
.attr("x", width - margins.right + 10)
.attr("y", 0)
.text("Arrival Time");
}
function redraw() {
width = chartArea.innerWidth() - margins.left - margins.right;
d3.select('svg').remove();
d3.select('#legend').remove();
draw(width, height);
}
var throttleTimer;
function throttle() {
window.clearTimeout(throttleTimer);
throttleTimer = window.setTimeout(function() {
redraw();
}, 200);
}
function getColor(numberOfPassengers) {
cellColor = "";
if (numberOfPassengers < 10) {
cellColor = "#585858";
} else if (numberOfPassengers < 20) {
cellColor = "#FFCC00";
} else if (numberOfPassengers < 25) {
cellColor = "#FF3300";
} else {
cellColor = "#A00000";
}
return cellColor;
}
function removeSecondsFromHHMMSS (time) {
return time.slice(0, -3)
}
#chartDiv #xaxis .domain {
fill: none;
stroke: #000;
}
#chartDiv #xaxis text,
#yaxis text {
font-size: 12px;
}
#chartDiv .axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
display: none;
}
#chartDiv .axis text {
font-family: sans-serif;
font-size: 11px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chartDiv">
</div>

Related

Color the area formed between Line Chart and Threshold line

I am referring to below link:
[https://stackoverflow.com/questions/25469434/finding-threshold-intersection-in-a-d3-chart][1]
I need to achieve similar thing but I need to color the area formed by intersection of horizontal line and the line
Can somebody help me
You can do it fairly easily with a gradient. Here's how you would do that. Note that you'd want to replace the offset %'s in the gradient definition with appropriately calculated numbers.
var data = [{
"time": "2014-02-25T19:00:00Z",
"temp": "39.08"
}, {
"time": "2014-02-25T21:00:00Z",
"temp": "39.51"
}, {
"time": "2014-02-25T23:00:00Z",
"temp": "39.14"
}, {
"time": "2014-02-26T01:00:00Z",
"temp": "40.79"
}, {
"time": "2014-02-26T03:00:00Z",
"temp": "41.17"
}, {
"time": "2014-02-26T05:00:00Z",
"temp": "40.39"
}, {
"time": "2014-02-26T07:00:00Z",
"temp": "40.49"
}, {
"time": "2014-02-26T09:00:00Z",
"temp": "40.29"
}, {
"time": "2014-02-26T11:00:00Z",
"temp": "39.90"
}, {
"time": "2014-02-26T13:00:00Z",
"temp": "39.66"
}, {
"time": "2014-02-26T15:00:00Z",
"temp": "39.01"
}, {
"time": "2014-02-26T17:00:00Z",
"temp": "37.91"
}, {
"time": "2014-02-26T19:00:00Z",
"temp": "39.64"
}, {
"time": "2014-02-26T21:00:00Z",
"temp": "38.21"
}, {
"time": "2014-02-26T23:00:00Z",
"temp": "39.60"
}, {
"time": "2014-02-27T01:00:00Z",
"temp": "40.13"
}, {
"time": "2014-02-27T03:00:00Z",
"temp": "40.51"
}, {
"time": "2014-02-27T05:00:00Z",
"temp": "40.78"
}, {
"time": "2014-02-27T07:00:00Z",
"temp": "40.54"
}, {
"time": "2014-02-27T09:00:00Z",
"temp": "40.29"
}, {
"time": "2014-02-27T11:00:00Z",
"temp": "40.24"
}, {
"time": "2014-02-27T13:00:00Z",
"temp": "40.00"
}, {
"time": "2014-02-27T15:00:00Z",
"temp": "40.01"
}, {
"time": "2014-02-27T17:00:00Z",
"temp": "38.96"
}, {
"time": "2014-02-27T19:00:00Z",
"temp": "39.20"
}, {
"time": "2014-02-27T21:00:00Z",
"temp": "40.14"
}, {
"time": "2014-02-27T23:00:00Z",
"temp": "38.71"
}, {
"time": "2014-02-28T01:00:00Z",
"temp": "40.88"
}, {
"time": "2014-02-28T03:00:00Z",
"temp": "40.98"
}, {
"time": "2014-02-28T05:00:00Z",
"temp": "41.05"
}, {
"time": "2014-02-28T07:00:00Z",
"temp": "40.60"
}, {
"time": "2014-02-28T09:00:00Z",
"temp": "40.47"
}, {
"time": "2014-02-28T11:00:00Z",
"temp": "40.39"
}, {
"time": "2014-02-28T13:00:00Z",
"temp": "40.44"
}, {
"time": "2014-02-28T15:00:00Z",
"temp": "37.58"
}, {
"time": "2014-02-28T17:00:00Z",
"temp": "38.26"
}, {
"time": "2014-02-28T19:00:00Z",
"temp": "37.83"
}, {
"time": "2014-02-28T21:00:00Z",
"temp": "39.26"
}, {
"time": "2014-02-28T23:00:00Z",
"temp": "38.25"
}, {
"time": "2014-03-01T01:00:00Z",
"temp": "39.60"
}, {
"time": "2014-03-01T03:00:00Z",
"temp": "40.09"
}, {
"time": "2014-03-01T05:00:00Z",
"temp": "39.92"
}, {
"time": "2014-03-01T07:00:00Z",
"temp": "39.67"
}, {
"time": "2014-03-01T09:00:00Z",
"temp": "39.73"
}, {
"time": "2014-03-01T11:00:00Z",
"temp": "39.93"
}, {
"time": "2014-03-01T13:00:00Z",
"temp": "39.90"
}, {
"time": "2014-03-01T15:00:00Z",
"temp": "39.82"
}, {
"time": "2014-03-01T17:00:00Z",
"temp": "37.47"
}, {
"time": "2014-03-01T19:00:00Z",
"temp": "38.30"
}, {
"time": "2014-03-01T21:00:00Z",
"temp": "39.17"
}, {
"time": "2014-03-01T23:00:00Z",
"temp": "38.87"
}, {
"time": "2014-03-02T01:00:00Z",
"temp": "40.01"
}, {
"time": "2014-03-02T03:00:00Z",
"temp": "40.31"
}, {
"time": "2014-03-02T05:00:00Z",
"temp": "39.31"
}, {
"time": "2014-03-02T07:00:00Z",
"temp": "39.78"
}, {
"time": "2014-03-02T09:00:00Z",
"temp": "40.32"
}, {
"time": "2014-03-02T11:00:00Z",
"temp": "40.48"
}, {
"time": "2014-03-02T13:00:00Z",
"temp": "39.94"
}, {
"time": "2014-03-02T15:00:00Z",
"temp": "38.42"
}, {
"time": "2014-03-02T17:00:00Z",
"temp": "39.41"
}, {
"time": "2014-03-02T19:00:00Z",
"temp": "39.56"
}, {
"time": "2014-03-02T21:00:00Z",
"temp": "36.89"
}, {
"time": "2014-03-02T23:00:00Z",
"temp": "39.53"
}, {
"time": "2014-03-03T01:00:00Z",
"temp": "40.97"
}, {
"time": "2014-03-03T03:00:00Z",
"temp": "40.58"
}, {
"time": "2014-03-03T05:00:00Z",
"temp": "38.17"
}, {
"time": "2014-03-03T07:00:00Z",
"temp": "39.50"
}, {
"time": "2014-03-03T09:00:00Z",
"temp": "40.47"
}, {
"time": "2014-03-03T11:00:00Z",
"temp": "40.28"
}, {
"time": "2014-03-03T13:00:00Z",
"temp": "37.48"
}, {
"time": "2014-03-03T15:00:00Z",
"temp": "38.13"
}, {
"time": "2014-03-03T17:00:00Z",
"temp": "39.17"
}, {
"time": "2014-03-03T19:00:00Z",
"temp": "39.27"
}, {
"time": "2014-03-03T21:00:00Z",
"temp": "38.65"
}, {
"time": "2014-03-03T23:00:00Z",
"temp": "39.78"
}, {
"time": "2014-03-04T01:00:00Z",
"temp": "39.62"
}, {
"time": "2014-03-04T03:00:00Z",
"temp": "39.49"
}, {
"time": "2014-03-04T05:00:00Z",
"temp": "39.65"
}, {
"time": "2014-03-04T07:00:00Z",
"temp": "40.07"
}, {
"time": "2014-03-04T09:00:00Z",
"temp": "40.72"
}, {
"time": "2014-03-04T11:00:00Z",
"temp": "40.46"
}, {
"time": "2014-03-04T13:00:00Z",
"temp": "38.86"
}, {
"time": "2014-03-04T15:00:00Z",
"temp": "39.40"
}, {
"time": "2014-03-04T17:00:00Z",
"temp": "40.39"
}, {
"time": "2014-03-04T19:00:00Z",
"temp": "39.61"
}, {
"time": "2014-03-04T21:00:00Z",
"temp": "38.94"
}, {
"time": "2014-03-04T23:00:00Z",
"temp": "40.43"
}, {
"time": "2014-03-05T01:00:00Z",
"temp": "40.17"
}, {
"time": "2014-03-05T03:00:00Z",
"temp": "39.81"
}, {
"time": "2014-03-05T05:00:00Z",
"temp": "40.68"
}, {
"time": "2014-03-05T07:00:00Z",
"temp": "39.80"
}, {
"time": "2014-03-05T09:00:00Z",
"temp": "40.38"
}, {
"time": "2014-03-05T11:00:00Z",
"temp": "39.05"
}, {
"time": "2014-03-05T13:00:00Z",
"temp": "37.91"
}, {
"time": "2014-03-05T15:00:00Z",
"temp": "39.28"
}, {
"time": "2014-03-05T17:00:00Z",
"temp": "39.72"
}, {
"time": "2014-03-05T19:00:00Z",
"temp": "38.84"
}, {
"time": "2014-03-05T21:00:00Z",
"temp": "39.74"
}, {
"time": "2014-03-05T23:00:00Z",
"temp": "40.63"
}, {
"time": "2014-03-06T01:00:00Z",
"temp": "39.66"
}, {
"time": "2014-03-06T03:00:00Z",
"temp": "40.71"
}, {
"time": "2014-03-06T05:00:00Z",
"temp": "40.67"
}, {
"time": "2014-03-06T07:00:00Z",
"temp": "40.93"
}, {
"time": "2014-03-06T09:00:00Z",
"temp": "40.48"
}, {
"time": "2014-03-06T11:00:00Z",
"temp": "39.54"
}, {
"time": "2014-03-06T13:00:00Z",
"temp": "40.54"
}, {
"time": "2014-03-06T15:00:00Z",
"temp": "39.90"
}, {
"time": "2014-03-06T17:00:00Z",
"temp": "39.85"
}, {
"time": "2014-03-06T19:00:00Z",
"temp": "39.37"
}, {
"time": "2014-03-06T21:00:00Z",
"temp": "40.58"
}, {
"time": "2014-03-06T23:00:00Z",
"temp": "39.72"
}, {
"time": "2014-03-07T01:00:00Z",
"temp": "40.40"
}, {
"time": "2014-03-07T03:00:00Z",
"temp": "40.68"
}, {
"time": "2014-03-07T05:00:00Z",
"temp": "40.72"
}, {
"time": "2014-03-07T07:00:00Z",
"temp": "41.08"
}, {
"time": "2014-03-07T09:00:00Z",
"temp": "38.06"
}, {
"time": "2014-03-07T11:00:00Z",
"temp": "39.39"
}, {
"time": "2014-03-07T13:00:00Z",
"temp": "39.83"
}, {
"time": "2014-03-07T15:00:00Z",
"temp": "40.51"
}, {
"time": "2014-03-07T17:00:00Z",
"temp": "40.21"
}, {
"time": "2014-03-07T19:00:00Z",
"temp": "38.25"
}, {
"time": "2014-03-07T21:00:00Z",
"temp": "40.39"
}, {
"time": "2014-03-07T23:00:00Z",
"temp": "40.54"
}, {
"time": "2014-03-08T01:00:00Z",
"temp": "39.31"
}, {
"time": "2014-03-08T03:00:00Z",
"temp": "40.29"
}, {
"time": "2014-03-08T05:00:00Z",
"temp": "40.94"
}, {
"time": "2014-03-08T07:00:00Z",
"temp": "41.05"
}, {
"time": "2014-03-08T09:00:00Z",
"temp": "39.82"
}, {
"time": "2014-03-08T11:00:00Z",
"temp": "39.14"
}, {
"time": "2014-03-08T13:00:00Z",
"temp": "36.90"
}, {
"time": "2014-03-08T15:00:00Z",
"temp": "39.69"
}, {
"time": "2014-03-08T17:00:00Z",
"temp": "39.61"
}, {
"time": "2014-03-08T19:00:00Z",
"temp": "38.97"
}, {
"time": "2014-03-08T21:00:00Z",
"temp": "39.58"
}, {
"time": "2014-03-08T23:00:00Z",
"temp": "40.39"
}, {
"time": "2014-03-09T01:00:00Z",
"temp": "40.85"
}, {
"time": "2014-03-09T03:00:00Z",
"temp": "40.66"
}, {
"time": "2014-03-09T05:00:00Z",
"temp": "40.91"
}, {
"time": "2014-03-09T07:00:00Z",
"temp": "40.83"
}, {
"time": "2014-03-09T09:00:00Z",
"temp": "37.44"
}, {
"time": "2014-03-09T11:00:00Z",
"temp": "39.01"
}, {
"time": "2014-03-09T13:00:00Z",
"temp": "37.28"
}, {
"time": "2014-03-09T15:00:00Z",
"temp": "38.47"
}, {
"time": "2014-03-09T17:00:00Z",
"temp": "39.60"
}, {
"time": "2014-03-09T19:00:00Z",
"temp": "39.15"
}, {
"time": "2014-03-09T21:00:00Z",
"temp": "40.64"
}, {
"time": "2014-03-09T23:00:00Z",
"temp": "37.76"
}];
var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%SZ").parse;
data.forEach(function (d) { d.time = parseDate(d.time); });
var chart = d3.select("#chart");
var padding = 40,
width = 950,
height = 300,
xTicks = 10,
yTicks = 8;
var threshold = 40.5;
var svg = chart.append("svg")
.attr("width", width + padding * 2)
.attr("height", height + padding * 2)
.append("g")
.attr("transform", "translate(" + padding + "," + padding + ")");
var myDefs = svg.append("defs");
var myGradient = myDefs.append("linearGradient")
.attr("id", "myGradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", "0")
.attr("x2", "0")
.attr("y1", "0")
.attr("y2", height);
myGradient.append("stop")
.attr("stop-color", "blue")
.attr("offset", "0%");
myGradient.append("stop")
.attr("stop-color", "blue")
.attr("offset", "25%");
myGradient.append("stop")
.attr("stop-color", "rgba(0,0,0,0)")
.attr("offset", "25%");
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(xTicks);
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(yTicks);
var valueLine = d3.svg.line()
.interpolate("basis")
.x(function (d) {
return x(d.time);
})
.y(function (d) {
return y(d.temp);
});
x.domain(d3.extent(data, function (d) {
return d.time;
}));
y.domain([33, 43]);
var mainLine = svg.append("path")
.attr({
"class": "line",
stroke: "steelblue",
d: valueLine(data)
});
svg.append("line").attr("stroke", "#F00").attr("x1", 0).attr("y1", y(threshold)).attr("x2", width).attr("y2", y(threshold)).attr("class", "line");
path.line { stroke-width: 2; fill: url(#myGradient); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<div id="chart"></div>

Understanding why strings break this 3d.js force.graph code

I am running this code in a jupyter notebook. First, I create this HTML element:
%%html
<div id="d3-example"></div>
<style>
.node {stroke: #fff; stroke-width: 1.5px;}
.link {stroke: #999; stroke-opacity: .6;}
</style>
Then I run this javascript:
%%javascript
// We load the d3.js library from the Web.
require.config({paths:
{d3: "http://d3js.org/d3.v3.min"}});
require(["d3"], function(d3) {
// The code in this block is executed when the
// d3.js library has been loaded.
// First, we specify the size of the canvas
// containing the visualization (size of the
// <div> element).
var width = 300, height = 300;
// We create a color scale.
var color = d3.scale.category10();
// We create a force-directed dynamic graph layout.
var force = d3.layout.force()
.charge(-120)
.linkDistance(1)
.size([width, height]);
// In the <div> element, we create a <svg> graphic
// that will contain our interactive visualization.
var svg = d3.select("#d3-example").select("svg")
if (svg.empty()) {
svg = d3.select("#d3-example").append("svg")
.attr("width", width)
.attr("height", height);
}
// We load the JSON file.
d3.json("graph2.json", function(error, graph) {
if (error) throw error;
// In this block, the file has been loaded
// and the 'graph' object contains our graph.
// We load the nodes and links in the
// force-directed graph.
force.nodes(graph.nodes)
.links(graph.links)
.start();
// We create a <line> SVG element for each link
// in the graph.
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link");
// We create a <circle> SVG element for each node
// in the graph, and we specify a few attributes.
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5) // radius
.style("fill", function(d) {
// The node color depends on the club.
return color(d.club);
})
.call(force.drag);
// The name of each node is the node number.
node.append("title")
.text(function(d) { return d.name; });
// We bind the positions of the SVG elements
// to the positions of the dynamic force-directed
// graph, at each time step.
force.on("tick", function() {
link.attr("x1", function(d){return d.source.x})
.attr("y1", function(d){return d.source.y})
.attr("x2", function(d){return d.target.x})
.attr("y2", function(d){return d.target.y});
node.attr("cx", function(d){return d.x})
.attr("cy", function(d){return d.y});
});
});
});
And this is the content of the json file:
{
"nodes": [
{
"name": 0,
"club": "Mr. Hi"
},
{
"name": 1,
"club": "Mr. Hi"
},
{
"name": 2,
"club": "Mr. Hi"
},
{
"name": 3,
"club": "Mr. Hi"
},
{
"name": 4,
"club": "Mr. Hi"
},
{
"name": 5,
"club": "Mr. Hi"
},
{
"name": 6,
"club": "Mr. Hi"
},
{
"name": 7,
"club": "Mr. Hi"
},
{
"name": 8,
"club": "Mr. Hi"
},
{
"name": 9,
"club": "Officer"
},
{
"name": 10,
"club": "Mr. Hi"
},
{
"name": "11",
"club": "Mr. Hi"
},
{
"name": "12",
"club": "Mr. Hi"
},
{
"name": "13",
"club": "Mr. Hi"
},
{
"name": "14",
"club": "Officer"
},
{
"name": "15",
"club": "Officer"
},
{
"name": "16",
"club": "Mr. Hi"
},
{
"name": "17",
"club": "Mr. Hi"
},
{
"name": "18",
"club": "Officer"
},
{
"name": "19",
"club": "Mr. Hi"
},
{
"name": "20",
"club": "Officer"
},
{
"name": "21",
"club": "Mr. Hi"
},
{
"name": "22",
"club": "Officer"
},
{
"name": "23",
"club": "Officer"
},
{
"name": "24",
"club": "Officer"
},
{
"name": "25",
"club": "Officer"
},
{
"name": "26",
"club": "Officer"
},
{
"name": "27",
"club": "Officer"
},
{
"name": "28",
"club": "Officer"
},
{
"name": "29",
"club": "Officer"
},
{
"name": "30",
"club": "Officer"
},
{
"name": "31",
"club": "Officer"
},
{
"name": "32",
"club": "Officer"
},
{
"name": "33",
"club": "Officer"
}
],
"links": [
{
"source": 0,
"target": 1
},
{
"source": 0,
"target": 2
},
{
"source": 0,
"target": 3
},
{
"source": 0,
"target": 4
},
{
"source": 0,
"target": 5
},
{
"source": 0,
"target": 6
},
{
"source": 0,
"target": 7
},
{
"source": 0,
"target": 8
},
{
"source": 0,
"target": 10
},
{
"source": 0,
"target": 11
},
{
"source": 0,
"target": 12
},
{
"source": 0,
"target": 13
},
{
"source": 0,
"target": 17
},
{
"source": 0,
"target": 19
},
{
"source": 0,
"target": 21
},
{
"source": 0,
"target": 31
},
{
"source": 1,
"target": 2
},
{
"source": 1,
"target": 3
},
{
"source": 1,
"target": 7
},
{
"source": 1,
"target": 13
},
{
"source": 1,
"target": 17
},
{
"source": 1,
"target": 19
},
{
"source": 1,
"target": 21
},
{
"source": 1,
"target": 30
},
{
"source": 2,
"target": 3
},
{
"source": 2,
"target": 7
},
{
"source": 2,
"target": 8
},
{
"source": 2,
"target": 9
},
{
"source": 2,
"target": 13
},
{
"source": 2,
"target": 27
},
{
"source": 2,
"target": 28
},
{
"source": 2,
"target": 32
},
{
"source": 3,
"target": 7
},
{
"source": 3,
"target": 12
},
{
"source": 3,
"target": 13
},
{
"source": 4,
"target": 6
},
{
"source": 4,
"target": 10
},
{
"source": 5,
"target": 6
},
{
"source": 5,
"target": 10
},
{
"source": 5,
"target": 16
},
{
"source": 6,
"target": 16
},
{
"source": 8,
"target": 30
},
{
"source": 8,
"target": 32
},
{
"source": 8,
"target": 33
},
{
"source": 9,
"target": 33
},
{
"source": 13,
"target": 33
},
{
"source": 14,
"target": 32
},
{
"source": 14,
"target": 33
},
{
"source": 15,
"target": 32
},
{
"source": 15,
"target": 33
},
{
"source": 18,
"target": 32
},
{
"source": 18,
"target": 33
},
{
"source": 19,
"target": 33
},
{
"source": 20,
"target": 32
},
{
"source": 20,
"target": 33
},
{
"source": 22,
"target": 32
},
{
"source": 22,
"target": 33
},
{
"source": 23,
"target": 25
},
{
"source": 23,
"target": 27
},
{
"source": 23,
"target": 29
},
{
"source": 23,
"target": 32
},
{
"source": 23,
"target": 33
},
{
"source": 24,
"target": 25
},
{
"source": 24,
"target": 27
},
{
"source": 24,
"target": 31
},
{
"source": 25,
"target": 31
},
{
"source": 26,
"target": 29
},
{
"source": 26,
"target": 33
},
{
"source": 27,
"target": 33
},
{
"source": 28,
"target": 31
},
{
"source": 28,
"target": 33
},
{
"source": 29,
"target": 32
},
{
"source": 29,
"target": 33
},
{
"source": 30,
"target": 32
},
{
"source": 30,
"target": 33
},
{
"source": 31,
"target": 32
},
{
"source": 31,
"target": 33
},
{
"source": 32,
"target": 33
}
]
}
​I want to customize the code and use it to visualize a different file. But I don't fully understand the code. I changed the values in the links section to strings. And that breaks the code. I want to use strings for my other graph. But I don't see how the javascript code depends on integers. For some reason, it breaks and no graph is displayed.

Y-Axis label prefix for XY Amcharts

I didn't find any solution how to add prefix/suffix for Y-Axis of XYAmChart. Seems like labelFunction are not supported for valueAxes in XY chart type. Any suggestions?
var chart = AmCharts.makeChart("chartdiv", {
"type": "xy",
"theme": "light",
"dataDateFormat": "DD-MM-YYYY",
"graphs": [
{
"id":"g8",
"balloon":{
"drop":true,
"adjustBorderColor":false,
"color":"#ffffff"
},
"bullet":"round",
"bulletBorderAlpha":1,
"bulletColor":"#FFFFFF",
"bulletSize":5,
"dashLength":0,
"hideBulletsCount":50,
"lineThickness":2,
"lineColor":"#67b7dc",
"title":"Store 8",
"useLineColorForBulletBorder":true,
"xField":"d-1-c2",
"yField":"p-1-c2",
"xAxis":"g8",
"balloonText":"<span style='font-size:18px;'>[[d-1-c2]]</span><br>07/1/2017-12/31/2017"
},
{
"id":"g8-copy1",
"balloon":{
"drop":true,
"adjustBorderColor":false,
"color":"#ffffff"
},
"bullet":"round",
"bulletBorderAlpha":1,
"bulletColor":"#FFFFFF",
"bulletSize":5,
"dashLength":15,
"hideBulletsCount":50,
"lineThickness":2,
"lineColor":"#67b7dc",
"title":"Store 8",
"useLineColorForBulletBorder":true,
"xField":"d-1-c1",
"yField":"p-1-c1",
"xAxis":"g8-copy1",
"balloonText":"<span style='font-size:18px;'>[[d-1-c1]]</span><br>1/1/2017-6/29/2017"
}
],
"valueAxes": [
{
"id": "g8",
"axisAlpha": 1,
"gridAlpha": 1,
"axisColor": "#b0de09",
"color": "#b0de09",
"dashLength": 5,
"centerLabelOnFullp": true,
"position": "bottom",
"type": "date",
"minp": "DD-MM-YYYY",
"markPeriodChange": false,
"labelFunction": function(value, valueText) {
return "prefix:" + valueText;
}
},
{
"id": "g8-copy1",
"gridAlpha": 0,
"axisAlpha": 1,
"centerLabelOnFullp": false,
"position": "bottom",
"offset": 40,
"type": "date",
"minp": "DD-MM-YYYY",
'markPeriodChange': false,
"labelFunction": function(value, valueText) {
return "prefix:" + valueText;
}
}
],
"dataProvider": [
{
"d-1-c2":"01/01/2017",
"p-1-c2":"5684.6400"
},{
"d-1-c2":"01/02/2017",
"p-1-c2":"6468.9600"
},{
"d-1-c2":"01/03/2017",
"p-1-c2":"9032.7600"
},{
"d-1-c2":"01/04/2017",
"p-1-c2":"6385.9200"
},{
"d-1-c2":"01/05/2017",
"p-1-c2":"10087.3900"
},{
"d-1-c2":"01/06/2017",
"p-1-c2":"6136.3300"
},
{
"d-1-c1":"01/07/2017",
"p-1-c1":"4659.7000"
},{
"d-1-c1":"01/08/2017",
"p-1-c1":"9719.7100"
},{
"d-1-c1":"01/09/2017",
"p-1-c1":"4789.7300"
},{
"d-1-c1":"01/10/2017",
"p-1-c1":"7448.3900"
},{
"d-1-c1":"01/11/2017",
"p-1-c1":"6202.7200"
},{
"d-1-c1":"01/12/2017",
"p-1-c1":"9274.0300"
},{
"d-1-c1":"01/01/2018"
},{
"d-1-c2":"01/07/2017"
}
]
});
#chartdiv {
width: 100%;
height: 500px;
}
<script src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script src="//www.amcharts.com/lib/3/xy.js"></script>
<script src="//www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>
labelFunction is definitely supported as you can see below.
"valueAxes": [ {
"position": "bottom",
"axisAlpha": 0,
"labelFunction": function(value, valueText) {
return "prefix:" + valueText;
}
}, {
"minMaxMultiplier": 1.2,
"axisAlpha": 0,
"position": "left",
"labelFunction": function(value, valueText) {
return "prefix:" + valueText;
}
} ],
Demo:
var chart = AmCharts.makeChart( "chartdiv", {
"type": "xy",
"theme": "light",
"balloon":{
"fixedPosition":true,
},
"dataProvider": [ {
"y": 10,
"x": 14,
"value": 59,
"y2": -5,
"x2": -3,
"value2": 44
}, {
"y": 5,
"x": 3,
"value": 50,
"y2": -15,
"x2": -8,
"value2": 12
}, {
"y": -10,
"x": 8,
"value": 19,
"y2": -4,
"x2": 6,
"value2": 35
}, {
"y": -6,
"x": 5,
"value": 65,
"y2": -5,
"x2": -6,
"value2": 168
}, {
"y": 15,
"x": -4,
"value": 92,
"y2": -10,
"x2": -8,
"value2": 102
}, {
"y": 13,
"x": 1,
"value": 8,
"y2": -2,
"x2": 0,
"value2": 41
}, {
"y": 1,
"x": 6,
"value": 35,
"y2": 0,
"x2": -3,
"value2": 16
} ],
"valueAxes": [ {
"position": "bottom",
"axisAlpha": 0,
"labelFunction": function(value, valueText) {
return "prefix:" + valueText;
}
}, {
"minMaxMultiplier": 1.2,
"axisAlpha": 0,
"position": "left",
"labelFunction": function(value, valueText) {
return "prefix:" + valueText;
}
} ],
"startDuration": 1.5,
"graphs": [ {
"balloonText": "x:<b>[[x]]</b> y:<b>[[y]]</b><br>value:<b>[[value]]</b>",
"bullet": "circle",
"bulletBorderAlpha": 0.2,
"bulletAlpha": 0.8,
"lineAlpha": 0,
"fillAlphas": 0,
"valueField": "value",
"xField": "x",
"yField": "y",
"maxBulletSize": 100
}, {
"balloonText": "x:<b>[[x]]</b> y:<b>[[y]]</b><br>value:<b>[[value]]</b>",
"bullet": "diamond",
"bulletBorderAlpha": 0.2,
"bulletAlpha": 0.8,
"lineAlpha": 0,
"fillAlphas": 0,
"valueField": "value2",
"xField": "x2",
"yField": "y2",
"maxBulletSize": 100
} ]
} );
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
#chartdiv {
width: 100%;
height: 100%;
}
<script src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script src="//www.amcharts.com/lib/3/xy.js"></script>
<script src="//www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>
You can also use unit and unitPosition if your custom labeling doesn't
require any additional logic that you can leverage through labelFunction.
"valueAxes": [ {
"position": "bottom",
"axisAlpha": 0,
"unit": "unit-prefix:",
"unitPosition": "left"
}, {
"minMaxMultiplier": 1.2,
"axisAlpha": 0,
"position": "left",
"unit": "unit-prefix:",
"unitPosition": "left"
} ],
Demo below.
var chart = AmCharts.makeChart( "chartdiv", {
"type": "xy",
"theme": "light",
"balloon":{
"fixedPosition":true,
},
"dataProvider": [ {
"y": 10,
"x": 14,
"value": 59,
"y2": -5,
"x2": -3,
"value2": 44
}, {
"y": 5,
"x": 3,
"value": 50,
"y2": -15,
"x2": -8,
"value2": 12
}, {
"y": -10,
"x": 8,
"value": 19,
"y2": -4,
"x2": 6,
"value2": 35
}, {
"y": -6,
"x": 5,
"value": 65,
"y2": -5,
"x2": -6,
"value2": 168
}, {
"y": 15,
"x": -4,
"value": 92,
"y2": -10,
"x2": -8,
"value2": 102
}, {
"y": 13,
"x": 1,
"value": 8,
"y2": -2,
"x2": 0,
"value2": 41
}, {
"y": 1,
"x": 6,
"value": 35,
"y2": 0,
"x2": -3,
"value2": 16
} ],
"valueAxes": [ {
"position": "bottom",
"axisAlpha": 0,
"unit": "unit-prefix:",
"unitPosition": "left"
}, {
"minMaxMultiplier": 1.2,
"axisAlpha": 0,
"position": "left",
"unit": "unit-prefix:",
"unitPosition": "left"
} ],
"startDuration": 1.5,
"graphs": [ {
"balloonText": "x:<b>[[x]]</b> y:<b>[[y]]</b><br>value:<b>[[value]]</b>",
"bullet": "circle",
"bulletBorderAlpha": 0.2,
"bulletAlpha": 0.8,
"lineAlpha": 0,
"fillAlphas": 0,
"valueField": "value",
"xField": "x",
"yField": "y",
"maxBulletSize": 100
}, {
"balloonText": "x:<b>[[x]]</b> y:<b>[[y]]</b><br>value:<b>[[value]]</b>",
"bullet": "diamond",
"bulletBorderAlpha": 0.2,
"bulletAlpha": 0.8,
"lineAlpha": 0,
"fillAlphas": 0,
"valueField": "value2",
"xField": "x2",
"yField": "y2",
"maxBulletSize": 100
} ]
} );
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
#chartdiv {
width: 100%;
height: 100%;
}
<script src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script src="//www.amcharts.com/lib/3/xy.js"></script>
<script src="//www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>

D3.js labeled force graph does not reload data

I am trying to create a force graph in d3.js with some labels on top of each node and also some content-dependent style (for instance, the colour of the node is dependent on a 'type' property). I am starting with one of the examples but I cannot make the graph to display new data when I update it. For instance, when changing the text property on the list of data, the label on the node should change, however it does not. I think the problem might be in the data()/enter() procedure, which I am still trying to fully understand. What I have so far managed to get is the following: https://jsfiddle.net/5Luv0btd/2/ . Any help would be much appreciated!
That is because once you've entered the data, you do not have to operate on the nodeEnter anymore. The reason is simple: .enter() merges into the update selection when you append or insert.. In other words, after chaining .enter(), node effectively refers to both the old and new data. Citing the example for the v3.x documentation for d3:
var update_sel = svg.selectAll("circle").data(data)
update_sel.attr(/* operate on old elements only */)
update_sel.enter().append("circle").attr(/* operate on new elements only */)
update_sel.attr(/* operate on old and new elements */)
update_sel.exit().remove() /* complete the enter-update-exit pattern */
Therefore, working with node itself will suffice, i.e.:
// Enter selection
node.enter().append("g")
.attr("class", "node")
.call(drag);
// From this point onwards:
// `node` will refer to both old and new data
// Do magic ;)
node.append("circle")
.attr("r", 10)
.style('fill', function(d) {
return color(d.type)
})
.attr("width", 16)
.attr("height", 16);
node.append("text")
.attr("dx", 0)
.attr("dy", ".35em")
.text(function(d) {
return d.name
})
.attr("text-anchor", "middle");
See working fiddle here: https://jsfiddle.net/teddyrised/5Luv0btd/5/, or refer to the code snippet below:
var data = {
"nodes": [{
"name": "Myriel",
"type": 1
}, {
"name": "Napoleon",
"type": 1
}, {
"name": "Mlle.Baptistine",
"type": 1
}, {
"name": "Mme.Magloire",
"type": 1
}, {
"name": "CountessdeLo",
"type": 1
}, {
"name": "Geborand",
"type": 1
}, {
"name": "Champtercier",
"type": 1
}, {
"name": "Cravatte",
"type": 1
}, {
"name": "Count",
"type": 1
}, {
"name": "OldMan",
"type": 1
}, {
"name": "Labarre",
"type": 2
}, {
"name": "Valjean",
"type": 2
}, {
"name": "Marguerite",
"type": 3
}, {
"name": "Mme.deR",
"type": 2
}, {
"name": "Isabeau",
"type": 2
}, {
"name": "Gervais",
"type": 2
}, {
"name": "Tholomyes",
"type": 3
}, {
"name": "Listolier",
"type": 3
}, {
"name": "Fameuil",
"type": 3
}, {
"name": "Blacheville",
"type": 3
}, {
"name": "Favourite",
"type": 3
}, {
"name": "Dahlia",
"type": 3
}, {
"name": "Zephine",
"type": 3
}, {
"name": "Fantine",
"type": 3
}, {
"name": "Mme.Thenardier",
"type": 4
}, {
"name": "Thenardier",
"type": 4
}, {
"name": "Cosette",
"type": 5
}, {
"name": "Javert",
"type": 4
}, {
"name": "Fauchelevent",
"type": 0
}, {
"name": "Bamatabois",
"type": 2
}, {
"name": "Perpetue",
"type": 3
}, {
"name": "Simplice",
"type": 2
}, {
"name": "Scaufflaire",
"type": 2
}, {
"name": "Woman1",
"type": 2
}, {
"name": "Judge",
"type": 2
}, {
"name": "Champmathieu",
"type": 2
}, {
"name": "Brevet",
"type": 2
}, {
"name": "Chenildieu",
"type": 2
}, {
"name": "Cochepaille",
"type": 2
}, {
"name": "Pontmercy",
"type": 4
}, {
"name": "Boulatruelle",
"type": 6
}, {
"name": "Eponine",
"type": 4
}, {
"name": "Anzelma",
"type": 4
}, {
"name": "Woman2",
"type": 5
}, {
"name": "MotherInnocent",
"type": 0
}, {
"name": "Gribier",
"type": 0
}, {
"name": "Jondrette",
"type": 7
}, {
"name": "Mme.Burgon",
"type": 7
}, {
"name": "Gavroche",
"type": 8
}, {
"name": "Gillenormand",
"type": 5
}, {
"name": "Magnon",
"type": 5
}, {
"name": "Mlle.Gillenormand",
"type": 5
}, {
"name": "Mme.Pontmercy",
"type": 5
}, {
"name": "Mlle.Vaubois",
"type": 5
}, {
"name": "Lt.Gillenormand",
"type": 5
}, {
"name": "Marius",
"type": 8
}, {
"name": "BaronessT",
"type": 5
}, {
"name": "Mabeuf",
"type": 8
}, {
"name": "Enjolras",
"type": 8
}, {
"name": "Combeferre",
"type": 8
}, {
"name": "Prouvaire",
"type": 8
}, {
"name": "Feuilly",
"type": 8
}, {
"name": "Courfeyrac",
"type": 8
}, {
"name": "Bahorel",
"type": 8
}, {
"name": "Bossuet",
"type": 8
}, {
"name": "Joly",
"type": 8
}, {
"name": "Grantaire",
"type": 8
}, {
"name": "MotherPlutarch",
"type": 9
}, {
"name": "Gueulemer",
"type": 4
}, {
"name": "Babet",
"type": 4
}, {
"name": "Claquesous",
"type": 4
}, {
"name": "Montparnasse",
"type": 4
}, {
"name": "Toussaint",
"type": 5
}, {
"name": "Child1",
"type": 10
}, {
"name": "Child2",
"type": 10
}, {
"name": "Brujon",
"type": 4
}, {
"name": "Mme.Hucheloup",
"type": 8
}],
"links": [{
"source": 1,
"target": 0,
"value": 1
}, {
"source": 2,
"target": 0,
"value": 8
}, {
"source": 3,
"target": 0,
"value": 10
}, {
"source": 3,
"target": 2,
"value": 6
}, {
"source": 4,
"target": 0,
"value": 1
}, {
"source": 5,
"target": 0,
"value": 1
}, {
"source": 6,
"target": 0,
"value": 1
}, {
"source": 7,
"target": 0,
"value": 1
}, {
"source": 8,
"target": 0,
"value": 2
}, {
"source": 9,
"target": 0,
"value": 1
}, {
"source": 11,
"target": 10,
"value": 1
}, {
"source": 11,
"target": 3,
"value": 3
}, {
"source": 11,
"target": 2,
"value": 3
}, {
"source": 11,
"target": 0,
"value": 5
}, {
"source": 12,
"target": 11,
"value": 1
}, {
"source": 13,
"target": 11,
"value": 1
}, {
"source": 14,
"target": 11,
"value": 1
}, {
"source": 15,
"target": 11,
"value": 1
}, {
"source": 17,
"target": 16,
"value": 4
}, {
"source": 18,
"target": 16,
"value": 4
}, {
"source": 18,
"target": 17,
"value": 4
}, {
"source": 19,
"target": 16,
"value": 4
}, {
"source": 19,
"target": 17,
"value": 4
}, {
"source": 19,
"target": 18,
"value": 4
}, {
"source": 20,
"target": 16,
"value": 3
}, {
"source": 20,
"target": 17,
"value": 3
}, {
"source": 20,
"target": 18,
"value": 3
}, {
"source": 20,
"target": 19,
"value": 4
}, {
"source": 21,
"target": 16,
"value": 3
}, {
"source": 21,
"target": 17,
"value": 3
}, {
"source": 21,
"target": 18,
"value": 3
}, {
"source": 21,
"target": 19,
"value": 3
}, {
"source": 21,
"target": 20,
"value": 5
}, {
"source": 22,
"target": 16,
"value": 3
}, {
"source": 22,
"target": 17,
"value": 3
}, {
"source": 22,
"target": 18,
"value": 3
}, {
"source": 22,
"target": 19,
"value": 3
}, {
"source": 22,
"target": 20,
"value": 4
}, {
"source": 22,
"target": 21,
"value": 4
}, {
"source": 23,
"target": 16,
"value": 3
}, {
"source": 23,
"target": 17,
"value": 3
}, {
"source": 23,
"target": 18,
"value": 3
}, {
"source": 23,
"target": 19,
"value": 3
}, {
"source": 23,
"target": 20,
"value": 4
}, {
"source": 23,
"target": 21,
"value": 4
}, {
"source": 23,
"target": 22,
"value": 4
}, {
"source": 23,
"target": 12,
"value": 2
}, {
"source": 23,
"target": 11,
"value": 9
}, {
"source": 24,
"target": 23,
"value": 2
}, {
"source": 24,
"target": 11,
"value": 7
}, {
"source": 25,
"target": 24,
"value": 13
}, {
"source": 25,
"target": 23,
"value": 1
}, {
"source": 25,
"target": 11,
"value": 12
}, {
"source": 26,
"target": 24,
"value": 4
}, {
"source": 26,
"target": 11,
"value": 31
}, {
"source": 26,
"target": 16,
"value": 1
}, {
"source": 26,
"target": 25,
"value": 1
}, {
"source": 27,
"target": 11,
"value": 17
}, {
"source": 27,
"target": 23,
"value": 5
}, {
"source": 27,
"target": 25,
"value": 5
}, {
"source": 27,
"target": 24,
"value": 1
}, {
"source": 27,
"target": 26,
"value": 1
}, {
"source": 28,
"target": 11,
"value": 8
}, {
"source": 28,
"target": 27,
"value": 1
}, {
"source": 29,
"target": 23,
"value": 1
}, {
"source": 29,
"target": 27,
"value": 1
}, {
"source": 29,
"target": 11,
"value": 2
}, {
"source": 30,
"target": 23,
"value": 1
}, {
"source": 31,
"target": 30,
"value": 2
}, {
"source": 31,
"target": 11,
"value": 3
}, {
"source": 31,
"target": 23,
"value": 2
}, {
"source": 31,
"target": 27,
"value": 1
}, {
"source": 32,
"target": 11,
"value": 1
}, {
"source": 33,
"target": 11,
"value": 2
}, {
"source": 33,
"target": 27,
"value": 1
}, {
"source": 34,
"target": 11,
"value": 3
}, {
"source": 34,
"target": 29,
"value": 2
}, {
"source": 35,
"target": 11,
"value": 3
}, {
"source": 35,
"target": 34,
"value": 3
}, {
"source": 35,
"target": 29,
"value": 2
}, {
"source": 36,
"target": 34,
"value": 2
}, {
"source": 36,
"target": 35,
"value": 2
}, {
"source": 36,
"target": 11,
"value": 2
}, {
"source": 36,
"target": 29,
"value": 1
}, {
"source": 37,
"target": 34,
"value": 2
}, {
"source": 37,
"target": 35,
"value": 2
}, {
"source": 37,
"target": 36,
"value": 2
}, {
"source": 37,
"target": 11,
"value": 2
}, {
"source": 37,
"target": 29,
"value": 1
}, {
"source": 38,
"target": 34,
"value": 2
}, {
"source": 38,
"target": 35,
"value": 2
}, {
"source": 38,
"target": 36,
"value": 2
}, {
"source": 38,
"target": 37,
"value": 2
}, {
"source": 38,
"target": 11,
"value": 2
}, {
"source": 38,
"target": 29,
"value": 1
}, {
"source": 39,
"target": 25,
"value": 1
}, {
"source": 40,
"target": 25,
"value": 1
}, {
"source": 41,
"target": 24,
"value": 2
}, {
"source": 41,
"target": 25,
"value": 3
}, {
"source": 42,
"target": 41,
"value": 2
}, {
"source": 42,
"target": 25,
"value": 2
}, {
"source": 42,
"target": 24,
"value": 1
}, {
"source": 43,
"target": 11,
"value": 3
}, {
"source": 43,
"target": 26,
"value": 1
}, {
"source": 43,
"target": 27,
"value": 1
}, {
"source": 44,
"target": 28,
"value": 3
}, {
"source": 44,
"target": 11,
"value": 1
}, {
"source": 45,
"target": 28,
"value": 2
}, {
"source": 47,
"target": 46,
"value": 1
}, {
"source": 48,
"target": 47,
"value": 2
}, {
"source": 48,
"target": 25,
"value": 1
}, {
"source": 48,
"target": 27,
"value": 1
}, {
"source": 48,
"target": 11,
"value": 1
}, {
"source": 49,
"target": 26,
"value": 3
}, {
"source": 49,
"target": 11,
"value": 2
}, {
"source": 50,
"target": 49,
"value": 1
}, {
"source": 50,
"target": 24,
"value": 1
}, {
"source": 51,
"target": 49,
"value": 9
}, {
"source": 51,
"target": 26,
"value": 2
}, {
"source": 51,
"target": 11,
"value": 2
}, {
"source": 52,
"target": 51,
"value": 1
}, {
"source": 52,
"target": 39,
"value": 1
}, {
"source": 53,
"target": 51,
"value": 1
}, {
"source": 54,
"target": 51,
"value": 2
}, {
"source": 54,
"target": 49,
"value": 1
}, {
"source": 54,
"target": 26,
"value": 1
}, {
"source": 55,
"target": 51,
"value": 6
}, {
"source": 55,
"target": 49,
"value": 12
}, {
"source": 55,
"target": 39,
"value": 1
}, {
"source": 55,
"target": 54,
"value": 1
}, {
"source": 55,
"target": 26,
"value": 21
}, {
"source": 55,
"target": 11,
"value": 19
}, {
"source": 55,
"target": 16,
"value": 1
}, {
"source": 55,
"target": 25,
"value": 2
}, {
"source": 55,
"target": 41,
"value": 5
}, {
"source": 55,
"target": 48,
"value": 4
}, {
"source": 56,
"target": 49,
"value": 1
}, {
"source": 56,
"target": 55,
"value": 1
}, {
"source": 57,
"target": 55,
"value": 1
}, {
"source": 57,
"target": 41,
"value": 1
}, {
"source": 57,
"target": 48,
"value": 1
}, {
"source": 58,
"target": 55,
"value": 7
}, {
"source": 58,
"target": 48,
"value": 7
}, {
"source": 58,
"target": 27,
"value": 6
}, {
"source": 58,
"target": 57,
"value": 1
}, {
"source": 58,
"target": 11,
"value": 4
}, {
"source": 59,
"target": 58,
"value": 15
}, {
"source": 59,
"target": 55,
"value": 5
}, {
"source": 59,
"target": 48,
"value": 6
}, {
"source": 59,
"target": 57,
"value": 2
}, {
"source": 60,
"target": 48,
"value": 1
}, {
"source": 60,
"target": 58,
"value": 4
}, {
"source": 60,
"target": 59,
"value": 2
}, {
"source": 61,
"target": 48,
"value": 2
}, {
"source": 61,
"target": 58,
"value": 6
}, {
"source": 61,
"target": 60,
"value": 2
}, {
"source": 61,
"target": 59,
"value": 5
}, {
"source": 61,
"target": 57,
"value": 1
}, {
"source": 61,
"target": 55,
"value": 1
}, {
"source": 62,
"target": 55,
"value": 9
}, {
"source": 62,
"target": 58,
"value": 17
}, {
"source": 62,
"target": 59,
"value": 13
}, {
"source": 62,
"target": 48,
"value": 7
}, {
"source": 62,
"target": 57,
"value": 2
}, {
"source": 62,
"target": 41,
"value": 1
}, {
"source": 62,
"target": 61,
"value": 6
}, {
"source": 62,
"target": 60,
"value": 3
}, {
"source": 63,
"target": 59,
"value": 5
}, {
"source": 63,
"target": 48,
"value": 5
}, {
"source": 63,
"target": 62,
"value": 6
}, {
"source": 63,
"target": 57,
"value": 2
}, {
"source": 63,
"target": 58,
"value": 4
}, {
"source": 63,
"target": 61,
"value": 3
}, {
"source": 63,
"target": 60,
"value": 2
}, {
"source": 63,
"target": 55,
"value": 1
}, {
"source": 64,
"target": 55,
"value": 5
}, {
"source": 64,
"target": 62,
"value": 12
}, {
"source": 64,
"target": 48,
"value": 5
}, {
"source": 64,
"target": 63,
"value": 4
}, {
"source": 64,
"target": 58,
"value": 10
}, {
"source": 64,
"target": 61,
"value": 6
}, {
"source": 64,
"target": 60,
"value": 2
}, {
"source": 64,
"target": 59,
"value": 9
}, {
"source": 64,
"target": 57,
"value": 1
}, {
"source": 64,
"target": 11,
"value": 1
}, {
"source": 65,
"target": 63,
"value": 5
}, {
"source": 65,
"target": 64,
"value": 7
}, {
"source": 65,
"target": 48,
"value": 3
}, {
"source": 65,
"target": 62,
"value": 5
}, {
"source": 65,
"target": 58,
"value": 5
}, {
"source": 65,
"target": 61,
"value": 5
}, {
"source": 65,
"target": 60,
"value": 2
}, {
"source": 65,
"target": 59,
"value": 5
}, {
"source": 65,
"target": 57,
"value": 1
}, {
"source": 65,
"target": 55,
"value": 2
}, {
"source": 66,
"target": 64,
"value": 3
}, {
"source": 66,
"target": 58,
"value": 3
}, {
"source": 66,
"target": 59,
"value": 1
}, {
"source": 66,
"target": 62,
"value": 2
}, {
"source": 66,
"target": 65,
"value": 2
}, {
"source": 66,
"target": 48,
"value": 1
}, {
"source": 66,
"target": 63,
"value": 1
}, {
"source": 66,
"target": 61,
"value": 1
}, {
"source": 66,
"target": 60,
"value": 1
}, {
"source": 67,
"target": 57,
"value": 3
}, {
"source": 68,
"target": 25,
"value": 5
}, {
"source": 68,
"target": 11,
"value": 1
}, {
"source": 68,
"target": 24,
"value": 1
}, {
"source": 68,
"target": 27,
"value": 1
}, {
"source": 68,
"target": 48,
"value": 1
}, {
"source": 68,
"target": 41,
"value": 1
}, {
"source": 69,
"target": 25,
"value": 6
}, {
"source": 69,
"target": 68,
"value": 6
}, {
"source": 69,
"target": 11,
"value": 1
}, {
"source": 69,
"target": 24,
"value": 1
}, {
"source": 69,
"target": 27,
"value": 2
}, {
"source": 69,
"target": 48,
"value": 1
}, {
"source": 69,
"target": 41,
"value": 1
}, {
"source": 70,
"target": 25,
"value": 4
}, {
"source": 70,
"target": 69,
"value": 4
}, {
"source": 70,
"target": 68,
"value": 4
}, {
"source": 70,
"target": 11,
"value": 1
}, {
"source": 70,
"target": 24,
"value": 1
}, {
"source": 70,
"target": 27,
"value": 1
}, {
"source": 70,
"target": 41,
"value": 1
}, {
"source": 70,
"target": 58,
"value": 1
}, {
"source": 71,
"target": 27,
"value": 1
}, {
"source": 71,
"target": 69,
"value": 2
}, {
"source": 71,
"target": 68,
"value": 2
}, {
"source": 71,
"target": 70,
"value": 2
}, {
"source": 71,
"target": 11,
"value": 1
}, {
"source": 71,
"target": 48,
"value": 1
}, {
"source": 71,
"target": 41,
"value": 1
}, {
"source": 71,
"target": 25,
"value": 1
}, {
"source": 72,
"target": 26,
"value": 2
}, {
"source": 72,
"target": 27,
"value": 1
}, {
"source": 72,
"target": 11,
"value": 1
}, {
"source": 73,
"target": 48,
"value": 2
}, {
"source": 74,
"target": 48,
"value": 2
}, {
"source": 74,
"target": 73,
"value": 3
}, {
"source": 75,
"target": 69,
"value": 3
}, {
"source": 75,
"target": 68,
"value": 3
}, {
"source": 75,
"target": 25,
"value": 3
}, {
"source": 75,
"target": 48,
"value": 1
}, {
"source": 75,
"target": 41,
"value": 1
}, {
"source": 75,
"target": 70,
"value": 1
}, {
"source": 75,
"target": 71,
"value": 1
}, {
"source": 76,
"target": 64,
"value": 1
}, {
"source": 76,
"target": 65,
"value": 1
}, {
"source": 76,
"target": 66,
"value": 1
}, {
"source": 76,
"target": 63,
"value": 1
}, {
"source": 76,
"target": 62,
"value": 1
}, {
"source": 76,
"target": 48,
"value": 1
}, {
"source": 76,
"target": 58,
"value": 1
}]
};
var width = 960,
height = 500,
color = d3.scale.category20();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.gravity(0.05)
.distance(100)
.charge(-100)
.size([width, height]);
var draw = function(data) {
force
.nodes(data.nodes)
.links(data.links)
.start();
var drag = d3.behavior.drag().origin(function(d) {
return d;
});
var link = svg.selectAll(".link")
.data(data.links);
var linkEnter = link.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(data.nodes, function(d) {
return d.name
});
node.enter().append("g")
.attr("class", "node")
.call(drag);
node.append("circle")
.attr("r", 10)
.style('fill', function(d) {
return color(d.type)
})
.attr("width", 16)
.attr("height", 16);
node.append("text")
.attr("dx", 0)
.attr("dy", ".35em")
.text(function(d) {
return d.name
})
.attr("text-anchor", "middle");
link.exit().remove();
node.exit().remove();
force.on("tick", function() {
link.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
}
draw(data);
setTimeout(function(d) {
data.nodes[0].name = "A changed name";
data.nodes[0].type = 2;
// The node 'Myriel' should now have the labed 'A changed name'
draw(data)
}, 2000);
.link {
stroke: #ccc;
}
.node text {
pointer-events: none;
font: 10px sans-serif;
}
<script src="//d3js.org/d3.v3.min.js"></script>

How to add text in the center of node in force directed graph? [duplicate]

This question already has answers here:
Placing labels at the center of nodes in d3.js
(3 answers)
Closed 7 years ago.
Here is the code to draw to text in the center of the circle.
node.append("text")
.attr("dx", 10)
.attr("dy", ".35em")
.text(function(d) { return d.group });
Here is the jsfiddle
Just set text-anchor attribute middle to the text element. This code would work even for nodes having different size.
node.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.text(function(d) { return d.group });
Working snippet:
var width = 500,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(80)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var mis = document.getElementById('mis').innerHTML;
graph = JSON.parse(mis);
force.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", function(d,i){ return i%2==0?10:8 })
.style("fill", function(d) {
return color(d.group);
})
node.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.text(function(d) {
return d.group
});
force.on("tick", function() {
link.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
d3.selectAll("circle").attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
d3.selectAll("text").attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
});
});
.link {
stroke: #ccc;
}
.node text {
pointer-events: none;
font: 10px sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script type="application/json" id="mis">
{ "nodes": [{ "name": "Myriel", "group": 1 }, { "name": "Napoleon", "group": 1 }, { "name": "Mlle.Baptistine", "group": 1 }, { "name": "Mme.Magloire", "group": 1 }, { "name": "CountessdeLo", "group": 1 }, { "name": "Geborand", "group": 1 }, { "name": "Champtercier", "group": 1 }, { "name": "Cravatte", "group": 1 }, { "name": "Count", "group": 1 }, { "name": "OldMan", "group": 1 }, { "name": "Labarre", "group": 2 }, { "name": "Valjean", "group": 2 }, { "name": "Marguerite", "group": 3 }, { "name": "Mme.deR", "group": 2 }, { "name": "Isabeau", "group": 2 }, { "name": "Gervais", "group": 2 }, { "name": "Tholomyes", "group": 3 }, { "name": "Listolier", "group": 3 }, { "name": "Fameuil", "group": 3 }, { "name": "Blacheville", "group": 3 }, { "name": "Favourite", "group": 3 }, { "name": "Dahlia", "group": 3 }, { "name": "Zephine", "group": 3 }, { "name": "Fantine", "group": 3 }, { "name": "Mme.Thenardier", "group": 4 }, { "name": "Thenardier", "group": 4 }, { "name": "Cosette", "group": 5 }, { "name": "Javert", "group": 4 }, { "name": "Fauchelevent", "group": 0 }, { "name": "Bamatabois", "group": 2 }, { "name": "Perpetue", "group": 3 }, { "name": "Simplice", "group": 2 }, { "name": "Scaufflaire", "group": 2 }, { "name": "Woman1", "group": 2 }, { "name": "Judge", "group": 2 }, { "name": "Champmathieu", "group": 2 }, { "name": "Brevet", "group": 2 }, { "name": "Chenildieu", "group": 2 }, { "name": "Cochepaille", "group": 2 }, { "name": "Pontmercy", "group": 4 }, { "name": "Boulatruelle", "group": 6 }, { "name": "Eponine", "group": 4 }, { "name": "Anzelma", "group": 4 }, { "name": "Woman2", "group": 5 }, { "name": "MotherInnocent", "group": 0 }, { "name": "Gribier", "group": 0 }, { "name": "Jondrette", "group": 7 }, { "name": "Mme.Burgon", "group": 7 }, { "name": "Gavroche", "group": 8 }, { "name": "Gillenormand", "group": 5 }, { "name": "Magnon", "group": 5 }, { "name": "Mlle.Gillenormand", "group": 5 }, { "name": "Mme.Pontmercy", "group": 5 }, { "name": "Mlle.Vaubois", "group": 5 }, { "name": "Lt.Gillenormand", "group": 5 }, { "name": "Marius", "group": 8 }, { "name": "BaronessT", "group": 5 }, { "name": "Mabeuf", "group": 8 }, { "name": "Enjolras", "group": 8 }, { "name": "Combeferre", "group": 8 }, { "name": "Prouvaire", "group": 8 }, { "name": "Feuilly", "group": 8 }, { "name": "Courfeyrac", "group": 8 }, { "name": "Bahorel", "group": 8 }, { "name": "Bossuet", "group": 8 }, { "name": "Joly", "group": 8 }, { "name": "Grantaire", "group": 8 }, { "name": "MotherPlutarch", "group": 9 }, { "name": "Gueulemer", "group": 4 }, { "name": "Babet", "group": 4 }, { "name": "Claquesous", "group": 4 }, { "name": "Montparnasse", "group": 4 }, { "name": "Toussaint", "group": 5 }, { "name": "Child1", "group": 10 }, { "name": "Child2", "group": 10 }, { "name": "Brujon", "group": 4 }, { "name": "Mme.Hucheloup", "group": 8 }], "links": [{ "source": 1, "target": 0, "value": 1 }, { "source": 2, "target": 0, "value": 8 }, { "source": 3, "target": 0, "value": 10 }, { "source": 3, "target": 2, "value": 6 }, { "source": 4, "target": 0, "value": 1 }, { "source": 5, "target": 0, "value": 1 }, { "source": 6, "target": 0, "value": 1 }, { "source": 7, "target": 0, "value": 1 }, { "source": 8, "target": 0, "value": 2 }, { "source": 9, "target": 0, "value": 1 }, { "source": 11, "target": 10, "value": 1 }, { "source": 11, "target": 3, "value": 3 }, { "source": 11, "target": 2, "value": 3 }, { "source": 11, "target": 0, "value": 5 }, { "source": 12, "target": 11, "value": 1 }, { "source": 13, "target": 11, "value": 1 }, { "source": 14, "target": 11, "value": 1 }, { "source": 15, "target": 11, "value": 1 }, { "source": 17, "target": 16, "value": 4 }, { "source": 18, "target": 16, "value": 4 }, { "source": 18, "target": 17, "value": 4 }, { "source": 19, "target": 16, "value": 4 }, { "source": 19, "target": 17, "value": 4 }, { "source": 19, "target": 18, "value": 4 }, { "source": 20, "target": 16, "value": 3 }, { "source": 20, "target": 17, "value": 3 }, { "source": 20, "target": 18, "value": 3 }, { "source": 20, "target": 19, "value": 4 }, { "source": 21, "target": 16, "value": 3 }, { "source": 21, "target": 17, "value": 3 }, { "source": 21, "target": 18, "value": 3 }, { "source": 21, "target": 19, "value": 3 }, { "source": 21, "target": 20, "value": 5 }, { "source": 22, "target": 16, "value": 3 }, { "source": 22, "target": 17, "value": 3 }, { "source": 22, "target": 18, "value": 3 }, { "source": 22, "target": 19, "value": 3 }, { "source": 22, "target": 20, "value": 4 }, { "source": 22, "target": 21, "value": 4 }, { "source": 23, "target": 16, "value": 3 }, { "source": 23, "target": 17, "value": 3 }, { "source": 23, "target": 18, "value": 3 }, { "source": 23, "target": 19, "value": 3 }, { "source": 23, "target": 20, "value": 4 }, { "source": 23, "target": 21, "value": 4 }, { "source": 23, "target": 22, "value": 4 }, { "source": 23, "target": 12, "value": 2 }, { "source": 23, "target": 11, "value": 9 }, { "source": 24, "target": 23, "value": 2 }, { "source": 24, "target": 11, "value": 7 }, { "source": 25, "target": 24, "value": 13 }, { "source": 25, "target": 23, "value": 1 }, { "source": 25, "target": 11, "value": 12 }, { "source": 26, "target": 24, "value": 4 }, { "source": 26, "target": 11, "value": 31 }, { "source": 26, "target": 16, "value": 1 }, { "source": 26, "target": 25, "value": 1 }, { "source": 27, "target": 11, "value": 17 }, { "source": 27, "target": 23, "value": 5 }, { "source": 27, "target": 25, "value": 5 }, { "source": 27, "target": 24, "value": 1 }, { "source": 27, "target": 26, "value": 1 }, { "source": 28, "target": 11, "value": 8 }, { "source": 28, "target": 27, "value": 1 }, { "source": 29, "target": 23, "value": 1 }, { "source": 29, "target": 27, "value": 1 }, { "source": 29, "target": 11, "value": 2 }, { "source": 30, "target": 23, "value": 1 }, { "source": 31, "target": 30, "value": 2 }, { "source": 31, "target": 11, "value": 3 }, { "source": 31, "target": 23, "value": 2 }, { "source": 31, "target": 27, "value": 1 }, { "source": 32, "target": 11, "value": 1 }, { "source": 33, "target": 11, "value": 2 }, { "source": 33, "target": 27, "value": 1 }, { "source": 34, "target": 11, "value": 3 }, { "source": 34, "target": 29, "value": 2 }, { "source": 35, "target": 11, "value": 3 }, { "source": 35, "target": 34, "value": 3 }, { "source": 35, "target": 29, "value": 2 }, { "source": 36, "target": 34, "value": 2 }, { "source": 36, "target": 35, "value": 2 }, { "source": 36, "target": 11, "value": 2 }, { "source": 36, "target": 29, "value": 1 }, { "source": 37, "target": 34, "value": 2 }, { "source": 37, "target": 35, "value": 2 }, { "source": 37, "target": 36, "value": 2 }, { "source": 37, "target": 11, "value": 2 }, { "source": 37, "target": 29, "value": 1 }, { "source": 38, "target": 34, "value": 2 }, { "source": 38, "target": 35, "value": 2 }, { "source": 38, "target": 36, "value": 2 }, { "source": 38, "target": 37, "value": 2 }, { "source": 38, "target": 11, "value": 2 }, { "source": 38, "target": 29, "value": 1 }, { "source": 39, "target": 25, "value": 1 }, { "source": 40, "target": 25, "value": 1 }, { "source": 41, "target": 24, "value": 2 }, { "source": 41, "target": 25, "value": 3 }, { "source": 42, "target": 41, "value": 2 }, { "source": 42, "target": 25, "value": 2 }, { "source": 42, "target": 24, "value": 1 }, { "source": 43, "target": 11, "value": 3 }, { "source": 43, "target": 26, "value": 1 }, { "source": 43, "target": 27, "value": 1 }, { "source": 44, "target": 28, "value": 3 }, { "source": 44, "target": 11, "value": 1 }, { "source": 45, "target": 28, "value": 2 }, { "source": 47, "target": 46, "value": 1 }, { "source": 48, "target": 47, "value": 2 }, { "source": 48, "target": 25, "value": 1 }, { "source": 48, "target": 27, "value": 1 }, { "source": 48, "target": 11, "value": 1 }, { "source": 49, "target": 26, "value": 3 }, { "source": 49, "target": 11, "value": 2 }, { "source": 50, "target": 49, "value": 1 }, { "source": 50, "target": 24, "value": 1 }, { "source": 51, "target": 49, "value": 9 }, { "source": 51, "target": 26, "value": 2 }, { "source": 51, "target": 11, "value": 2 }, { "source": 52, "target": 51, "value": 1 }, { "source": 52, "target": 39, "value": 1 }, { "source": 53, "target": 51, "value": 1 }, { "source": 54, "target": 51, "value": 2 }, { "source": 54, "target": 49, "value": 1 }, { "source": 54, "target": 26, "value": 1 }, { "source": 55, "target": 51, "value": 6 }, { "source": 55, "target": 49, "value": 12 }, { "source": 55, "target": 39, "value": 1 }, { "source": 55, "target": 54, "value": 1 }, { "source": 55, "target": 26, "value": 21 }, { "source": 55, "target": 11, "value": 19 }, { "source": 55, "target": 16, "value": 1 }, { "source": 55, "target": 25, "value": 2 }, { "source": 55, "target": 41, "value": 5 }, { "source": 55, "target": 48, "value": 4 }, { "source": 56, "target": 49, "value": 1 }, { "source": 56, "target": 55, "value": 1 }, { "source": 57, "target": 55, "value": 1 }, { "source": 57, "target": 41, "value": 1 }, { "source": 57, "target": 48, "value": 1 }, { "source": 58, "target": 55, "value": 7 }, { "source": 58, "target": 48, "value": 7 }, { "source": 58, "target": 27, "value": 6 }, { "source": 58, "target": 57, "value": 1 }, { "source": 58, "target": 11, "value": 4 }, { "source": 59, "target": 58, "value": 15 }, { "source": 59, "target": 55, "value": 5 }, { "source": 59, "target": 48, "value": 6 }, { "source": 59, "target": 57, "value": 2 }, { "source": 60, "target": 48, "value": 1 }, { "source": 60, "target": 58, "value": 4 }, { "source": 60, "target": 59, "value": 2 }, { "source": 61, "target": 48, "value": 2 }, { "source": 61, "target": 58, "value": 6 }, { "source": 61, "target": 60, "value": 2 }, { "source": 61, "target": 59, "value": 5 }, { "source": 61, "target": 57, "value": 1 }, { "source": 61, "target": 55, "value": 1 }, { "source": 62, "target": 55, "value": 9 }, { "source": 62, "target": 58, "value": 17 }, { "source": 62, "target": 59, "value": 13 }, { "source": 62, "target": 48, "value": 7 }, { "source": 62, "target": 57, "value": 2 }, { "source": 62, "target": 41, "value": 1 }, { "source": 62, "target": 61, "value": 6 }, { "source": 62, "target": 60, "value": 3 }, { "source": 63, "target": 59, "value": 5 }, { "source": 63, "target": 48, "value": 5 }, { "source": 63, "target": 62, "value": 6 }, { "source": 63, "target": 57, "value": 2 }, { "source": 63, "target": 58, "value": 4 }, { "source": 63, "target": 61, "value": 3 }, { "source": 63, "target": 60, "value": 2 }, { "source": 63, "target": 55, "value": 1 }, { "source": 64, "target": 55, "value": 5 }, { "source": 64, "target": 62, "value": 12 }, { "source": 64, "target": 48, "value": 5 }, { "source": 64, "target": 63, "value": 4 }, { "source": 64, "target": 58, "value": 10 }, { "source": 64, "target": 61, "value": 6 }, { "source": 64, "target": 60, "value": 2 }, { "source": 64, "target": 59, "value": 9 }, { "source": 64, "target": 57, "value": 1 }, { "source": 64, "target": 11, "value": 1 }, { "source": 65, "target": 63, "value": 5 }, { "source": 65, "target": 64, "value": 7 }, { "source": 65, "target": 48, "value": 3 }, { "source": 65, "target": 62, "value": 5 }, { "source": 65, "target": 58, "value": 5 }, { "source": 65, "target": 61, "value": 5 }, { "source": 65, "target": 60, "value": 2 }, { "source": 65, "target": 59, "value": 5 }, { "source": 65, "target": 57, "value": 1 }, { "source": 65, "target": 55, "value": 2 }, { "source": 66, "target": 64, "value": 3 }, { "source": 66, "target": 58, "value": 3 }, { "source": 66, "target": 59, "value": 1 }, { "source": 66, "target": 62, "value": 2 }, { "source": 66, "target": 65, "value": 2 }, { "source": 66, "target": 48, "value": 1 }, { "source": 66, "target": 63, "value": 1 }, { "source": 66, "target": 61, "value": 1 }, { "source": 66, "target": 60, "value": 1 }, { "source": 67, "target": 57, "value": 3 }, { "source": 68, "target": 25, "value": 5 }, { "source": 68, "target": 11, "value": 1 }, { "source": 68, "target": 24, "value": 1 }, { "source": 68, "target": 27, "value": 1 }, { "source": 68, "target": 48, "value": 1 }, { "source": 68, "target": 41, "value": 1 }, { "source": 69, "target": 25, "value": 6 }, { "source": 69, "target": 68, "value": 6 }, { "source": 69, "target": 11, "value": 1 }, { "source": 69, "target": 24, "value": 1 }, { "source": 69, "target": 27, "value": 2 }, { "source": 69, "target": 48, "value": 1 }, { "source": 69, "target": 41, "value": 1 }, { "source": 70, "target": 25, "value": 4 }, { "source": 70, "target": 69, "value": 4 }, { "source": 70, "target": 68, "value": 4 }, { "source": 70, "target": 11, "value": 1 }, { "source": 70, "target": 24, "value": 1 }, { "source": 70, "target": 27, "value": 1 }, { "source": 70, "target": 41, "value": 1 }, { "source": 70, "target": 58, "value": 1 }, { "source": 71, "target": 27, "value": 1 }, { "source": 71, "target": 69, "value": 2 }, { "source": 71, "target": 68, "value": 2 }, { "source": 71, "target": 70, "value": 2 }, { "source": 71, "target": 11, "value": 1 }, { "source": 71, "target": 48, "value": 1 }, { "source": 71, "target": 41, "value": 1 }, { "source": 71, "target": 25, "value": 1 }, { "source": 72, "target": 26, "value": 2 }, { "source": 72, "target": 27, "value": 1 }, { "source": 72, "target": 11, "value": 1 }, { "source": 73, "target": 48, "value": 2 }, { "source": 74, "target": 48, "value": 2 }, { "source": 74, "target": 73, "value": 3 }, { "source": 75, "target": 69, "value": 3 }, { "source": 75, "target": 68, "value": 3 }, { "source": 75, "target": 25, "value": 3 }, { "source": 75, "target": 48, "value": 1 }, { "source": 75, "target": 41, "value": 1 }, { "source": 75, "target": 70, "value": 1 }, { "source": 75, "target": 71, "value": 1 }, { "source": 76, "target": 64, "value": 1 }, { "source": 76, "target": 65, "value": 1 }, { "source": 76, "target": 66, "value": 1 }, { "source": 76, "target": 63, "value": 1 }, { "source": 76, "target": 62, "value": 1 }, { "source": 76, "target": 48, "value": 1 }, { "source": 76, "target": 58, "value": 1 }] }
</script>
You can tamper the dx and dy to move it to the center something like this.
node.append("text")
.attr("dx", function(d) { if(d.group > 9) {return -5.5} else {return -1.5;} })
.attr("dy", ".3em")
.text(function(d) { return d.group });
What this does is if the group is 9 then single digit then return -1.5 else for 2 digit return -5.5.
Working code here
Hope this helps!
It works after changing the position of dx;
node.append("text")
.attr("dx", -2)
.attr("dy", ".35em")
.text(function(d) { return d.group });
Here is the updated fiddle.

Resources