简体   繁体   中英

D3 line and chart graphs on the same page breaking

I am trying to render 2 graphs on the same page: chart graph and a linear graph

in html i have two divs which bind to the 2 different graphs respectively like so: <div id="svg-container"> <div id="svg-container-avg"> The first graph that i import in html is this linear 'average' graph that just doesn't display the path or the x axis. It works fine if i delete the chart graph which is imported straight after. I would automatically assume that there are some sort of dependencies between the two graphs, but i cannot find anything...

my first import, linear graph: scns-avg.js file contains this

 // Set the dimensions of the canvas / graph var margin = { top: 30, right: 20, bottom: 70, left: 50 }, width = 800 - margin.left - margin.right, height = 350 - margin.top - margin.bottom; var x = d3.scale.linear().range([0, width]); var y = d3.scale.linear().range([height, 0]); var xAxis = d3.svg.axis().scale(x) .orient("bottom").ticks(5); var yAxis = d3.svg.axis().scale(y) .orient("left").ticks(5); var valueline = d3.svg.line() .x(function(d) { return x(d.scnsID); }) .y(function(d) { return y(d.average); }); var svg2 = d3.select("#svg-container-avg") .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 + ")"); // Get the data d3.json("scns-avg-data-retrieval.php", function(error, data) { data.forEach(function(d) { d.scnsID = d.scnsID; d.average = +d.average; }); // Scale the range of the data x.domain(d3.extent(data, function(d) { return d.scnsID; })); y.domain([0, d3.max(data, function(d) { return d.average; })]); svg2.append("path") // Add the valueline path. .style("stroke", "rgba(13, 183, 196, 0.9)") .attr("d", valueline(data)); svg2.selectAll("dot") .data(data) .enter().append("circle") .attr("class", "dot") .attr("r", 3.5) .attr("cx", function(d) { return x(d.scnsID); }) .attr("cy", function(d) { return y(d.average); }) svg2.append("g") // Add the X Axis .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg2.append("g") // Add the Y Axis .attr("class", "y axis") .call(yAxis); }); 
 My Data structor in JSON: [{"date":"11-Mar-16","average":"3.18","scnsID":"2"},{"date":"12-Mar-16","average":"3.09","scnsID":"3"},{"date":"15-Mar-16","average":"3.16","scnsID":"4"},{"date":"17-Mar-16","average":"3.20","scnsID":"5"}] 

When trying to run the html page with both graphs being imported the scns-avg.js throws up in the console Error: Invalid value for attribute d="M43,2.8124999999999902LNaN,15.46875000000002LNaN,5.6249999999999805L471,0" which points to valueline(data) in this part of the code svg2.append("path") .style("stroke", "rgba(13, 183, 196, 0.9)") .attr("d", valueline(data)); That is dependent on this piece of code, so the problem must be lying here, but for 6 hours now i can't find the solution to this.. var valueline = d3.svg.line() .x(function(d) { return x(d.scnsID); }) .y(function(d) { return y(d.average); });

My chart graph that gets imported next and if disabled the linear graph renders properly is as follows below:

 var margin = {top: 20, right: 20, bottom: 30, left: 40}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; 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") .ticks(5); var tip = d3.tip() .attr('class', 'd3-tip') .offset([-10, 0]) .html(function(d) { return "<strong>Frequency:</strong> <span style='color:rgba(13, 183, 196, 0.9)'>" + d.average + "</span>"; }); var svg = d3.select("#svg-container").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 + ")"); svg.call(tip); // Get the data d3.json("scns-data-retrieval.php", function(error, data) { if (error) throw error; data.forEach(function(d) { d.question = d.question; d.average = +d.average; }); x.domain(data.map(function(d) { return d.question; })); y.domain([0, 5]); legendSpace = width/5; 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", 0 - margin.left) .attr("x", 0 - (height / 3)) .attr("dy", ".71em") .style("text-anchor", "end") .text("Level of need for help:"); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.question); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.average); }) .attr("height", function(d) { return height - y(d.average); }) .on('mouseover', tip.show) .on('mouseout', tip.hide); }); function type(d) { d.average = +d.average; return d; }; 
 data structure in JSON: [{"question":1,"average":3.3333333333333},{"question":2,"average":2.5},{"question":3,"average":4},{"question":4,"average":2.75},{"question":5,"average":2.75},{"question":6,"average":2.75},{"question":7,"average":3},{"question":8,"average":3},{"question":9,"average":2.75},{"question":10,"average":3.25},{"question":11,"average":3.25},{"question":12,"average":3.5},{"question":13,"average":3},{"question":14,"average":3.25},{"question":15,"average":3.5},{"question":16,"average":3.5},{"question":17,"average":3.25},{"question":18,"average":3.75},{"question":19,"average":3.5},{"question":20,"average":3},{"question":21,"average":3},{"question":22,"average":3.5},{"question":23,"average":3.25},{"question":24,"average":3.75},{"question":25,"average":3.75},{"question":26,"average":3.75},{"question":27,"average":3.5},{"question":28,"average":2.75},{"question":29,"average":2.25},{"question":30,"average":3.5},{"question":31,"average":3},{"question":32,"average":3}] 

I can't do this anymore and it's driving me crazy so i am now turning to the power of stackoverflow!

After some mad research and trial and error i have fixed this problem.

When you are trying to render more than 1 graph, if they are of different type and not lets say - multiple linear graphs, but something like a linear graph with a bar chart the variable scope is getting mixed up and it's not restricted to the javascript file once it's imported into html.

To fix this problem every graph js file has to wrapped in (function(){ All your graph code goes here })();

This restricts the variable scope to just the function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM