nvd3 ブレット チャートをカスタマイズしましたが、正常に動作しています。ウィンドウのサイズが変更されると問題が発生し、chart.update ハンドラーがエラーd3.js:8868 Uncaught TypeError: Cannot read property '1' of undefinedを作成するため、コード コントロールはチャート関数を再度実行しません。助けてください。
// expected input data format
var config = {
title: 'Sample Chart',
subtitle: 'description subtitle',
legend: true,
min: 0,
max: 500,
averageText: 'Top Users in Intro Psychology courses nationally',
data: [{
label: 'Instructor1',
marker: 20,
color: ''
}, {
label: 'Instructor2',
marker: 250,
color: ''
}, {
label: 'Instructor3',
marker: 150,
color: ''
}, {
label: 'Instructor4',
marker: 50,
color: ''
}]
};
// initializing the colors category
var colors = config.data.map(function(val) {
return val.color
}),
defaultColors = d3.scale.category20().range();
// data initialization
function generateData() {
var sum = new Number().valueOf();
config.data.sort(function(val1, val2) {
return val1.marker <= val2.marker;
});
config.data.forEach(function(val, i) {
sum += Number(val.marker);
});
return {
"ranges": [config.min, sum / config.data.length, config.max],
"measures": [config.max],
"markers": config.data.map(function(val) {
return val.marker
})
};
}
// wrap the text within given width
function wrap(text, width) {
var words = text.text().split(/\s+/),
line = [],
dy = parseFloat(text.attr("dy")) || 10,
lineNumber = 0,
lineHeight = 3;
var tspan = text.text(null).append('tspan');
var offset = 0;
while (1) {
if (tspan.node().getComputedTextLength() > width) {
words.unshift(line.pop());
tspan.text(line.join(' '));
offset = (width - tspan.node().getComputedTextLength()) / 2;
tspan.attr('x', offset);
tspan = text.append('tspan').attr("dy", lineHeight + dy);
line = [];
++lineNumber;
} else {
if (!words.length)
break;
line.push(words.shift());
tspan.text(line.join(' '));
offset = (width - tspan.node().getComputedTextLength()) / 2;
tspan.attr('x', offset);
}
}
text.attr('y', -1 * lineNumber * lineHeight * 5);
}
// set the position for markers
function setMarkers(markers) {
markers.each(function(mark, i) {
var marker = d3.select(this);
marker.attr('d', 'M -5 -10 l0 20 l5 5 l5 -5 l0 -20 z')
.style({
'fill': colors[i] || defaultColors[i],
'stroke': 'none'
});
});
}
//convert r,g,b to hex value
function rgb2hex(rgb) {
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
return (rgb && rgb.length === 4) ? "#" +
("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : '';
}
// handle tooltip events
function setTooltipEvents(chart) {
chart.bullet.dispatch.on('elementMouseover.tooltip', function(evt) {
if (evt.label === 'Current') {
return false;
}
var thisBullet = config.data.filter(function(val, i) {
return (rgb2hex(evt.color) == (val.color || defaultColors[i]) && evt.value === val.marker);
})[0];
evt['series'] = {
key: thisBullet.label,
value: evt.value,
color: evt.color
};
chart.tooltip.data(evt).hidden(false);
});
d3.select('#chart #nv-avg').on('mouseover', function(evt) {
evt['series'] = {
key: 'Average',
value: evt.ranges[1],
color: defaultColors[defaultColors.length - 1]
};
chart.tooltip.data(evt).hidden(false);
});
d3.select('#chart #nv-avg').on('mousemove', function(evt) {
chart.tooltip();
});
d3.select('#chart #nv-avg').on('mouseleave', function(evt) {
chart.tooltip.hidden(true);
});
}
// core graph/chart drawing snippet
nv.addGraph(function() {
var chart = nv.models.bulletChart() // initialize the chart
.margin({
right: 10,
left: 10
})
.tickFormat(function(d) {
return d + "%";
});
d3.select('#chart svg') //setup chart svg container
.datum(generateData())
.transition().duration(1000)
.style({
'height': '400px'
})
.call(chart);
var width = nv.utils.availableWidth(null, d3.select('#chart svg'), chart._options.margin);
var scaleBar = d3.select('.nv-measure') // style for main axis
.style({
'fill': '#000',
'height': '5'
});
var parentBox = d3.select(scaleBar.node().parentNode); // wrapper for main axis
var avgRange = d3.select('.nv-rangeAvg').node(); // average marker node
var avgBox = avgRange.getBBox(); // average marker dimensions
var scaleBarBox = scaleBar.node().getBBox(); // main axis dimensions
d3.selectAll('.nv-range').remove(); // remove extra elements
d3.select('.nv-bulletChart').attr('transform', function() {
var transform = d3.transform(d3.select(this).attr("transform"));
return 'translate(' + transform.translate[0] + ',' + 185 + ')';
});
// set average marker
var avgRectWidth = 150,
avgRectHeight = 50;
var avgMarker = parentBox.append('g').attr({
'transform': 'translate(' + (avgBox.x + avgBox.width - avgRectWidth / 2) + ',' + (-1 * (avgRectHeight - scaleBarBox.y)) + ')',
'id': 'nv-avg'
});
var avgMarkerRect = avgMarker.append('rect')
.attr({
'width': avgRectWidth,
'height': avgRectHeight,
'x': 0,
'y': 0,
'fill': '#fff',
'fill-opacity': 0
});
var avgMarkerBox = avgMarkerRect.node().getBBox();
avgMarker.append('path')
.attr({
'transform': 'translate(' + (avgMarkerBox.x + avgMarkerBox.width / 2) + ',' + avgMarkerBox.height + ')',
'd': 'M0 0 l7.5 -5 l0 -25 l-15 0 l0 25 z'
}).style({
'fill': defaultColors[defaultColors.length - 1],
'stroke': 'none'
});
avgMarker.append('text').text(config.averageText).attr({
'x': 0,
'y': 0
});
d3.select('#nv-avg text').call(wrap, avgMarkerBox.width);
// left end circle
parentBox.append('circle').attr({
'cx': scaleBarBox.x,
'cy': scaleBarBox.y + scaleBarBox.height / 2,
'r': '10'
});
//right end circle
parentBox.append('circle').attr({
'cx': scaleBarBox.x + scaleBarBox.width,
'cy': scaleBarBox.y + scaleBarBox.height / 2,
'r': '10'
});
// set markers for data to be plotted
d3.select('#chart').selectAll('.nv-markerTriangle')
.call(setMarkers);
//optional functionality to format ticks
d3.selectAll('#chart .nv-tick').each(function(tick, i) {
var text = d3.select(this).select('text');
if (i % 2 !== 0)
text.text('');
});
setTooltipEvents(chart);
nv.utils.windowResize(function() {
chart.update();
width = nv.utils.availableWidth(null, d3.select('#chart svg'), chart._options.margin);
}); // update chart on resize
return chart;
});
<html>
<head>
<link data-require="nvd3@*" data-semver="1.8.1" rel="stylesheet" href="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.css" />
<link data-require="bootstrap-css@*" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
<script data-require="nvd3@*" data-semver="1.8.1" src="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.js"></script>
<script type="text/javascript.js"></script>
</head>
<body>
<div id="chart" class="container" style="position: relative;top: 50px;">
<svg></svg>
</div>
</body>
</html>