I'm using on d3.js, and it's working fine.But i'm not figuring out to insert zoom. I'm using a snippet to inser the zoom inside the chart.
this is my code:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: #35353a;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var margin = {top: 40, right: 50, bottom: 60, left: 70},
width = 1060 - margin.left - margin.right,
height = 700 - 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")
.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/test.tsv", function(error, data) {
if (error) throw error;
data.forEach(function(d) {
d.y = +d.y;
d.x = +d.x;
});
x.domain(d3.extent(data, function(d) { return d.x; })).nice();
y.domain(d3.extent(data, function(d) { return d.y; })).nice();
svg.append("rect")
.style('fill', 'transparent')
.attr("width", width)
.attr("height", height);
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("1° Principal Component");
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("2° Principal Component")
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.style("fill", function(d) { return color(d.cluster); });
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; });
});
</script>
if I insert the code to zoom, i'm not able to see the graph again:
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);
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.right + ")")
.call(zoom);-> add zoom to svg
function zoomed() {
container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
what's wrong?
little snippet of tsv:
x y cluster
-1.0403321821456555 -0.9975352942962847 1 Cluster
-1.0404728255519613 -1.0021499065423058 1 Cluster
-1.0405312135780753 -1.0036348433263207 1 Cluster
-1.0405417259454817 -0.9883123582794969 1 Cluster
-1.0406344016908704 -0.9988259809896288 1 Cluster
-1.0406850822323188 -1.004030268612692 1 Cluster
-1.0406958447337742 -1.0065636473623911 1 Cluster
-1.0408667295862442 -1.0046081788513885 1 Cluster
-1.0408845367165218 -0.995137367062602 1 Cluster
-1.040932294864444 -0.991519347648691 1 Cluster
-1.040976952803462 -0.9833995692226501 1 Cluster
-1.0409896369345166 -0.9951495809699621 1 Cluster
-1.0410051379794218 -0.99448305469843 1 Cluster
-1.0410265061033306 -0.9951333768928067 1 Cluster
-1.0410330574179099 -0.9949308462686461 1 Cluster
-1.0410357249485886 -1.0053243527321372 1 Cluster
-1.0410491702402065 -1.006726904241483 1 Cluster
-1.041049812593761 -0.9865506278675225 1 Cluster
-1.0410667719605575 -0.9911033214658317 1 Cluster
-1.0411116340142055 -0.9735253204825465 1 Cluster
thanks in advance.
I am playing blind here as I don't have a running code:
function zoomed() {
container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
This should have been:
function zoomed() {
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
Explanation: I see the code does not have a container; the translate should be on the g group appended to svg.
Related
I would like to add a tooltip to the line chart, where each data point displays a text box upon hover, as follows:
-----------------|
x-coordinate: ## |
y-coordinate: ## |
-----------------|
The working snippet for the working graph is posted below. But I will comment out the tooltip block to plot the chart.
Thanks.
var margin = {top: 50, right: 50, bottom: 50, left: 50}
, width = window.innerWidth - margin.left - margin.right
, height = window.innerHeight - margin.top - margin.bottom;
//labels
var labels = ['Mon','Tue','Thur','Frid'];
var yvals = [12,11,0,18];
// X scale
var xScale = d3.scalePoint()
.domain(labels) // input
.range([0, width-1]); // output
// Y scale
var yScale = d3.scaleLinear()
.domain([0, 20])
.range([height,0]);
var line = d3.line()
.x(function(d, i) { return xScale(labels[i]); })
.y(function(d) { return yScale(d.y); })
.curve(d3.curveMonotoneX)
var dataset = d3.range(yvals.length).map(function(d,i) { return {"y": yvals[i]} })
//Tooltip
//var tip = d3.select('body')
//.append('div')
//.attr('class', 'tip')
//.html('number:'+ function(d,i) return {data[data.i]})
// .style('border', '1px solid steelblue')
// .style('padding', '5px')
//.style('position', 'absolute')
// .style('display', 'none')
//.on('mouseover', function(d, i) {
// tip.transition().duration(0);
// })
// .on('mouseout', function(d, i) {
// tip.style('display', 'none');
// });
// SVGs
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 + ")");
svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "white");
svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// x axis call
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
//.call(d3.axisBottom(xScale));
.call(d3.axisBottom(xScale));
// y axis call
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(yScale));
svg.append("path")
.datum(dataset)
.attr("class", "line")
.attr("d", line);
// 12. Appends a circle for each datapoint
svg.selectAll(".dot")
.data(dataset)
.enter().append("circle") // Uses the enter().append() method
.attr("class", "dot") // Assign a class for styling
.attr("cx", function(d, i) { return xScale(labels[i]) })
.attr("cy", function(d,i) { return yScale(yvals[i]) })
.attr("r", 3);
//.on('mouseover', function(d, i) {
// tip.transition().duration(0);
// })
svg.append("text")
.attr("class", "title")
.attr("x", width/2)
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.text("Testing");
.line {
fill: none;
stroke: orange;
stroke-width: 1;
}
.dot {
fill: brown;
stroke: #fff;
}
<!DOCTYPE html>
<meta charset="utf-8">
<style type="text/css">
</style>
<body>
</body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
</script>
I have just made a few changes to the mousemove event.
var margin = {
top: 50,
right: 50,
bottom: 50,
left: 50
},
width = window.innerWidth - margin.left - margin.right,
height = window.innerHeight - margin.top - margin.bottom;
//labels
var labels = ['Mon', 'Tue', 'Thur', 'Frid'];
var yvals = [12, 11, 0, 18];
// X scale
var xScale = d3.scalePoint()
.domain(labels) // input
.range([0, width - 1]); // output
// Y scale
var yScale = d3.scaleLinear()
.domain([0, 20])
.range([height, 0]);
var line = d3.line()
.x(function(d, i) {
return xScale(labels[i]);
})
.y(function(d) {
return yScale(d.y);
})
.curve(d3.curveMonotoneX)
var dataset = d3.range(yvals.length).map(function(d, i) {
return {
"y": yvals[i]
}
})
var tip = d3.select('body').append("div")
.attr("class", "tip");
// SVGs
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 + ")");
svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "white");
svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// x axis call
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
//.call(d3.axisBottom(xScale));
.call(d3.axisBottom(xScale));
// y axis call
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(yScale));
svg.append("path")
.datum(dataset)
.attr("class", "line")
.attr("d", line);
// 12. Appends a circle for each datapoint
svg.selectAll(".dot")
.data(dataset)
.enter().append("circle") // Uses the enter().append() method
.attr("class", "dot") // Assign a class for styling
.attr("cx", function(d, i) {
return xScale(labels[i])
})
.attr("cy", function(d, i) {
return yScale(yvals[i])
})
.attr("r", 3)
.on("mouseover", function() {
tip.style("display", null);
})
.on("mouseout", function() {
tip.style("display", "none");
})
.on("mousemove", function(d) {
return tip
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + 10 + "px")
.style("visibility", "visible")
.html(function() {
return '<div style="border:1px solid #ccc;">' +
'<p style="font-weight:bold;">' + d.y + '</p>' +
'</div>';
})
})
svg.append("text")
.attr("class", "title")
.attr("x", width / 2)
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.text("Testing");
.line {
fill: none;
stroke: orange;
stroke-width: 1;
}
.dot {
fill: brown;
stroke: #fff;
}
.tip {
position: absolute;
border: 1px solid steelblue;
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script>
Here is the working jsFiddle
Hope it helps :)
Here is the template for my Django where I am visualizing training using D3:
.line {
fill: none;
stroke: gray;
stroke-width: 2px;
}
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var real = {{values.real0|safe}}, pred = {{values.got0|safe}};
var margin = {top: 20, right: 20, bottom: 110, left: 50},
margin2 = {top: 430, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
height2 = 500 - margin2.top - margin2.bottom;
var x = d3.scaleLinear().range([0, width]).domain([0, Object.keys(real).length]),
x2 = d3.scaleLinear().range([0, width]).domain([0, Object.keys(real).length]),
y = d3.scaleLinear().range([height, 0]).domain([0, 1]),
y2 = d3.scaleLinear().range([height2, 0]).domain([0, 1]);
var xAxis = d3.axisBottom(x),
xAxis2 = d3.axisBottom(x2),
yAxis = d3.axisLeft(y);
var brush = d3.brushX()
.extent([[0, 0], [width, height2]])
.on("brush", brushed);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var formain = d3.line()
.x(function(d,i) { return x(i); })
.y(function(d) { return y(d); });
var forbrush = d3.line()
.x(function(d,i) { return x2(i); })
.y(function(d) { return y2(d); });
var focus = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("class", "context")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
// Real starts
var color = d3.scaleLinear()
.domain([0, 0.5, 1])
.range(["red", "dodgerblue", "lime"]);
// x.domain(d3.extent(data, function(d) { return d.date; }));
// y.domain([0, d3.max(data, function(d) { return d.price; })+200]);
// x2.domain(x.domain());
// y2.domain(y.domain());
// append scatter plot to main chart area
var dots = focus.append("g");
dots.attr("clip-path", "url(#clip)");
dots.selectAll("dot")
.data(real)
.enter().append("circle")
.attr('class', 'dot')
.attr("r",5)
.style("opacity", .5)
.attr("cx", function(d,i) { return x(i); })
.attr("cy", function(d) { return y(d); })
.attr("fill",(function (d) { return color(d) }));
focus.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
focus.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text(Object.keys({{values|safe}}));
// console.log(Object.keys({{values|safe}}));
svg.append("text")
.attr("transform",
"translate(" + ((width + margin.right + margin.left)/2) + " ," +
(height + margin.top + margin.bottom) + ")")
.style("text-anchor", "middle")
.text("index");
// append scatter plot to brush chart area
var dots = context.append("g");
dots.attr("clip-path", "url(#clip)");
dots.selectAll("dot")
.data(real)
.enter().append("circle")
.attr('class', 'dotContext')
.attr("r",3)
.style("opacity", .5)
.attr("cx", function(d,i) { return x2(i); })
.attr("cy", function(d) { return y2(d); })
.attr("fill",(function (d) { return color(d) }));
context.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
context.append("g")
.attr("class", "brush")
.call(brush)
.call(brush.move, x.range());
focus.append("path")
.data([real])
.attr("class", "line")
.attr("d", formain);
context.append("path")
.data([real])
.attr("class", "line")
.attr("d", forbrush);
//create brush function redraw scatterplot with selection
function brushed() {
var selection = d3.event.selection;
x.domain(selection.map(x2.invert, x2));
focus.selectAll(".dot")
.attr("cx", function(d,i) { return x(i); })
.attr("cy", function(d) { return y(d); });
context.selectAll(".line")
.attr("cx", function(d,i) { return x(i); })
.attr("cy", function(d) { return y(d); });
focus.select(".axis--x").call(xAxis);
context.select(".axis--x").call(xAxis2);
}
</script>
The output I received is something like the following:
What I want is the the magnifier focus should display the respective contents of the line and the dots. Plus I want to have the line in the background and dots on the foreground.
Please help me modify the sample for my use. There is some attribute I guess I am missing.
The sample csv need is : Sample Csv
Try to change the few thing and it will work. see below:
var focus = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("class", "context")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
focus.append("path")
.data([real])
.attr("class", "line")
.attr("d", formain);
context.append("path")
.data([real])
.attr("class", "line")
.attr("d", forbrush);
Place it just as mentioned.
Change the brushed() function like the following:
function brushed() {
var selection = d3.event.selection;
x.domain(selection.map(x2.invert, x2));
focus.selectAll(".dot")
.attr("cx", function(d,i) { return x(i); })
.attr("cy", function(d) { return y(d); });
focus.selectAll(".line")
.attr("d",formain)
}
See the output of mine. It worked.:
Hope this will help you.
Hi I'm trying to get the mouseover function work for my line chart so I can hover over the line chart and see the values of each point. I tried using the mouse function but it didn't work. How can I fix/do this? I also included a picture of the line chart
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Unemployment by Ward Bar Chart</title>
<style type="text/css">
.axis text{
font-family: Arial;
font-size: 13px;
color: #333333;
text-anchor: end;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
.textlabel{
font-family: Arial;
font-size:13px;
color: #333333;
text-anchor: middle;
}
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 20, right: 0, bottom: 60, left: 60},
width = 475;
height = 350;
padding = 100;
// Adds the svg canvas
var svg = d3.select("body")
.append("svg:svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("viewBox", "0 0 " + width + " " + height);
// Parse the date / time
var parseDate = d3.time.format("%m/%d/%y").parse;
var formatTax = d3.format(",.2f");
// Set the ranges
var x = d3.time.scale()
.range([0, width - margin.right - margin.left], .1)
.nice();
var y = d3.scale.linear()
.range([height - margin.top - margin.bottom, 20])
.nice();
// Define the axes
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(function(d) {return "$" + d + "B"});
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.Date); })
.y(function(d) { return y(d["Tax Collections"]); });
// Get the data
d3.csv("Yearly Tax Collections.csv", function(error, data) {
data.forEach(function(d) {
d.Date = parseDate(d.Date);
d["Tax Collections"] = formatTax(+d["Tax Collections"]/1000000000);
});
var g = svg.selectAll("g").data(data).enter().append("svg:g")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.Date; }));
y.domain([0, d3.max(data, function(d) { return Math.ceil (d["Tax Collections"]); })
]);
// Add the valueline path and mouseover
svg.append("path")
.attr("class", "line")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("d", valueline(data))
.attr("id", "myPath")
.on("mousemove", mMove)
.append("title");
function mMove(){
var m = d3.mouse(this);
d3.select("#myPath")
.select("title")
.filter(function(d, i)
.attr({
'x':function(d,i) {
return x(d.Date);
},
'y':function(d,i) {
return y(d["Tax Collections"]);
}
})
.text(function(d,i){
return "$" + d["Tax Collections"] + "B";
})
}
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + (height - margin.bottom) + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(yAxis);
// Y-axis labels
svg.append("text")
.attr("text-anchor", "middle")
.style("font-size", "13px")
.style("color", "#333333")
.attr("transform", "translate ("+ (padding/4) + "," +(height/2)+") rotate(-90)")
.text("Tax Revenue")
.style("font-family", "Arial");
// X-axis labels
svg.append("text")
.attr("text-anchor", "middle")
.style("font-size", "13px")
.style("color", "#333333")
.attr("transform", "translate("+ (width/2) + "," +(height-(padding/4)) + ")")
.text("Fiscal Year")
.style("font-family", "Arial");
//source
svg.append("text")
.attr("text-anchor", "middle")
.style("font-size", "13px")
.style("color", "#333333")
.attr("transform", "translate("+ (width/4.5) + "," +(height/1) + ")")
.text("Source: DC OCFO")
.style("font-family", "Arial")
//title for the chart
svg.append("text")
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("color", "#333333")
.attr("transform", "translate("+ (width/3) + "," +(height/30) + ")")
.text("DC Total Tax Revenues by Fiscal Year")
.style("font-family", "Arial");
svg.append("text")
.attr("text-anchor", "left")
.style("font-size", "13px")
.style("color", "#333333")
.attr("transform", "translate("+ (width/20) + "," +(height/12) + ")")
.text("2000 to 2015")
.style("font-family", "Arial")
//line labels
svg.append('g')
.classed('labels-group', true)
.selectAll('text')
.data(data)
.enter()
.append('text')
.filter(function(d, i) { return i === 0||i === (data.length - 1) })
.classed('label',true)
.classed('label',true)
.attr({
'x':function(d,i) {
return x(d.Date);
},
'y':function(d,i) {
return y(d["Tax Collections"]);
}
})
.text(function(d,i){
return "$" + d["Tax Collections"] + "B";
})
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
});
</script>
</body>
Thank you in avance!
Hi I'm trying to get the mouseover function work for my line chart so I can hover over the line chart and see the values of each point. I tried using the mouse function but it didn't work. How can I do this? I also included a picture of the line chart
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Unemployment by Ward Bar Chart</title>
<style type="text/css">
.axis text{
font-family: Arial;
font-size: 13px;
color: #333333;
text-anchor: end;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
.textlabel{
font-family: Arial;
font-size:13px;
color: #333333;
text-anchor: middle;
}
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 20, right: 0, bottom: 60, left: 60},
width = 475;
height = 350;
padding = 100;
// Adds the svg canvas
var svg = d3.select("body")
.append("svg:svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("viewBox", "0 0 " + width + " " + height);
// Parse the date / time
var parseDate = d3.time.format("%m/%d/%y").parse;
var formatTax = d3.format(",.2f");
// Set the ranges
var x = d3.time.scale()
.range([0, width - margin.right - margin.left], .1)
.nice();
var y = d3.scale.linear()
.range([height - margin.top - margin.bottom, 20])
.nice();
// Define the axes
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(function(d) {return "$" + d + "B"});
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.Date); })
.y(function(d) { return y(d["Tax Collections"]); });
// Get the data
d3.csv("Yearly Tax Collections.csv", function(error, data) {
data.forEach(function(d) {
d.Date = parseDate(d.Date);
d["Tax Collections"] = formatTax(+d["Tax Collections"]/1000000000);
});
var g = svg.selectAll("g").data(data).enter().append("svg:g")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.Date; }));
y.domain([0, d3.max(data, function(d) { return Math.ceil (d["Tax Collections"]); })
]);
// Add the valueline path and mouseover
svg.append("path")
.attr("class", "line")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("d", valueline(data))
.append("title");
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + (height - margin.bottom) + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(yAxis);
// Y-axis labels
svg.append("text")
.attr("text-anchor", "middle")
.style("font-size", "13px")
.style("color", "#333333")
.attr("transform", "translate ("+ (padding/4) + "," +(height/2)+") rotate(-90)")
.text("Tax Revenue")
.style("font-family", "Arial");
// X-axis labels
svg.append("text")
.attr("text-anchor", "middle")
.style("font-size", "13px")
.style("color", "#333333")
. attr("transform", "translate("+ (width/2) + "," +(height-(padding/4)) + ")")
.text("Fiscal Year")
.style("font-family", "Arial");
//source
svg.append("text")
.attr("text-anchor", "middle")
.style("font-size", "13px")
.style("color", "#333333")
.attr("transform", "translate("+ (width/4.5) + "," +(height/1) + ")")
.text("Source: DC OCFO")
.style("font-family", "Arial")
//title for the chart
svg.append("text")
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("color", "#333333")
.attr("transform", "translate("+ (width/3) + "," +(height/30) + ")")
.text("DC Total Tax Revenues by Fiscal Year")
.style("font-family", "Arial");
svg.append("text")
.attr("text-anchor", "left")
.style("font-size", "13px")
.style("color", "#333333")
.attr("transform", "translate("+ (width/20) + "," +(height/12) + ")")
.text("2000 to 2015")
.style("font-family", "Arial")
//line labels
svg.append('g')
.classed('labels-group', true)
.selectAll('text')
.data(data)
.enter()
.append('text')
.filter(function(d, i) { return i === 0||i === (data.length - 1) })
.classed('label',true)
.classed('label',true)
.attr({
'x':function(d,i) {
return x(d.Date);
},
'y':function(d,i) {
return y(d["Tax Collections"]);
}
})
.text(function(d,i){
return "$" + d["Tax Collections"] + "B";
})
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
});
</script>
</body>
Thank you in advance!
While rendering your line labels, you just want to add an event listener for mouseover that shows and hides it. So it appears everything here is good to go except for showing and hiding your labels, which again you should do on mouseover/mouseout.
Here's an example of what I mean that I recently worked on:
g.append('svg:circle')
.attr('cx', function(){ return x(j.timestamp._d); })
.attr('cy', function(){ return y(j.value); })
.attr('r', 4)
.attr('stroke', ML.colors.array[i])
.attr('stroke-width', 2)
.attr('fill', '#ffffff')
.attr('class', 'circle-markers')
.attr('data-index', k)
.on('mouseover', function(){
$(this).attr('fill', ML.colors.array[i]);
}).on('mouseout', function(){
$(this).attr('fill', '#ffffff');
});
In this example I have a line chart with circles drawn at each point. The circles initially have a white center with a stroke but on mouseover the center fills in the same color as the stroke. Then of course on mouseout this reverses.
Hope this helps.
Problem:
I've got a D3.js scatter plot that has 16 different data sets, but it seems like D3 has only 10 different colours built-in before it repeats. You can see what I mean by clicking that link.
Code:
function updatePlot() {
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.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")
.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("data.csv", function(error, 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("HPF/LPF Intensity Ratio");
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("HPF Intensity (relative units)")
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; });
});
}
(The code is pretty much copy/paste from here with a little customisation in the areas of D3 that I understand)
Thanks!
This part of the docs has the answer: Ordinal-Scales#categorical-colors. Thanks to user and Lars Kotthoff!
Simply replaced category10 with category20.