graph - una - plot matlab
Agregar información sobre herramientas al gráfico lineal D3 (1)
Me estoy volviendo loco sobre cómo agregar información sobre herramientas a mi gráfico d3 lineal, para que el usuario pueda ver el valor específico del rendimiento a lo largo de los años. Este es el violín: http://jsfiddle.net/d9Lya/ y este es el código
// define dimensions of graph
var m = [20, 80, 80, 80]; // margins
var w = 650 - m[1] - m[3]; // width
var h = 500 - m[0] - m[2]; // height
var data = [30, 28, 33] ;
var years = [2010, 2011, 2012] ;
var data2 = [100, 200, 200] ;
var years2 = [2009, 2010, 2011] ;
var alldata = data.concat(data2);
var allyears = years.concat(years2);
var data3 = [200, 220, 300] ;
var years3 = [2011, 2012, 2013] ;
var alldata = data.concat(data2, data3);
var allyears = years.concat(years2, years3);
//unique vals functin
var unique = function(origArr) {
var newArr = [],
origLen = origArr.length,
found,
x, y;
for ( x = 0; x < origLen; x++ ) {
found = undefined;
for ( y = 0; y < newArr.length; y++ ) {
if ( origArr[x] === newArr[y] ) {
found = true;
break;
}
}
if ( !found) newArr.push( origArr[x] );
}
return newArr;
};
allyears = unique(allyears);
var x = d3.scale.linear().domain([d3.min(allyears), d3.max(allyears)]).range([0,w]);
var y = d3.scale.linear().domain([0, (d3.max(alldata))*1.3]).range([h, 0]);
var line = d3.svg.line()
.x(function(d,i) {
return x(years[i]);
})
.y(function(d) {
return y(d);
})
var line2 = d3.svg.line()
.x(function(d,i) {
return x(years2[i]);
})
.y(function(d) {
return y(d);
})
var line3 = d3.svg.line()
.x(function(d,i) {
return x(years3[i]);
})
.y(function(d) {
return y(d);
})
// Add an SVG element with the desired dimensions and margin.
var graph = d3.select("#graph").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
// create xAxis
var xAxis = d3.svg.axis().scale(x).ticks(allyears.length).tickSize(-h).tickSubdivide(true);
// Add the x-axis.
graph.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis);
// create left yAxis
var yAxisLeft = d3.svg.axis().scale(y).ticks(8).orient("left");
// Add the y-axis to the left
graph.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(-25,0)")
.call(yAxisLeft);
graph.append("svg:text")
.attr("class", "title1")
.attr("x", (w/2))
.attr("y", 0)
.text("Performance")
.style({ "stroke": "Black", "fill": "Black", "stroke-width": "1px"})
.attr("text-anchor", "middle")
.style("font-size", "16px") ;
graph.append("svg:path").attr("d", line(data)).style("stroke", "steelblue");
graph.append("svg:text")
.attr("class", "title1")
.attr("x", 0)
.attr("y", 30)
.text("TEAM A")
.style({ "stroke": "steelblue", "fill": "steelblue", "stroke-width": "0px"});
graph.append("svg:path")
.attr("d", line2(data2)).style("stroke", "green")
;
graph.append("svg:text")
.attr("class", "title2")
.attr("x", 0)
.attr("y", 50)
.text("TEAM B")
.style({ "stroke": "Green", "fill": "Green", "stroke-width": "0px"});
graph.append("svg:path").attr("d", line3(data3)).style("stroke", "red");
graph.append("svg:text")
.attr("class", "title3")
.attr("x", 0)
.attr("y", 70)
.text("team C")
.style({ "stroke": "Red", "fill": "Red", "stroke-width": "0px"});
En realidad, soy nuevo en D3 y he visto muchas otras muestras y no puedo reproducirlas en mi código js. ¿Alguien puede ayudarme? Saludos
Mencioné en los comentarios que "los datos de la línea son la matriz completa, y averiguar dónde en la línea el mouse del usuario requerirá un cálculo adicional". Esa es una de las razones para usar "círculos invisibles" para tomar eventos del mouse sobre los puntos de datos. Otra es que puede hacer que el radio del círculo sea mucho más grande que el ancho del trazo para hacer un área más grande para los eventos del mouse. Una tercera es que puede decorar los círculos al pasar el ratón , como en los gráficos de líneas NVD3 .
Pero, ¿qué sucede si no quieres círculos adicionales que llenen tu DOM? ¿O qué pasa si quieres que el evento mouseover se active en cualquier lugar de la línea, no solo en los puntos? Todavía puede averiguar dónde está el mouse relativo a la línea y puede usarlo para encontrar el punto correcto en la matriz de datos para esa línea.
d3.selectAll("path")
.on("mouseover", findValue);
function findValue(d, i) {
var mouseX = d3.mouse(this.parentNode)[0];
//find the mouse''s horizontal coordinate relative to the drawing container
var dataX = x.invert(mouseX);
//invert the scale to find the x value at the mouse point
//scan through the data array to find the value closest to the mouse
var j = d.length;
while ((j--) && (d[j].x > dataX)); //repeat until false
var datapoint;
if (j >= 0) {
//d[j] will now be the first datapoint *less than* the mousepoint
//compare it with d[j+1] to see which is closer to the mouse:
if ( isNaN(d[j+1]) || (dataX - d[j].x < d[j+1].x - dataX) )
datapoint = d[j];
else
datapoint = d[j+1];
} else {
//all the values in the array were greater than the mouse point,
//so return the first point
datapoint = d[0];
}
//Do something with your datapoint value:
alert("Crossed line " + i + " near " + [datapoint.x, datapoint.y]);
}
Ejemplo en vivo aquí: http://fiddle.jshell.net/c2mru/8/
El valor d
pasado a la función del controlador de eventos es el objeto de datos adjunto al elemento <path>
. Esa es normalmente la matriz de puntos en la línea, aunque a veces es un objeto que contiene la matriz de puntos como una propiedad, en cuyo caso tendría que enmendar esto para adaptarlo. Utilizando d3.mouse(container)
puede determinar la posición del mouse en el sistema de coordenadas SVG correspondiente, y utilizando el método de inversión de la escala puede determinar la posición del mouse con respecto al eje horizontal. Luego, suponiendo que sus datos son un gráfico de líneas normal que no repite los valores de x, es una simple cuestión de desplazarse por la matriz de puntos para encontrar el más cercano al mouse.
Tenga en cuenta que este método no funcionará con el código original de @picus, porque ese código en realidad no usa métodos d3 para vincular datos a los elementos. (@picus, echa un vistazo a la página de Tutoriales para saber cómo hacer que trabajar con d3 sea mucho más fácil).