Built with blockbuilder.org
forked from f94f's block: cuatro en uno
| license: mit |
Built with blockbuilder.org
forked from f94f's block: cuatro en uno
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script src="https://unpkg.com/d3-force-attract@latest"></script> | |
| <script src="https://unpkg.com/d3-force-cluster@latest"></script> | |
| <script src="https://rawgit.com/exupero/saveSvgAsPng/gh-pages/saveSvgAsPng.js"></script> | |
| <style> | |
| /*body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }*/ | |
| .bar-pe { | |
| fill: #0075ea; | |
| } | |
| .bar-to { | |
| fill: #008e2d; | |
| } | |
| .bar-pa { | |
| fill: #ffa500; | |
| } | |
| .bar-re { | |
| fill: #FF0000; | |
| } | |
| .bar-pe:hover { | |
| fill: #56aafe; | |
| } | |
| .bar-to:hover { | |
| fill: #00BC3C; | |
| } | |
| .bar-pa:hover { | |
| fill: #ffbb3d; | |
| } | |
| .bar-re:hover { | |
| fill: #ff1e1e; | |
| } | |
| /*tooltip*/ | |
| .show { | |
| display: block; | |
| } | |
| .hidden { | |
| display: none; | |
| } | |
| .tooltip { | |
| background-color: #333; | |
| padding: 4px 8px; | |
| position: absolute; | |
| color: #fff; | |
| opacity: 0.8; | |
| z-index: 100; | |
| } | |
| .title { | |
| font: bold 14px "Helvetica Neue", Helvetica, Arial, sans-serif; | |
| } | |
| .axis { | |
| font: 10px sans-serif; | |
| } | |
| .axis path, | |
| .axis line { | |
| fill: none; | |
| stroke: #000; | |
| stroke-dasharray: 2px 2px; | |
| } | |
| .x.axis path { | |
| display: none; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="prueba" style="width:1300px; height:1000px"> | |
| </div> | |
| <button class="btn btn-primary" onclick="svgToPng()">svg to png</button> | |
| <script> | |
| //Inicio Barras1 | |
| var puntos1 = [ | |
| {name: "Pendientes", value: 0.40}, | |
| {name: "Totales", value: 0.0667}, | |
| {name: "Parciales", value: 0.0667}, | |
| {name: "Rechazados", value: 0.0} | |
| ]; | |
| var widthAbs = 1000; | |
| heightAbs = 1000; | |
| var margin1 = {top: 50, right: 0, bottom: 50, left: 50}, | |
| width1 = 650 - margin1.left - margin1.right, | |
| height1 = 500 - margin1.top - margin1.bottom; | |
| var x1 = d3.scaleBand().rangeRound([0, width1], 0.1, 0.3); | |
| var y1 = d3.scaleLinear() | |
| .range([height1, 0]); | |
| var xAxis1 = d3.axisBottom() | |
| .scale(x1); | |
| var yAxis1 = d3.axisLeft() | |
| .scale(y1) | |
| .ticks(8, "%"); | |
| var tooltip = d3.select("#prueba").append("div") | |
| .attr("class", "tooltip"); | |
| var svg = d3.select("#prueba").append("svg") | |
| .attr("width", 100 + "%") | |
| .attr("height", 100 + "%") | |
| .append("g") | |
| .attr("transform", "translate(" + margin1.left + "," + margin1.top + ")"); | |
| //GRÁFICO 1 | |
| x1.domain(puntos1.map(function(d) { return d.name; })); | |
| y1.domain([0, d3.max(puntos1, function(d) { return d.value; })]); | |
| svg.append("text") | |
| .attr("class", "title") | |
| .attr("x", (width1 / 5)) | |
| .attr("y", -20) | |
| .text("Porcentaje de las entregas según su estado"); | |
| svg.append("g") | |
| .attr("class", "x axis") | |
| .attr("transform", "translate(0," + height1 + ")") | |
| .call(xAxis1) | |
| .selectAll(".tick text") | |
| .call(wrap, x1.bandwidth()); | |
| svg.append("g") | |
| .attr("class", "y axis") | |
| .call(yAxis1); | |
| svg.selectAll(".bar") | |
| .data(puntos1) | |
| .enter().append("rect") | |
| .attr("class", function(d) { | |
| if(d.name == "Pendientes") { return "bar-pe";} | |
| else if(d.name == "Totales") { return "bar-to";} | |
| else if(d.name == "Parciales") { return "bar-pa";} | |
| else if(d.name == "Rechazados") { return "bar-re";} | |
| }) | |
| .attr("x", function(d) { return x1(d.name); }) | |
| .attr("width", x1.bandwidth()) | |
| .attr("y", function(d) { return y1(d.value); }) | |
| .attr("height", function(d) { return height1 - y1(d.value); }) | |
| .on('mouseover', function(d){ | |
| d3.select("#major").text(d.key); | |
| tooltip.transition() | |
| .duration(500) | |
| .style("opacity", 1); | |
| tooltip.html((d.value * 100) + "%") | |
| .style("left", (d3.event.pageX - 25) + "px") | |
| .style("top", (d3.event.pageY - 50) + "px"); | |
| }) | |
| .on('mousemove', function (d) { | |
| tooltip.style("top", (d3.event.pageY - 50) + 'px'); | |
| tooltip.style("left", (d3.event.pageX - 25) + 'px'); | |
| }) | |
| .on('mouseout', function(d){ | |
| d3.select("#major").text("Mouse over"); | |
| tooltip.transition() | |
| .duration(500) | |
| .style("opacity", 0); | |
| }) | |
| for(var k=0; k<4;k++) { | |
| svg.append("text") | |
| .attr("class", "title") | |
| .attr("x", (55+150*k)) | |
| .attr("y", (height1/2)) | |
| .text(puntos1[k]["value"] + "%"); | |
| } | |
| //GRÁFICO 2 | |
| var puntos2 = [ | |
| {name: "Pendientes", value: 0.40}, | |
| {name: "Totales", value: 0.0667}, | |
| {name: "Parciales", value: 0.0667}, | |
| {name: "Rechazados", value: 0.0} | |
| ]; | |
| var margin2 = {top: 50, right: 0, bottom: 50, left: 50}, | |
| widthYaxis = width1+margin2.left+1, | |
| width2 = width1*2, | |
| height2 = height1; | |
| var x2 = d3.scaleBand().rangeRound([width1+margin2.left, width2], 0.1, 0.3); | |
| var y2 = d3.scaleLinear() | |
| .range([height2, 0]); | |
| var xAxis2 = d3.axisBottom() | |
| .scale(x2); | |
| var yAxis2 = d3.axisLeft() | |
| .scale(y2) | |
| .ticks(8, "%"); | |
| var grafica2 = d3.select("#prueba").append("svg") | |
| .append("g"); | |
| x2.domain(puntos2.map(function(d) { return d.name; })); | |
| y2.domain([0, d3.max(puntos2, function(d) { return d.value; })]); | |
| svg.append("text") | |
| .attr("class", "title") | |
| .attr("x", width1+(width2 / 5)) | |
| .attr("y", -20) | |
| .text("Porcentaje de las entregas según su estado"); | |
| svg.append("g") | |
| .attr("class", "x axis") | |
| .attr("transform", "translate(0," + height2 + ")") | |
| .call(xAxis2) | |
| .selectAll(".tick text") | |
| .call(wrap, x2.bandwidth()); | |
| svg.append("g") | |
| .attr("class", "y axis") | |
| .attr("transform", "translate(" + widthYaxis + ", 0)") | |
| .call(yAxis2); | |
| svg.selectAll(".bar") | |
| .data(puntos2) | |
| .enter().append("rect") | |
| .attr("class", function(d) { | |
| if(d.name == "Pendientes") { return "bar-pe";} | |
| else if(d.name == "Totales") { return "bar-to";} | |
| else if(d.name == "Parciales") { return "bar-pa";} | |
| else if(d.name == "Rechazados") { return "bar-re";} | |
| }) | |
| .attr("x", function(d) { return x2(d.name); }) | |
| .attr("width", x2.bandwidth()) | |
| .attr("y", function(d) { return y2(d.value); }) | |
| .attr("height", function(d) { return height2 - y2(d.value); }) | |
| .on('mouseover', function(d){ | |
| d3.select("#major").text(d.key); | |
| tooltip.transition() | |
| .duration(500) | |
| .style("opacity", 1); | |
| tooltip.html((d.value * 100) + "%") | |
| .style("left", (d3.event.pageX - 25) + "px") | |
| .style("top", (d3.event.pageY - 50) + "px"); | |
| }) | |
| .on('mousemove', function (d) { | |
| tooltip.style("top", (d3.event.pageY - 50) + 'px'); | |
| tooltip.style("left", (d3.event.pageX - 25) + 'px'); | |
| }) | |
| .on('mouseout', function(d){ | |
| d3.select("#major").text("Mouse over"); | |
| tooltip.transition() | |
| .duration(500) | |
| .style("opacity", 0); | |
| }); | |
| for(var l=0; l<4;l++) { | |
| svg.append("text") | |
| .attr("class", "title") | |
| .attr("x", (width1 + 100 + 140*l )) | |
| .attr("y", (height1/2)) | |
| .text(puntos2[l]["value"] + "%"); | |
| } | |
| //GRÁFICO 3 | |
| var puntos3 = [ | |
| {name: "Pendientes", value: 0.40}, | |
| {name: "Totales", value: 0.0667}, | |
| {name: "Parciales", value: 0.0667}, | |
| {name: "Rechazados", value: 0.0} | |
| ]; | |
| var margin3 = {top: 100, right: 0, bottom: 50, left: 50}, | |
| width3 = width1, | |
| height3 = height1*2 + margin3.top; | |
| var x3 = d3.scaleBand().rangeRound([0, width3], 0.1, 0.3); | |
| var y3 = d3.scaleLinear() | |
| .range([height3, height1 + margin3.top]); | |
| var xAxis3 = d3.axisBottom() | |
| .scale(x3); | |
| var yAxis3 = d3.axisLeft() | |
| .scale(y3) | |
| .ticks(8, "%"); | |
| var grafica3 = d3.select("#prueba").append("svg") | |
| .append("g"); | |
| x3.domain(puntos3.map(function(d) { return d.name; })); | |
| y3.domain([0, d3.max(puntos3, function(d) { return d.value; })]); | |
| svg.append("text") | |
| .attr("class", "title") | |
| .attr("x", (width1 / 5)) | |
| .attr("y", (height1 + margin3.top)-20) | |
| .text("Porcentaje de las entregas según su estado"); | |
| svg.append("g") | |
| .attr("class", "x axis") | |
| .attr("transform", "translate(0," + height3 + ")") | |
| .call(xAxis3) | |
| .selectAll(".tick text") | |
| .call(wrap, x3.bandwidth()); | |
| svg.append("g") | |
| .attr("class", "y axis") | |
| .call(yAxis3); | |
| svg.selectAll(".bar") | |
| .data(puntos1) | |
| .enter().append("rect") | |
| .attr("class", function(d) { | |
| if(d.name == "Pendientes") { return "bar-pe";} | |
| else if(d.name == "Totales") { return "bar-to";} | |
| else if(d.name == "Parciales") { return "bar-pa";} | |
| else if(d.name == "Rechazados") { return "bar-re";} | |
| }) | |
| .attr("x", function(d) { return x3(d.name); }) | |
| .attr("width", x3.bandwidth()) | |
| .attr("y", function(d) { return y3(d.value); }) | |
| .attr("height", function(d) { return height3 - y3(d.value); }) | |
| .on('mouseover', function(d){ | |
| d3.select("#major").text(d.key); | |
| tooltip.transition() | |
| .duration(500) | |
| .style("opacity", 1); | |
| tooltip.html((d.value * 100) + "%") | |
| .style("left", (d3.event.pageX - 25) + "px") | |
| .style("top", (d3.event.pageY - 50) + "px"); | |
| }) | |
| .on('mousemove', function (d) { | |
| tooltip.style("top", (d3.event.pageY - 50) + 'px'); | |
| tooltip.style("left", (d3.event.pageX - 25) + 'px'); | |
| }) | |
| .on('mouseout', function(d){ | |
| d3.select("#major").text("Mouse over"); | |
| tooltip.transition() | |
| .duration(500) | |
| .style("opacity", 0); | |
| }) | |
| for(var z=0; z<4;z++) { | |
| svg.append("text") | |
| .attr("class", "title") | |
| .attr("x", (55 + 150*z )) | |
| .attr("y", (height3 - 200)) | |
| .text(puntos2[z]["value"] + "%"); | |
| } | |
| function wrap(text, width) { | |
| text.each(function() { | |
| var text = d3.select(this), | |
| words = text.text().split(/\s+/).reverse(), | |
| word, | |
| line = [], | |
| lineNumber = 0, | |
| lineHeight = 1.1, // ems | |
| y = text.attr("y"), | |
| dy = parseFloat(text.attr("dy")), | |
| tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"); | |
| while (word = words.pop()) { | |
| line.push(word); | |
| tspan.text(line.join(" ")); | |
| if (tspan.node().getComputedTextLength() > width) { | |
| line.pop(); | |
| tspan.text(line.join(" ")); | |
| line = [word]; | |
| tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word); | |
| } | |
| } | |
| }); | |
| } | |
| function type(d) { | |
| d.value = +d.value; | |
| return d; | |
| } | |
| //Fin Barras | |
| //Inicio Motivos | |
| var datos = [ | |
| {motivo: "Emp", frequency: 10}, | |
| {motivo: "Pro", frequency: 1}, | |
| {motivo: "Can", frequency: 3}, | |
| {motivo: "No", frequency: 4}, | |
| {motivo: "Cli", frequency: 5}, | |
| {motivo: "Epa", frequency: 6}, | |
| {motivo: "Prd", frequency: 7}, | |
| {motivo: "Cie", frequency: 8}, | |
| {motivo: "Ent", frequency: 9}, | |
| {motivo: "Noh", frequency: 9}, | |
| {motivo: "Cen", frequency: 9}, | |
| {motivo: "Otros", frequency: 9} | |
| ]; | |
| var width4 = width2 + (width2/2) +10, | |
| height4 = height3 + (height3/2), | |
| padding = 1.5, // separation between same-color nodes | |
| clusterPadding = 0, // separation between different-color nodes | |
| maxRadius = 40; | |
| minRadius = 15; | |
| contador = 0; | |
| var n = datos.length, // total number of nodes | |
| m = 20; // number of distinct clusters | |
| var salto = function() { | |
| if ( maxRadius/n > minRadius) | |
| return Math.floor(maxRadius/n); | |
| else | |
| return minRadius; | |
| } | |
| var color = d3.scaleLinear().domain([0,1]) | |
| .interpolate(d3.interpolateHcl) | |
| .range([d3.rgb("#EBEBFF"), d3.rgb('#0000FF')]); | |
| // The largest node for each cluster. | |
| var clusters = new Array(m); | |
| var nodes = d3.range(n).map(function () { | |
| var i = Math.floor(Math.random() * m), | |
| i1 = contador, | |
| r = Math.sqrt((i + 1) / m * -Math.log(Math.random())) * maxRadius, | |
| r1 = datos[contador]["frequency"], | |
| r2 = function () { | |
| var actual = datos[contador]["frequency"]; | |
| var maximo = datos[0]["frequency"]; | |
| var relacion = Math.floor(actual * maxRadius / maximo); | |
| if (relacion <= salto()) | |
| return salto(); | |
| return (relacion); | |
| }, | |
| degrade = function () { | |
| var actual = datos[contador]["frequency"]; | |
| var maximo = datos[0]["frequency"]; | |
| var relacion = Math.floor(actual * n / maximo); | |
| return relacion; | |
| }, | |
| d = { | |
| cluster: i1, | |
| degrade: degrade(), | |
| radius: r2(), | |
| nombre: datos[contador]["motivo"], | |
| frecuencia: datos[contador]["frequency"], | |
| x: Math.cos(i1 / m * 2 * Math.PI) * 200 + width4 / 2 + Math.random(), | |
| y: Math.sin(i1 / m * 2 * Math.PI) * 200 + height4 / 2 + Math.random() | |
| }; | |
| contador++; | |
| if (!clusters[i1] || (r2 > clusters[i1].radius)) clusters[i1] = d; | |
| return d; | |
| }); | |
| var simulation = d3.forceSimulation() | |
| // keep entire simulation balanced around screen center | |
| .force('center', d3.forceCenter(width4/2, height4/2)) | |
| // pull toward center | |
| .force('attract', d3.forceAttract() | |
| .target([width4/2, height4/2]) | |
| .strength(0.1)) | |
| // cluster by section | |
| .force('cluster', d3.forceCluster() | |
| .centers(function (d) { return clusters[d.cluster]; }) | |
| .strength(0.5) | |
| .centerInertia(0.1)) | |
| // apply collision with padding | |
| .force('collide', d3.forceCollide(function (d) { return d.radius + padding; }) | |
| .strength(0)) | |
| .on('tick', layoutTick) | |
| .nodes(nodes); | |
| var tooltip = d3.select("#prueba").append("div") | |
| .attr("class", "tooltip"); | |
| var grafico2 = d3.select('#prueba').append('svg') | |
| .attr('width', width4) | |
| .attr('height', height4); | |
| var node = svg.selectAll('circle') | |
| .data(nodes) | |
| .enter() | |
| .append('circle') | |
| .style('fill', function (d) { return color( d.degrade/n); }) | |
| .attr('id', function (d) { return d.nombre + ": " + d.frecuencia; }) | |
| .call(d3.drag() | |
| .on('start', dragstarted) | |
| .on('drag', dragged) | |
| .on('end', dragended) | |
| ) | |
| .on('mouseover', function(d){ | |
| d3.select("#major").text(d.key); | |
| tooltip.transition() | |
| .duration(500) | |
| .style("opacity", 1); | |
| tooltip.html( this.id ) | |
| .style("left", (d3.event.pageX - 25) + "px") | |
| .style("top", (d3.event.pageY - 50) + "px"); | |
| }) | |
| .on('mousemove', function (d) { | |
| tooltip.style("top", (d3.event.pageY - 50) + 'px'); | |
| tooltip.style("left", (d3.event.pageX - 25) + 'px'); | |
| }) | |
| .on('mouseout', function(d){ | |
| d3.select("#major").text("Mouse over"); | |
| tooltip.transition() | |
| .duration(500) | |
| .style("opacity", 0); | |
| }); | |
| svg.append("text") | |
| .attr("class", "title") | |
| .attr("x", (width2/6)+(width2/2)) | |
| .attr("y", (height1 + margin3.top - 20)) | |
| .text("Porcentaje de las entregas según su estado"); | |
| for(var j=0; j<n;j++) { | |
| svg.append("text") | |
| .attr("class", "title") | |
| .attr("x", (width1 + margin1.left)) | |
| .attr("y", (height1 + margin3.top + 10)+(14*j)) | |
| .text(datos[j]["motivo"] + ": " + datos[j]["frequency"]); | |
| } | |
| function dragstarted (d) { | |
| if (!d3.event.active) simulation.alphaTarget(0.3).restart(); | |
| d.fx = d.x; | |
| d.fy = d.y; | |
| } | |
| function dragged (d) { | |
| d.fx = d3.event.x; | |
| d.fy = d3.event.y; | |
| } | |
| function dragended (d) { | |
| if (!d3.event.active) simulation.alphaTarget(0); | |
| d.fx = null; | |
| d.fy = null; | |
| } | |
| // ramp up collision strength to provide smooth transition | |
| var transitionTime = 3000; | |
| var t = d3.timer(function (elapsed) { | |
| var dt = elapsed / transitionTime; | |
| simulation.force('collide').strength(Math.pow(dt, 2) * 0.7); | |
| if (dt >= 1.0) t.stop(); | |
| }); | |
| function layoutTick (e) { | |
| node | |
| .attr('cx', function (d) { return d.x; }) | |
| .attr('cy', function (d) { return d.y; }) | |
| .attr('r', function (d) { return d.radius; }) | |
| .attr('text', function (d) { return d.nombre; }); | |
| } | |
| //Fin Motivos | |
| function svgToPng() { | |
| saveSvgAsPng(d3.select('svg').node(), 'graficas.png'); | |
| } | |
| </script> | |
| </body> |