我有一个用Nvd3(http://krispo.github.io/angular-nvd3/)制作的图形,它工作正常,显示了良好的数据,但是我有两个问题;第一个,不是那么重要,是当我越过点(圆的动画)时没有动画的事实。
第二个问题更为重要,我在图表中添加了一个元素单击事件,奇怪的是,当我第一次在图形上单击时,该事件未触发,而第二次则触发。而且,当我使用示例plunkr(代码中的函数sinAndCos)中的数据时,不会出现此问题,但是当我使用自己的数据时,就会出现此问题。我尝试显示两组数据,它们非常相似,除了sinAndCos每条曲线有100个点,而我的有70个点。
这是我的图形代码:
console.log('RELOADCHART in progress')
var tmPoints = [];
var data = [];
function getData(){
angular.forEach(scope.curves, function (element) {
if (angular.isArray(element.tm)) {
tmPoints[element.well] = element.tm[0];
}
var wellName = element.well;
// Get all the points inside an array [{x:..,y:...},{...}]
var pointsValues = [];
console.log(normalized);
if (normalized) {
element.points.forEach(function (point) {
pointsValues.push({x: parseFloat(point.temperature), y: parseFloat(point.normalized)});
});
} else {
element.points.forEach(function (point) {
pointsValues.push({x: parseFloat(point.temperature), y: parseFloat(point.fluorescence)});
});
}
// Sort all the points by x
var values = pointsValues.sort(function (a, b) {
return a.x - b.x;
});
data.push({
values: values,
key: wellName,
color: CSS_COLOR_NAMES[Object.keys(scope.curves).indexOf(element.well)],
strokeWidth: 2
});
});
return data;
}
// Here if I use sinAndCos I don't have the problem
scope.data = getData();
/*Random Data Generator */
function sinAndCos() {
var sin = [], sin2 = [],
cos = [];
//Data is represented as an array of {x,y} pairs.
for (var i = 0; i < 100; i++) {
sin.push({x: i, y: Math.sin(i / 10)});
sin2.push({x: i, y: i % 10 == 5 ? null : Math.sin(i / 10) * 0.25 + 0.5});
cos.push({x: i, y: .5 * Math.cos(i / 10 + 2) + Math.random() / 10});
}
//Line chart data should be sent as an array of series objects.
return [
{
values: sin, //values - represents the array of {x,y} data points
key: 'Sine Wave', //key - the name of the series.
color: '#ff7f0e', //color - optional: choose your own line color.
strokeWidth: 2,
classed: 'dashed'
},
{
values: cos,
key: 'Cosine Wave',
color: '#2ca02c'
},
{
values: sin2,
key: 'Another sine wave',
color: '#7777ff',
area: true //area - set to true if you want this line to turn into a filled area chart.
}
];
};
scope.options = {
chart: {
type: 'lineChart',
height: 450,
margin: {
top: 20,
right: 20,
bottom: 40,
left: 55
},
//yDomain: [minY-100,maxY+100],
x: function (d) {
return d.x;
},
y: function (d) {
return d.y;
},
// Use interactive guideline if there is more than one set of data
useInteractiveGuideline: !(data.length === 1),
dispatch: {
stateChange: function (e) {
console.log("stateChange");
},
changeState: function () {
console.log("changeState");
},
tooltipShow: function () {
console.log("tooltipShow");
},
tooltipHide: function () {
console.log("tooltipHide");
}
},
transitionDuration: 500,
xAxis: {
axisLabel: 'Temperature (Celcius)'
},
yAxis: {
axisLabel: 'Fluorescence',
tickFormat: getTickFormat(normalized),
axisLabelDistance: -10
},
callback: function (chart) {
console.log("!!! lineChart callback !!!");
chart.lines.dispatch.on("elementClick", function (e) {
console.log("ELEMENT_CLICK");
});
/**
* ==> chart.lines.dispatch.on("elementclick") ne se déclenche qu'a partir d'un second clic,
* rien n'y fait pour le déclencher au premier clic, c'est comme si la méthode était inexistante
* a ce moment la
*/
if (angular.isObject(scope.api)) {
resetHighlight();
data = scope.data;
// Check if there is only one set of data
if ((data.length === 1 && angular.isObject(tmPoints[data[0].key]))) {
// If there is a TM for this set of data we show it
data[0].values.forEach(function (element) {
if (parseInt(element.x) === parseInt(tmPoints[data[0].key].tm)) {
// Recuperer l'objet point et non ses valeurs
highlightPoint(chart, {'point': element}, 10, true);
}
});
}
// If there is only one set of data we can active the tm calculation
if (data.length === 1) {
chart.lines.dispatch.on("elementClick", function (e) {
console.log("ELEMENT_CLICK");
// If there is already two points clicked
if (clickedPoints.length >= 2) {
// Remove the first point of the array
var pointToDelete = clickedPoints.shift();
// And remove his highlight
removeHighlightPoint(pointToDelete, pointToDelete.element.attributes[1].nodeValue);
}
// Push the new point
clickedPoints.push(e);
// Send the points to the controller
$rootScope.$broadcast(EVENTS.ADD_POINT, clickedPoints);
// highlight it
if (e.point)
highlightPoint(chart, e, 7, false);
});
}
}
}
},
title: {
enable: true,
text: 'Line Chart'
}
};
scope.api.refresh();
}
}