Scatterplot keeps copying itself - javascript

I'm trying to make a scatterplot that appears below an interactive worldmap with the help of D3. The scatterplot contains data from the country that the user clicked on in the worldmap. The problem is that when the user clicks on another country, the scatterplot of the previous country should disappear. This is not the case unfortunately, the second scatterplot just appears under the first scatterplot. Does anyone know how I can fix this? Any help would be greatly appreciated.
A part of the code I use for the scatterplot:
function ScatterCorruption(dataset, title){
var xValue = function(d) { return d.GDP;}
var yValue = function(d) { return d.Variable;}
// determine parameters
var margin = {top: 20, right: 20, bottom: 200, left: 70},
width = 600 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// formatters for axis and labels
var currencyFormat = d3.format("0.2f");
var decimalFormat = d3.format("0.2f");
// determine x scale
var x = d3.scale.linear()
.range([0, width]);
// determine y scale
var y = d3.scale.linear()
.range([height, 0]);
// determine x-axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
// determine y-axis
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
// make svg
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 + ")");
// add the tooltip area to the webpage
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
console.log(dataset)
// load in data
d3.tsv(dataset, function(error, data) {
if (error) throw error;
// convert data
data.forEach(function(d) {
d.GDP = +d.GDP;
d.Variable = +d.Variable;
});

You'll need to call this before rendering a new scatterplot: d3.selectAll("svg > *").remove(); so that your svg is clear again. Alternatively you can also do d3.select("svg").remove(); and then recreate the svg.

Related

D3 JS chart is cut off after adding labels for X and Y axis

I am making a scatterplot in D3 with the code below and the textlabels of the right circles are being cut off, after putting textlabels on the X and Y axis.
Here is a working jsFiddle:
https://jsfiddle.net/chemok78/1vcat0s8/4/
Adding the X and Y axis labels seems to move the whole chart to the right and up, making it move a bit out of the containing div. Anyone can help me how to fix this?
var url = "https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json";
d3.json(url, function(json) {
var data = json;
var margin = {
top: 40,
right: 100,
bottom: 80,
left: 80
};
var w = 1000 - margin.left - margin.right;
var h = 800 - margin.top - margin.bottom;
var svg = d3.select("#chart")
.append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var maxRank = d3.max(data, function(d) {
return d.Place;
});
var minSeconds = d3.min(data, function(d) {
return d.Seconds;
});
var maxSeconds = d3.max(data, function(d) {
return d.Seconds;
});
var formatTime = d3.time.format("%M:%S");
var formatSeconds = formatMinutes = function(d) {
return formatTime(new Date(2016, 0, 0, 0, 1, d));
};
var xScale = d3.scale.linear()
.domain([maxSeconds + 5, minSeconds])
.range([0, w]);
var yScale = d3.scale.linear()
.domain([0, maxRank + 2])
.range([0, h]);
This has nothing to do with "moving the chart". Here is the problem.
When you do this:
var labels = svg.selectAll("text")
You're selecting text elements that already exist in your SVG. Because of that, your "enter" selection will have less elements compared to what it should contain.
The solution is simple: select something that doesn't exist:
var labels = svg.selectAll("foo")
Or, alternatively, move the blocks that append the axes' labels to the bottom of the code.
Here is your updated fiddle: https://jsfiddle.net/mp7LxsL4/

How to design graph in given data in d3.js

I have unable draw for the line graph in the d3.js,i wrote some code but enable show the graph,how to draw a line for the given data.I have a problem for the how to parse the data for the given data and draw a lines ffor the given data of code.
var data=[{"key":[2000,1,1,12],"value":1000},{"key":[2000,2,1,12],"value":38965},
[{"key":[2000,7,1,24],"value":289},{"key":[2000,8,1,24],"value":389}
]
var parseDate = d3.time.format("%Y.%m.%d.%H").parse;
var map=data.map(function (d){
return {
key:parseDate((d.key[0])+"."+(d.key[1]+1)+"."+(d.key[2])+"."+(d.key[3]+1)),value:+d.value
}
});
console.log(map);
var margin = {top: 15, right: 20, bottom: 70, left: 85},
width = 440,height = 450;
var x = d3.time.scale().range([0, width]);
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")
var line = d3.svg.line()
.x(function(d) { return x(d.key); })
.y(function(d) { return y(d.value); })
.interpolate("cardinal")
var svg = d3.select("body").select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
x.domain(d3.extent(d3.map(function (d){return d.key;})));
y.domain(d3.extent(d3.map(function (d){return d.key;})));
svg.append("g")
.attr("class", "x axis x-axis")
.attr("transform", "translate(0," + height + ")").attr("fill","steelblue")
.call(xAxis);
svg.append("g").attr("class", "y axis y-axis").attr("fill","steelblue").call(yAxis)
svg.append("path").datum(map).attr("class", "line").attr("d", line);
There seem to be a number of problems with the above code including an extra [ in the data, which should be:
var data=[
{"key":[2000,1,1,12],"value":1000},
{"key":[2000,2,1,12],"value":38965},
{"key":[2000,7,1,24],"value":289},
{"key":[2000,8,1,24],"value":389}
]
Other than that, the way you parse the data seems fine, but there are some issues with the way you set up the chart.
I've created a new line chart using your data here: http://jsfiddle.net/henbox/9etp0xap/, based on this example: http://bl.ocks.org/mbostock/3883245
You'll probably find it easier to modify that jsfiddle rather than to debug the specific issues.

Zoom only zooms my axis and not the objects on my graph

I have a current zoom function I just learned to use in D3. However when I use it, it only moves my and zooms the axis of the graph not the objects on it.
I'm very knew to D3 and would like some help please.
My source code of the javascript is posted below:
//Setting generic width and height values for our SVG.
var margin = {top: 60, right: 0, bottom: 60, left: 40},
width = 1024 - 70 - margin.left - margin.right,
height = 668 - margin.top - margin.bottom;
//Other variable declarations.
//Creating scales used to scale everything to the size of the SVG.
var xScale = d3.scale.linear()
.domain([0, 1024])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([1, 768])
.range([height, 0]);
//Creates an xAxis variable that can be used in our SVG.
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
//Zoom command ...
var zoom = d3.behavior.zoom()
.x(xScale)
.y(yScale)
.scaleExtent([1, 10])
.on("zoom", zoomed);
// The mark '#' indicates an ID. IF '#' isn't included argument expected is a tag such as "svg" or "p" etc..
var SVG = d3.select("#mainSVG")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);
//Create background. The mouse must be over an object on the graph for the zoom to work. The rectangle will cover the entire graph.
var rect = SVG.append("rect")
.attr("width", width)
.attr("height", height);
//This selects 4 circles (non-existent, there requires data-binding) and appends them all below enter.
//The amount of numbers in data is the amount of circles to be appended in the enter() section.
var circle = SVG
.selectAll("circle")
.data([40,100,400,1900])
.enter()
.append("circle")
.attr("cx",function(d){return xScale(d)})
.attr("cy",function(d){return xScale(d)})
.attr("r",20);
//This appends a circles to our SVG.
var circle = SVG
.append("circle")
.attr("cx",function(d){ return xScale(d)})
.attr("cy",300)
.attr("r",20);
//Showing the axis that we created earlier in the script for both X and Y.
var xAxisGroup = SVG.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var yAxisGroup = SVG.append("g")
.attr("class", "y axis")
.call(yAxis);
function zoomed() {
SVG.select(".x.axis").call(xAxis);
SVG.select(".y.axis").call(yAxis);
}
You also need to redraw all the elements with the changed axes on zoom -- D3 won't do this for you automatically:
function zoomed() {
SVG.select(".x.axis").call(xAxis);
SVG.select(".y.axis").call(yAxis);
SVG.selectAll("circle")
.attr("cx",function(d){return xScale(d)})
.attr("cy",function(d){return xScale(d)});
}

customized logarithmic d3 chart

I am trying to create a d3 chart with logarithmic scale(1,10,100..). I used their functions and call but not much help.
var x = d3.scale.log()
.domain([1,10])
.range([0, width]);
var y = d3.scale.log()
.domain([1,10])
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.x(function(d) { return x(d[xAxxis]); })
.y(function(d) { return y(d[yAxxis]); });
var svg = d3.select("#"+this.divid).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 + ")");
x.domain(d3.extent(totalArray, function(d) { return d[xAxxis]; })).nice();
y.domain(d3.extent(totalArray, function(d) { return d[yAxxis]; })).nice();
Is there any way i can create the axis with 1e+0,10e+0,100e+0 rather than 1e+0,2e+0,3e+0
You can control which labels the axis renders using either the tick() or tickValues() method, depending on how you want to go about it. See the d3's API documentation for more details. Also, note that a log scale's tick() method takes no arguments, so you'll likely have to use tickValues() though the other method might come in handy for formatting.

Date-axis for d3.js

I'm playing again with d3.js the javascript library. I am able to create a chart with 2 numeric axes but now I want to have one numeric axis and one axis with a date. Unfortunately I'm not able to do this.
First of all, thats the code that is not running:
d3.json('builds.json',
function(data){
var format = d3.time.format("%Y-%m-%d");
data.forEach(function(d) {
d.finished_at = format.parse(d.finished_at);
});
var margin = {top: 40, right: 40, bottom: 40, left: 40},
width = 960,
height = 500;
var x = d3.time.scale()
.domain(d3.extent(data, function(d) { return d.finished_at; }))
.range([0, width - margin.right - margin.left]);
var y = d3.scale.linear()
.domain(d3.extent(data, function(d) { return d.result; }))
.range([height - margin.top - margin.bottom, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cx", function(d) { return x(d.finished_at); })
.attr("cy", function(d) { return y(d.result); })
.attr("r", 6);
svg.append("g") // Render the axis by calling a <g> selection.
.attr("transform", "translate(0," + y.range()[0] + ")") //setzt x-achse an null punkt von y-achse
.call(xAxis);
svg.append("g")
.call(yAxis);
});
The variable finished_at looks like this: "finished_at":"2011-11-20" and I tried to parse it.
But the output is the following:
Can anybody please help me?
The problem likely lies with your data. You will need to confirm that all of the finished_at values in your JSON are in the correct format.
Your code appears to work perfectly well with a small working JSON dataset: http://bl.ocks.org/4162693

Categories