I can't load a javascript scatter plot in any browser - javascript

Recently, maybe after updating Java, I'm unable to load a scatter plot on Chrome, Firefox or Internet Explorer.
One month ago, everything loaded fine. I don't know what happened. I've updated Java to the last version and enabled ActiveX on Internet options, but nothing works for me.
I'll paste the html code. It loads the point info using a csv file saved in the same folder:
<!DOCTYPE html> <meta charset="utf-8"> <style>
body { font: 12px Arial;}
.axis path, .axis line { fill: none; stroke: grey; stroke-width: 1;
shape-rendering: crispEdges; }
</style> <body>
<script src="http://d3js.org/d3.v4.js"></script> <script>
// Set the dimensions of the canvas / graph var margin = {top: 30, right: 20, bottom: 50, left: 60}, width = 900 - margin.left - margin.right, height = 360 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.timeParse("%a %b %d %H:%M:%S %Z %Y "); // Set the ranges
var y = d3.scaleTime().range([height, 0]); var x = d3.scaleLinear().range([0, width]);
// Define the axes
var xAxis = d3.axisBottom().scale(x) .ticks(5);
var yAxis = d3.axisLeft().scale(y)
.ticks(5);
// Adds the svg canvas 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 + ")"); // Get the data
d3.csv("data.csv", function(error, data) { var max = data.length; console.log(max)
data.forEach(function(d, i) { d.dateParsed = parseDate(d.date); d.close = max - i;
}); // Scale the range of the data
y.domain(d3.extent(data, function(d) { return d.dateParsed; })); x.domain([0, d3.max(data, function(d) { return d.close; })]);
// Add the scatterplot svg.selectAll("dot") .data(data)
.enter().append("circle") .attr("r", 0.5)
.attr("fill","#2980B9")
.attr("cy", function(d) { return y(d.dateParsed); }) .attr("cx", function(d) { return x(d.close); });
svg.append("g") .attr("class", "x axis")
.attr("transform", "translate(0," + height + ")") .call(xAxis);
svg.append("text") .attr("class", "x label") .attr("text-anchor", "middle") .attr("x", width / 2) .attr("y", height + 40) .text("followers");
svg.append("g")
.attr("class", "y axis") .call(yAxis);
svg.append("text") .attr("class", "y label") .attr("text-anchor", "middle") .attr("x", -height / 2 ) .attr("y", -50)
.attr("transform", "rotate(-90)") .text("account creation date");
});
</script> </body>

It looks like main issue is code is not formatted properly.
Many comments get mixed with the code caused the syntax errors.
I try to format the code and try to fix those errors.
As we don't have your data.csv file so we are not able to load that data but code creates the chart now.
You can try to use this code on your side with your data.csv file. It will help you to load the chart properly.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { font: 12px Arial;}
.axis path, .axis line { fill: none; stroke: grey; stroke-width: 1;
shape-rendering: crispEdges; }
</style>
</head>
<body>
<script src="http://d3js.org/d3.v4.js"></script> <script>
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 50, left: 60}, width = 900 - margin.left - margin.right, height = 360 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.timeParse("%a %b %d %H:%M:%S %Z %Y "); // Set the ranges
var y = d3.scaleTime().range([height, 0]); var x = d3.scaleLinear().range([0, width]);
// Define the axes
var xAxis = d3.axisBottom().scale(x) .ticks(5);
var yAxis = d3.axisLeft().scale(y)
.ticks(5);
// Adds the svg canvas
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 + ")"); // Get the data
d3.csv("data.csv", function(error, data) { var max = data.length;
console.log(max);
data.forEach(function(d, i) { d.dateParsed = parseDate(d.date); d.close = max - i;
});
// Scale the range of the data
y.domain(d3.extent(data, function(d) { return d.dateParsed; })); x.domain([0, d3.max(data, function(d) { return d.close; })]);
// Add the scatterplot
svg.selectAll("dot") .data(data)
.enter().append("circle") .attr("r", 0.5)
.attr("fill","#2980B9")
.attr("cy", function(d) { return y(d.dateParsed); }) .attr("cx", function(d) { return x(d.close); });
svg.append("g") .attr("class", "x axis")
.attr("transform", "translate(0," + height + ")") .call(xAxis);
svg.append("text") .attr("class", "x label") .attr("text-anchor", "middle") .attr("x", width / 2) .attr("y", height + 40) .text("followers");
svg.append("g")
.attr("class", "y axis") .call(yAxis);
svg.append("text") .attr("class", "y label") .attr("text-anchor", "middle") .attr("x", -height / 2 ) .attr("y", -50)
.attr("transform", "rotate(-90)") .text("account creation date");
});
</script>
</body>
</html>

