ejemplos - graficas en tiempo real javascript
El ejemplo del gráfico de barras D3 no funciona localmente (3)
El método d3.tsv
realiza una solicitud de datos AJAX. En la mayoría de los navegadores, esto no funcionará localmente debido a la misma política de origen , que generalmente prohíbe las solicitudes de file:///
AJAX file:///
urls.
Para obtener un ejemplo que utiliza AJAX ejecutándose localmente, necesitará un servidor web local. Si tiene Python, ejecutándose
> python -m SimpleHTTPServer
desde la línea de comando en el directorio con tus archivos lo hará. Si prefiere node.js, intente http-server .
Soy muy nuevo en D3 y quería ver cómo un ejemplo funcionaría localmente. Copié y pegué el código de gráfico de barras en un archivo local llamado index.html, y también lo copié en data.tsv. Por alguna razón, ¡no aparece absolutamente nada cuando abro el archivo en un navegador! Intenté cambiar el script src a "d3 / d3.v3.min.js" porque esa es la carpeta en la que descargué el d3 que descargué. Sin embargo, esto tampoco funciona. Para cada ejemplo que he intentado, aún no he podido ver correctamente un ejemplo de D3. ¡Ayuda sería apreciada!
El código index.html es el siguiente:
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<script src="d3/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var formatPercent = d3.format(".0%");
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(formatPercent);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.tsv("data.tsv", type, function(error, data) {
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); });
});
function type(d) {
d.frequency = +d.frequency;
return d;
}
</script>
y data.tsv tiene el siguiente formato: frecuencia de letra A .08167 B .01492 C .02780 D .04253 E .12702 F .02288 G .02022 H .06094 I .06973
Como alternativa, y yo mismo fui sugerido por Lars Kotthoff cuando trato de trabajar con archivos .tsv / .csv, puede trabajar directamente para este propósito en:
http://plnkr.co/
Esto le permite trabajar con todos los archivos .json / .tsv / .csv que desee y compartirlos con personas para colaborar. Puede hacerlo de forma anónima o no, lo importante es que no pierda la dirección HTTP generada en ese momento de su plunker.
Una cosa a tener en cuenta es que no puede cargar directamente los archivos de la manera en que lo haría en un servidor FTP, sino que debería:
- Haga clic en "nuevo archivo"
- Escriba el nombre de su archivo .csv / .tsv / .json como se menciona en su código (incluida la extensión)
- Copie y pegue el código que se encuentra en este archivo como está.
- No olvide actualizar los nombres de su .css / .js si es necesario para que coincida con el de su index.html
Como ya se dijo, lo más probable es que se encuentre con un problema CORS con el XHR en la biblioteca d3 para que un recurso externo pueda analizar los datos JSON.
Sin embargo, aquí hay otra solución: use JSONP y Express / Node.js junto con una función jQuery para iniciar una solicitud del lado del cliente para JSON, en lugar de usar el wrapper original para funciones d3.
Tuvo que eliminar el contenedor original d3.json y rellenar los diagramas de adyacencia con los datos de la solicitud. Comience clonando o descargando jsonp-d3-experiment e inicie el servidor utilizando el node server.js
. Por supuesto, necesita tener Node.js instalado globalmente, comenzando con los módulos empaquetados de nodo (npm). Copie su programa en un subdirectorio.
Coloque sus datos JSON en el directorio jsonp-d3-experiment y modifique server.js
para enrutar la solicitud a sus datos:
// Return data from callback
server.get(''/example'', function(req, res)
{
// Read the JSON data and send to JSONP response
readJSON(''example.json'', function (e, json)
{
if (e) { throw e; }
res.jsonp(json);
});
});
A continuación se muestra el código que modifiqué para una matriz de coocurrencia. $.getJSON
todo el script a $.getJSON
y d3.json
completo la función d3.json
.
<script>
$.getJSON("http://localhost:8080/example?callback=?", function(result){
miserables = result;
var margin = {
top: 80,
right: 0,
bottom: 10,
left: 80
},
width = 720,
height = 720;
var x = d3.scale.ordinal().rangeBands([0, width]),
z = d3.scale.linear().domain([0, 4]).clamp(true),
c = d3.scale.category10().domain(d3.range(10));
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("margin-left", -margin.left + "px")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var matrix = [],
nodes = miserables.nodes,
n = nodes.length;
// Compute index per node.
nodes.forEach(function(node, i) {
node.index = i;
node.count = 0;
matrix[i] = d3.range(n).map(function(j) {
return {
x: j,
y: i,
z: 0
};
});
});
// Convert links to matrix; count character occurrences.
miserables.links.forEach(function(link) {
matrix[link.source][link.target].z += link.value;
matrix[link.target][link.source].z += link.value;
matrix[link.source][link.source].z += link.value;
matrix[link.target][link.target].z += link.value;
nodes[link.source].count += link.value;
nodes[link.target].count += link.value;
});
// Precompute the orders.
var orders = {
name: d3.range(n).sort(function(a, b) {
return d3.ascending(nodes[a].name, nodes[b].name);
}),
count: d3.range(n).sort(function(a, b) {
return nodes[b].count - nodes[a].count;
}),
group: d3.range(n).sort(function(a, b) {
return nodes[b].group - nodes[a].group;
})
};
// The default sort order.
x.domain(orders.name);
svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height);
var row = svg.selectAll(".row")
.data(matrix)
.enter().append("g")
.attr("class", "row")
.attr("transform", function(d, i) {
return "translate(0," + x(i) + ")";
})
.each(row);
row.append("line")
.attr("x2", width);
row.append("text")
.attr("x", -6)
.attr("y", x.rangeBand() / 2)
.attr("dy", ".32em")
.attr("text-anchor", "end")
.text(function(d, i) {
return nodes[i].name;
});
var column = svg.selectAll(".column")
.data(matrix)
.enter().append("g")
.attr("class", "column")
.attr("transform", function(d, i) {
return "translate(" + x(i) + ")rotate(-90)";
});
column.append("line")
.attr("x1", -width);
column.append("text")
.attr("x", 6)
.attr("y", x.rangeBand() / 2)
.attr("dy", ".32em")
.attr("text-anchor", "start")
.text(function(d, i) {
return nodes[i].name;
});
function row(row) {
var cell = d3.select(this).selectAll(".cell")
.data(row.filter(function(d) {
return d.z;
}))
.enter().append("rect")
.attr("class", "cell")
.attr("x", function(d) {
return x(d.x);
})
.attr("width", x.rangeBand())
.attr("height", x.rangeBand())
.style("fill-opacity", function(d) {
return z(d.z);
})
.style("fill", function(d) {
return nodes[d.x].group == nodes[d.y].group ? c(nodes[d.x].group) : null;
})
.on("mouseover", mouseover)
.on("mouseout", mouseout);
}
function mouseover(p) {
d3.selectAll(".row text").classed("active", function(d, i) {
return i == p.y;
});
d3.selectAll(".column text").classed("active", function(d, i) {
return i == p.x;
});
}
function mouseout() {
d3.selectAll("text").classed("active", false);
}
d3.select("#order").on("change", function() {
clearTimeout(timeout);
order(this.value);
});
function order(value) {
x.domain(orders[value]);
var t = svg.transition().duration(2500);
t.selectAll(".row")
.delay(function(d, i) {
return x(i) * 4;
})
.attr("transform", function(d, i) {
return "translate(0," + x(i) + ")";
})
.selectAll(".cell")
.delay(function(d) {
return x(d.x) * 4;
})
.attr("x", function(d) {
return x(d.x);
});
t.selectAll(".column")
.delay(function(d, i) {
return x(i) * 4;
})
.attr("transform", function(d, i) {
return "translate(" + x(i) + ")rotate(-90)";
});
}
var timeout = setTimeout(function() {
order("group");
d3.select("#order").property("selectedIndex", 2).node().focus();
}, 5000);
});
</script>
Tenga en cuenta que ahora los datos JSON están en el result
, por lo que lo más fácil fue asignarlos a miserables
.
Nota: se requiere jQuery para esta solución.
Ahora debería poder abrir y representar localmente todas sus visualizaciones de d3 sin tener que alojarlas en un servidor, simplemente ábralas en su navegador directamente desde su sistema de archivos local.
HTH!