问题
I'm currently redesigning some visualizations to go from static embedded output from R to interactive graphs using angular-nvd3. I've made considerable progress and have nearly finished re-implementing all the options necessary.
However, the last part that is evading me is figuring out how to add persistent labels to all the data points.
While I have customized tooltips for this, it was one of the client requests to have names display as a toggle, so I don't think I can get around it.
Is there a built-in way to do this? I couldn't find anything through the nvd3 documentation.
I've included code from the reference scatter plot example - mine is very specific so this would be easier to work from.
var app = angular.module('plunker', ['nvd3']);
app.controller('MainCtrl', function($scope) {
$scope.options = {
chart: {
type: 'scatterChart',
height: 450,
color: d3.scale.category10().range(),
scatter: {
onlyCircles: false
},
showDistX: true,
showDistY: true,
tooltipContent: function(key) {
return '<h3>' + key + '</h3>';
},
duration: 350,
xAxis: {
axisLabel: 'X Axis',
tickFormat: function(d){
return d3.format('.02f')(d);
}
},
yAxis: {
axisLabel: 'Y Axis',
tickFormat: function(d){
return d3.format('.02f')(d);
},
axisLabelDistance: -5
},
zoom: {
//NOTE: All attributes below are optional
enabled: false,
scaleExtent: [1, 10],
useFixedDomain: false,
useNiceScale: false,
horizontalOff: false,
verticalOff: false,
unzoomEventType: 'dblclick.zoom'
}
}
};
$scope.data = generateData(4,40);
/* Random Data Generator (took from nvd3.org) */
function generateData(groups, points) {
var data = [],
shapes = ['circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],
random = d3.random.normal();
for (var i = 0; i < groups; i++) {
data.push({
key: 'Group ' + i,
values: []
});
for (var j = 0; j < points; j++) {
data[i].values.push({
x: random()
, y: random()
, size: Math.random()
, shape: shapes[j % 6]
});
}
}
return data;
}
});
回答1:
No nvd3 has nothing to show labels as per your requirement.
But this can be achieved mixing a little of d3 like this:
$scope.clear= function(){
d3.selectAll(".label").remove();//will clear all the labels
}
$scope.showLabel= function(){
$scope.clear();
//for each path make label
d3.selectAll(".nv-group path")[0].forEach(function(d){
var tf = d3.select(d).attr("transform")
t = d3.transform(tf).translate;
t[0] = t[0] +10;//moving the translate x by 5 pixel.
console.log(d3.select(d).data()[0])//data associated with the point
d3.select(d.parentNode)
.append("text")
.attr("class", "label")
.text("data: "+ d3.select(d).data()[0][1])//putting data
.attr("transform", "translate("+t[0]+","+t[1]+")");/setting the changed translate for label
});
}
Working code here
Hope this helps!
回答2:
You need array for names that you want to give. Check this code to cross check:
for (var i = 0; i < groups; i++) {
var names = new Array ('London', 'Paris','New York','India');
data.push({
key: names[i],
values: []
});
Code in App.js (edited) :
var app = angular.module('plunker', ['nvd3']);
app.controller('MainCtrl', function($scope) {
$scope.options = {
chart: {
type: 'scatterChart',
height: 450,
color: d3.scale.category10().range(),
scatter: {
onlyCircles: false
},
showDistX: true,
showDistY: true,
tooltipContent: function(key) {
return '<h3>' + key + '</h3>';
},
duration: 350,
xAxis: {
axisLabel: 'X Axis',
tickFormat: function(d){
return d3.format('.02f')(d);
}
},
yAxis: {
axisLabel: 'Y Axis',
tickFormat: function(d){
return d3.format('.02f')(d);
},
axisLabelDistance: -5
},
zoom: {
//NOTE: All attributes below are optional
enabled: false,
scaleExtent: [1, 10],
useFixedDomain: false,
useNiceScale: false,
horizontalOff: false,
verticalOff: false,
unzoomEventType: 'dblclick.zoom'
}
}
};
$scope.data = generateData(4,40);
/* Random Data Generator (took from nvd3.org) */
function generateData(groups, points) {
var data = [],
shapes = ['circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],
random = d3.random.normal();
for (var i = 0; i < groups; i++) {
var names = new Array ('London', 'Paris','New York','India');
data.push({
key: names[i],
values: []
});
for (var j = 0; j < points; j++) {
data[i].values.push({
x: random()
, y: random()
, size: Math.random()
, shape: shapes[j % 6]
});
}
}
return data;
}
});
来源:https://stackoverflow.com/questions/34279908/appending-text-to-points-in-angular-nvd3