Related

Why does this D3 code not produce any output in Jupyter Notebook?

I followed this blog here and here's the code that I'm trying to run on my Jupyter Notebook - essentially a simple scatter plot from the iris dataset.
from IPython.core.display import display, HTML
from string import Template
import pandas as pd
import json, random
HTML('<script src="./d3.min.js"></script>')
filename = 'https://gist.githubusercontent.com/mbostock/3887118/raw/2e68ffbeb23fe4dadd9b0f6bca62e9def6ee9e17/data.tsv'
iris = pd.read_csv(filename,sep="\t")
iris_array_of_dicts = iris.to_dict(orient='records')
css_text = '''
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: #000;
}
'''
js_text_template = Template('''
var margin = {top: 20, right: 20, bottom: 30, left: 40},
// **** width = 960 - margin.left - margin.right, ****
// **** height = 500 - margin.top - margin.bottom; ****
width = 720 - margin.left - margin.right,
height = 375 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.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 svg = d3.select("body").append("svg") ****
var svg = d3.select("#$graphdiv").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", function(error, data) { ****
// **** if (error) throw error; ****
var data = $python_data ;
data.forEach(function(d) {
d.sepalLength = +d.sepalLength;
d.sepalWidth = +d.sepalWidth;
});
x.domain(d3.extent(data, function(d) { return d.sepalWidth; })).nice();
y.domain(d3.extent(data, function(d) { return d.sepalLength; })).nice();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Sepal Width (cm)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Sepal Length (cm)")
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.sepalWidth); })
.attr("cy", function(d) { return y(d.sepalLength); })
.style("fill", function(d) { return color(d.species); });
var legend = svg.selectAll(".legend")
.data(color.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
// **** }); ****
''')
html_template = Template('''
<style> $css_text </style>
<div id="graph-div"></div>
<script> $js_text </script>
''')
js_text = js_text_template.substitute({'python_data': json.dumps(iris_array_of_dicts),
'graphdiv': 'graph-div'})
HTML(html_template.substitute({'css_text': css_text, 'js_text': js_text}))
The code runs without errors but doesn't display any output.
I've also tried to use the display functionality but that still produces no results.
What am I doing wrong? My assumption is that since this is an old blog post, Jupyter has moved past supporting Javascript this way and I have to use cell and line magics now but I'm not sure as I'm new to Javascript.
I have just tried and figured out the problem.
If you look at the console log, the browser do not interpret d3. To solve it add to your code.
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
You will now see your nice plot
Here an exemple of update
In [1]:
from IPython.core.display import display, HTML
from string import Template
import pandas as pd
import json, random
HTML('<script src="./d3.min.js"></script>')
filename = 'https://gist.githubusercontent.com/mbostock/3887118/raw/2e68ffbeb23fe4dadd9b0f6bca62e9def6ee9e17/data.tsv'
iris = pd.read_csv(filename,sep="\t")
iris_array_of_dicts = iris.to_dict(orient='records')
css_text = '''
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: #000;
}
'''
js_text_template = Template('''
var margin = {top: 20, right: 20, bottom: 30, left: 40},
// **** width = 960 - margin.left - margin.right, ****
// **** height = 500 - margin.top - margin.bottom; ****
width = 720 - margin.left - margin.right,
height = 375 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.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 svg = d3.select("body").append("svg") ****
var svg = d3.select("#$graphdiv").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", function(error, data) { ****
// **** if (error) throw error; ****
var data = $python_data ;
data.forEach(function(d) {
d.sepalLength = +d.sepalLength;
d.sepalWidth = +d.sepalWidth;
});
x.domain(d3.extent(data, function(d) { return d.sepalWidth; })).nice();
y.domain(d3.extent(data, function(d) { return d.sepalLength; })).nice();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Sepal Width (cm)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Sepal Length (cm)")
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.sepalWidth); })
.attr("cy", function(d) { return y(d.sepalLength); })
.style("fill", function(d) { return color(d.species); });
var legend = svg.selectAll(".legend")
.data(color.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
// **** }); ****
''')
html_template = Template('''
<style > $css_text </style>
<div id="graph-div"></div>
<script > $js_text </script>
''')
js_text = js_text_template.substitute({'python_data': json.dumps(iris_array_of_dicts),
'graphdiv': 'graph-div'})
my_plot = html_template.substitute({'css_text': css_text, 'js_text': js_text})
d3_download = """ <script src="http://d3js.org/d3.v3.min.js" charset="utf-8" > </script>"""
my_plot = d3_download + my_plot
HTML(my_plot)
Out [1]:

How to get JSON key for d3.js chart

Here is my problem : I an array with JSON object in it ad I would like to get the keys of JSON objects to build a bar chart with it.
Here is my array :
var dataset = [{
"T1": 4.23
},
{
"T2": 45.62
},
{
"T3": 24.78
},
{
"T4": 11.41
},
{
"T5": 5.19
},
{
"T6": 5.15
},
{
"T7": 1.99
},
{
"T8": 0.93
},
{
"T9": 0.61
}
];
And here is my code to draw the chart :
let width = 500;
let heigth = 200;
let barPadding = 1;
let svg = d3.select("#containerChart")
.append("svg")
.attr("width", width)
.attr("height", heigth);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function (d, i) {
return i + (20 + barPadding);
})
.attr("y", function (d) {
return heigth - (**values of JSON object** * 2)
})
.att("width", 20)
.attr("heigth", function (d) {
return (**values of JSON object** * 2)
})
.attr("fill", "teal")
Do you have any idea of how I could do ?
Thanks in advance for your help !!
Here's the codepen and here's the code for testing on your local:
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
.bar{
fill: steelblue;
}
.bar:hover{
fill: brown;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
// set the dimensions of the canvas
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// set the ranges
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
// define the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
// add the SVG element
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 + ")");
// load the data
d3.json("data.json", function(error, data) {
// scale the range of the data
x.domain(data.map(function(d) { return Object.keys(d); }));
y.domain([0, d3.max(data, function(d) { return +d[Object.keys(d)]; })]);
// add axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end");
// Add bar chart
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(Object.keys(d)); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(+d[Object.keys(d)]); })
.attr("height", function(d) { return height - y(+d[Object.keys(d)]); });
});
</script>
</body>
I replaced all references for the y axis with the json keys using Object.keys() and got the values for these keys to put into the x axis. You could also use for... in loop to do the same thing.
To test it locally, you will have to host both files on a local server or else you will get CORS errors. You could include a parsed inline json to avoid CORS altogether.
This one should work :
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function (d, i) {
return i + (20 + barPadding);
})
.attr("y", function (d,i) {
return heigth - d["T" + (i+1)]
})
.attr("width", 20)
.attr("heigth", function (d,i) {
return heigth - d["T" + (i+1)]
})
.attr("fill", "teal")

Aligning two graphs(Pie and Bar) side by side :: d3 js

I am a little new to D3 js.I need to align two graphs (bar and pie) side by side which will be displayed on a dashboard.When I use individual .html files for bar and pie charts,they work perfectly but the charts are getting overlapped when I combine them into a single .html file.
I have tried changing different parameters related to "svg" and corresponding x and y axes but to no avail.
There are two csv files(pie-data.csv,bar-data.csv) from where data will be picked.
Below is my code ::
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.arc text {
font: 10px sans-serif;
text-anchor: middle;
}
.arc path {
stroke: #fff;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var width = 500,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var labelArc = d3.svg.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.ticket_count; });
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.csv("pie-data.csv", type, function(error, data) {
if (error) throw error;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.ticket_meter); });
g.append("text")
.attr("transform", function(d) { return "translate(" + labelArc.centroid(d) + ")"; })
.attr("dy", ".35em")
.text(function(d) { return d.data.ticket_meter; });
});
function type(d) {
d.ticket_count = +d.ticket_count;
return d;
}
////////////////////////////////////////////////
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 150 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
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(10);
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.csv("bar-data.csv", function(error, data) {
data.forEach(function(d) {
d.issue_status = d.issue_status;
d.issue_count = +d.issue_count;
});
x.domain(data.map(function(d) { return d.issue_status; }));
y.domain([0, d3.max(data, function(d) { return d.issue_count; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
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")
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.style("fill", "steelblue")
.attr("x", function(d) { return x(d.issue_status); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.issue_count); })
.attr("height", function(d) { return height - y(d.issue_count); });
});
</script>
</body>
</html>
Please suggest any pointers so that alignment can be done.Thanks in advance.
You are using the same variable twice:
var svg = d3.select("body").append("svg");
(and, besides that one, you are repeating some other variables that should be unique)
Appending the SVGs to the "body" is not the correct way, because when you append an SVG to the body the SVG is put at the end of the page, and you'll not be able to position them side by side.
A solution would be creating one div for each chart, with IDs #chart1 and #chart2 for instance, and then creating two variables:
var svg1 = d3.select("#chart1").append("svg");
And
var svg2 = d3.select("#chart2").append("svg");
Don't forget to change all other variables accordingly.
After the changes, use CSS to align the two divs side by side.

error updating my barchart using d3

I came through this problem just when I though I had d3 undercontrol... I can't find out why my code is crashing when I update my barChart using an empty array of data...
here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Simple tables in D3</title>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<style type="text/css">
.chart rect {
fill: steelblue;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.axis {
font: 10px sans-serif;
}
</style>
</head>
<body>
<svg class="chart">
</svg>
<script>
var scanCounters = JSON.parse("[{\"scan\":\"111\",\"repetition\":3},{\"scan\":\"222\",\"repetition\":2},{\"scan\":\"333\",\"repetition\":4},{\"scan\":\"123\",\"repetition\":2},{\"scan\":\"456\",\"repetition\":1},{\"scan\":\"789\",\"repetition\":1}]");
var scanCounters2 = JSON.parse("[{\"scan\":\"111\",\"repetition\":8},{\"scan\":\"222\",\"repetition\":6},{\"scan\":\"333\",\"repetition\":5},{\"scan\":\"123\",\"repetition\":3}]");
var scanCounters3 = JSON.parse("[]");
var columns = ["scan", "repetition"];
var margin = {top: 20, right: 30, bottom: 30, left: 40};
var width = 960;
var height = 500;
var innerWidth = width - margin.left - margin.right;
var innerHeight = height - margin.top - margin.bottom;
var bcScan = barChart(600, 400, "chart");
bcScan.update(scanCounters);
setTimeout(function(){
bcScan.update(scanCounters2);
}, 1000);
setTimeout(function(){
bcScan.update(scanCounters3);
}, 2000);
function barChart(w, h, node) {
var bC = {};
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = w - margin.left - margin.right,
height = h - 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");
var svg = d3.select("." + node)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")");
svg.append("g")
.attr("class", "y axis")
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -40)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
bC.update = function(data) {
x.domain(data.map(function (d) {
return d[Object.keys(d)[0]];
}));
y.domain([0, d3.max(data, function (d) {
return d[Object.keys(d)[1]];
})]);
svg.select(".x.axis")
.transition()
.duration(300).call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");
svg.select(".y.axis")
.transition()
.duration(300)
.call(yAxis);
var bars = svg.selectAll(".bar").data(data, function (d) {
return d[Object.keys(d)[0]];
});
bars.exit()
.transition()
.duration(300)
.attr("y", y(0))
.attr("height", height - y(0))
.style('fill-opacity', 1e-6)
.remove();
bars.enter()
.append("rect")
.attr("class", "bar")
.attr("y", y(0))
.attr("height", height - y(0));
var trans = bars.transition().duration(300).attr("x", function (d) {
return x(d[Object.keys(d)[0]]);
});
trans.attr("width", x.rangeBand())
.attr("y", function (d) {
return y(d[Object.keys(d)[1]]);
})
.attr("height", function (d) {
return height - y(d[Object.keys(d)[1]]);
});
};
return bC;
}
</script>
</body>
</html>
The problem is when I call bcScan.update(scanCounters3); where scanCounters3 is an empty array.
This is the error message:
Error: Invalid value for attribute height="NaN"
Error: Invalid value for attribute y="NaN"
QUESTON: Could someone help me to understand why it is crashing?
thanks
#EthanJewett, is correct, if you look at your y.domain() on each iteration you get:
[0, 4]
[0, 8]
[0, NaN]
So on your last iteration, your exit transition is doing math on an NaN:
.attr("y", y(0))
.attr("height", height - y(0))
I would just drop those lines altogether and make the exit transition:
bars.exit()
.transition()
.duration(300)
.style('fill-opacity', 1e-6)
.remove();

Aligning the label in d3 line chart

Following is the data file : myStData.csv
xindex,mylabel
40,23
41,13
42,12
43,21
44,40
45,50
Following is my code snippet, and currently, the label is shown at "start" (text-anchor is set to start). It is placed at the start value of my csv file. But, I want the label to be placed at the end value.
I tried replacing the start text anchor to be end, but it didn't work in my case. Any help in this is highly appreciated.
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.10/d3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 13px Helvetica;}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
.legend {
font-size: 16px;
text-anchor: start;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 30, right: 40, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
//var x = d3.time.scale().range([0, width]);
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(14);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
var valueline = d3.svg.line()
.x(function(d) { return x(d.xindex); })
.y(function(d) { return y(d.mylabel); });
var chart1 = d3.select("body")
.append("svg")
.attr("width", width + margin.left + (margin.right * 2))
.attr("height", height + margin.top + (margin.bottom * 2))
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Get the data
d3.csv("myStData.csv", function(error, data) {
data.forEach(function(d) {
d.xindex = +d.xindex;
d.mylabel = +d.mylabel;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.xindex; }));
y.domain([0, d3.max(data, function(d) { return d.mylabel; })]);
chart1.append("path") // Add the valueline path.
.attr("class", "line")
.attr("d", valueline(data));
chart1.append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart1.append("g") // Add the Y Axis
.attr("class", "y axis")
.call(yAxis);
chart1.append("text")
.attr("transform", "translate(" + (width+3) + "," + y(data[0].mylabel) + ")")
.attr("dy", ".35em")
.attr("class","legend")
.attr("text-anchor", "start")
.style("fill", "red")
.text("MyLabel");
// Add the text label for the Y axis
chart1.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Y-Axis Label");
// Add the text label for the x axis
chart1.append("text")
.attr("transform", "translate(" + (width / 2) + " ," + (height + (margin.bottom * 1.5)) + ")")
.style("text-anchor", "middle")
.text("X-Axis Label");
});
Finally, I got the solution. Simple, as it was!
So, to re-iterate, what I wanted to achieve was to move the location of the 'MyLabel' label to the position where the line ends. Here's how it needs to be done:
chart1.append("text")
.attr("transform", "translate(" + (width+3) + "," + y(data[0].mylabel) + ")")
.attr("dy", ".35em")
.attr("class","legend")
.attr("text-anchor", "start")
.style("fill", "red")
.text("MyLabel");
This states that the y-axis position of the label needs to be at data[0] element's y value. We simply need to replace, data[0] by data[data.length-1] so that the y- value of the last data element is taken into consideration for positioning the label.
chart1.append("text")
.attr("transform", "translate(" + (width+3) + "," + y(data[data.length-1].mylabel) + ")")
.attr("dy", ".35em")
.attr("class","legend")
.attr("text-anchor", "start")
.style("fill", "red")
.text("MyLabel");

Categories

Resources