I am completely new to d3.
I have the following CSV:
HeaderAttempts HeaderGoals FreekickAttempts FreekickGoals Team
5 2 3 2 Team A
2 2 12 1 Team A
8 2 13 5 Team B
4 3 6 2 Team B
7 2 10 1 Team C
6 5 13 7 Team C
8 7 9 3 Team C
I am trying to create a scatter plot where x axis will have attempts and y axis will have the goals.
i have been able to create a scatter plot for the header attempts and goals by using the following code:
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
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 axisNames = {
HeaderAttempts: 'HeaderAttempts',
HeaderGoals: 'HeaderGoals',
FreekickAttempts: 'FreekickAttempts',
FreekickGoals: 'FreekickGoals'
};
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("FootballData.csv", function(error, data) {
data.forEach(function(d) {
d.HeaderAttempts = +d.HeaderAttempts;
d.HeaderGoals = +d.HeaderGoals;
d.FreekickAttempts = +d.FreekickAttempts;
d.FreekickGoals = +d.FreekickGoals;
});
x.domain(d3.extent(data, function(d) { return d.HeaderAttempts; })).nice();
y.domain(d3.extent(data, function(d) { return d.HeaderGoals; })).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("attempts");
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("goals")
var tooltip = d3.select("body").append("div") // tooltip code
.attr("class", "tooltip")
.style("opacity", 0);
var circlesH = svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.HeaderAttempts); })
.attr("cy", function(d) { return y(d.HeaderGoals); })
.style("fill", function(d) { return color(d.Team); })
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", 1.0);
tooltip.html(d.HeaderAttempts+" ,"+ d.HeaderGoals)
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 18) + "px");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
var circlesF = svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.FreekickAttempts); })
.attr("cy", function(d) { return y(d.FreekickGoals); })
.style("fill", function(d) { return color(d.Team); })
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", 1.0);
tooltip.html(d.FreekickAttempts+" ,"+ d.FreekickGoals)
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 18) + "px");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
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; });
d3.selectAll("[name=v]")
.on("change", function() {
var selected = this.value;
display = this.checked ? "inline" : "none";
svg.selectAll(".dot")
.filter(function(d) {return selected == d.Team;})
.attr("display", display);
});
});
</script>
<div id="filter">
<b>team Filter:</b>
<br>
<input name='v' value="Team A" type="checkbox" checked>Team A
</input>
<br>
<input name="v" value="Team B" type="checkbox" checked >Team B
</input>
<br>
<input name="v" value="Team C" type="checkbox" checked >Team C
</input>
</div>
I know this wasnt going to work but had to give it a shot.
Now i have no idea how to proceed.
This is actually a truncated data and i still have 4 more columns:
PenaltyAttempts, PenaltyGoals, CornerAttempts, CornerGoals
Your approach of making separate graphs and overlapping in this is not really correct.
Better way is to make your dataset as per your requirement.
data.forEach(function(d) {
d.HeaderAttempts = +d.HeaderAttempts;
d.HeaderGoals = +d.HeaderGoals;
d.FreekickAttempts = +d.FreekickAttempts;
d.FreekickGoals = +d.FreekickGoals;
var attempts = d.HeaderAttempts + d.FreekickAttempts;//calculate all attempts of a team
var goals = d.HeaderGoals + d.FreekickGoals;//calculate all goals of a team
//make your data set like this
all.push({
team: d.Team,
attempts: attempts,
goals: goals
});
});
Then use this all object to make your domains
x.domain(d3.extent(all, function(d) { return d.attempts; })).nice();
y.domain(d3.extent(all, function(d) { return d.goals; })).nice();
Even points can be made easily like this:
svg.selectAll(".dot")
.data(all)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) {console.log(d,"s");return x(d.attempts); })
.attr("cy", function(d) { return y(d.goals); })
.style("fill", function(d) { return color(d.team); })
Working code here
Hope this helps!
Related
I am using D3 charting library to create charts with Angular-cli. D3 version is 4.2.2. I create a multi-line chart and here is I am trying to add legend to the chart. Following code is my code look like.
import {Directive, ElementRef, HostListener, Renderer} from '#angular/core';
import * as D3 from 'd3';
#Directive({
selector: 'bar-graph'
})
export class BarGraphDirective {
private htmlElement:HTMLElement;
constructor(private elementRef:ElementRef, private renderer: Renderer) {
this.htmlElement = this.elementRef.nativeElement;
console.log(this.htmlElement);
console.log(D3);
let d3:any = D3;
var data = [{
"date": "2016-10-01",
"sales": 110,
"searches": 67
}, ...];
// set the dimensions and margins of the graph
var margin = {
top: 20,
right: 80,
bottom: 30,
left: 50
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date / time
var parseDate = d3.timeParse("%Y-%m-%d");
var formatTime = d3.timeFormat("%e %B");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var sales = function (d) {
return d["sales"];
}
var searches = function (d) {
return d.searches;
}
// define the line
var line = d3.line()
.x(function (d) {
return x(d.date);
})
.y(function (d) {
return y(d.sales);
});
var svg = d3.select(this.htmlElement).append("svg")
.attr("class", "bar-graph")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var color = d3.scaleOrdinal(d3.schemeCategory10);
var tooltip = d3.select("body").append("div")
.style("opacity", 0);
// format the data
data.forEach(function (d) {
d.date = parseDate(d.date);
});
x.domain(d3.extent(data, function (d) {
return d.date;
}));
y.domain([0, d3.max(data, function (d) {
return d.sales > d.searches ? d.sales : d.searches;
})]);
// Add the line path.
svg.append("path")
.attr("class", "line")
.style("fill", "none")
.attr("d", line(data))
.style("stroke", "orange")
.style("stroke-width", "2px");
// change line to look at searches
line.y(function (d) {
return y(d.searches);
});
// Add the second line path.
svg.append("path")
.attr("class", "line")
.style("fill", "none")
.attr("d", line(data))
.style("stroke", "steelblue")
.style("stroke-width", "2px");
// Add sales to the scatterplot
svg.selectAll(".sales-circle")
.data(data)
.enter().append("circle")
.attr('class', 'sales-circle')
.attr("r", 4)
.attr("cx", function (d) {
return x(d.date);
})
.attr("cy", function (d) {
return y(d.sales);
})
.style("fill", "orange");
// Add searches to the scatterplot
svg.selectAll(".searches-circle")
.data(data)
.enter().append("circle")
.attr("r", 4)
.attr('class', 'searches-circle')
.attr("cx", function (d) {
return x(d.date);
})
.attr("cy", function (d) {
return y(d.searches);
})
.style("fill", "steelblue")
.on("mouseover", function (d) {
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html(formatTime(d["date"]) + "<br/> Searches: " + d["searches"])
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.classed("tooltip", true);
})
.on("mouseout", function (d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
// draw legend
var legend = svg.selectAll("g")
.data(data)
.enter().append("g")
.attr("class", "legend");
// draw legend colored rectangles
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
// draw legend text
legend.append("text")
.style("font", "14px open-sans")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text("Sales");
// Add the X Axis
svg.append("g")
.style("font", "14px open-sans")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")));
// Add the Y Axis
svg.append("g")
.style("font", "14px open-sans")
.call(d3.axisLeft(y));
// Add Axis labels
svg.append("text")
.style("font", "14px open-sans")
.attr("text-anchor", "middle")
.attr("transform", "translate(" + (-margin.left / 2) + "," + (height / 2) + ")rotate(-90)")
.text("Sales / Searches");
svg.append("text")
.style("font", "14px open-sans")
.attr("text-anchor", "middle")
.attr("transform", "translate(" + (width / 2) + "," + (height + (margin.bottom)) + ")")
.text("Date");
}
}
My chart looks like below. It shows only one item in the legend. How to add both items (sales & searches) to the legend.
Any suggestion are highly appreciated.
Thanks You
Add this in the code for adding new rect and text:
legend.append("rect")
.attr("x", width - 18)
.attr("y", 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", "steelblue");
// draw legend text
legend.append("text")
.style("font", "14px open-sans")
.attr("x", width - 24)
.attr("y", 18)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text("Searches");
I have a bar chart that updates based on the results selected in a drop-down menu. When I change the selcetion, I get negaitve "y" values. It seems that my domain does not get updated with the new data. When I hard code the domain, my "y" are what I expect them to be. Anyone knows why ? Any other other comments (formatting, etc) welcomed.
var new_data;
//Create SVG margins and patting for the interior
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
//Create Scale
var xScale = d3
.scale
.ordinal()
.rangeRoundBands([margin.left, width], .1);
;
var yScale = d3
.scale
.linear()
.range([height, 0])
;
var xAxis = d3
.svg
.axis()
.scale(xScale)
.orient("bottom")
.tickPadding([5])
;
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(10)
;
//Create SVG with the above specs
var svg = d3.select("#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
.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
;
svg
.append("g")
.attr("class", "y axis")
.append("text") // just for the title (ticks are automatic)
.attr("transform", "rotate(-90)") // rotate the text!
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("frequency")
;
var temp = svg
.append("g")
.attr("class", "domx")
;
d3.csv("data3.csv", function(error, csv_data) {
// Filter the dataset to only get dept_1
var new_data = csv_data.filter(function(d) {
return d['dept'] == 'dept_1';
});
// function to handle histogram.
function histoGram(new_data){
//Create Scales
xScale
.domain(new_data.map(function(d) {return d.Pos;}))
;
yScale
// .domain([0, d3.max(new_data, function(d) { return d.Value; })])
.domain([0, d3.max(new_data, function(d) { return d.Value; })])
// .domain([0, 20])
;
svg
.select(".x.axis")
.transition()
.duration(1500)
.call(xAxis)
;
svg
.select(".y.axis")
.transition()
.duration(1500)
.call(yAxis)
;
// Data Join
var MyGroups = temp
.selectAll("g")
.data(new_data);
;
var MyGroupsEnter = MyGroups
.enter()
.append("g")
;
//Update
MyGroups
.attr("class", "update")
;
//Enter
MyGroupsEnter
.append("rect")
.attr("class", "enter")
.attr("x", function(d) { return xScale(d.Pos); })
.attr("y", function(d) { return (yScale(d.Value));})
.attr("width", xScale.rangeBand())
.attr("height", function(d) { return (height - yScale(d.Value)); })
.text(function(d) { return d.Value; })
.attr("fill", function(d) {return "rgb(0, 0, 0)";})
.style("fill-opacity", 0.2)
;
MyGroupsEnter
.append("text")
.attr("class", "text")
.text(function(d) { return d.Value; })
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "black")
.attr("text-anchor", "middle")
.attr("x", function(d) { return xScale(d.Pos) + xScale.rangeBand()/2; })
.attr("y", function(d) { return yScale(d.Value) - 10; })
;
//Enter + Update
MyGroups
.transition()
.duration(1500)
.select("rect")
.attr("x", function(d) { return xScale(d.Pos); })
.attr("width", xScale.rangeBand())
.attr("y", function(d) { return (yScale(d.Value));})
.attr("height", function(d) { return (height - yScale(d.Value)); })
.text(function(d) { return d.Value; })
.style("fill-opacity", 1) // set the fill opacity
.attr("fill", function(d) {return "rgb(0, 0, " + (d.Value * 30) + ")";})
;
MyGroups
.transition()
.duration(1500)
.select("text")
.attr("class", "text")
.text(function(d) { return d.Value; })
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "black")
.attr("text-anchor", "middle")
.attr("x", function(d) { return xScale(d.Pos) + xScale.rangeBand()/2; })
.attr("y", function(d) { return yScale(d.Value) - 8; })
;
MyGroups
.exit()
.transition()
.duration(1500)
.remove()
;
}
histoGram(new_data);
var options = ["dept_1","dept_2","dept_3"];
var dropDown = d3
.select("#sel_button")
.append("select")
.attr("name", "options-list")
.attr("id", "id-name");
var options = dropDown
.selectAll("option")
.data(options)
.enter()
.append("option");
options
.text(function (d) { return d; })
.attr("value", function (d) { return d; });
d3.select("#id-name")
.on("change", function() {
var value = d3.select(this).property("value");
var new_data2 = csv_data.filter(function(d) {
return d['dept'] == value;
});
histoGram(new_data2);
});
});
Here is the data:
dept,Pos,Value
dept_1,d1_p1,1
dept_1,d1_p10,10
dept_1,d1_p11,11
dept_1,d1_p12,12
dept_2,d2_p1,1.5
dept_2,d2_p2,3
dept_2,d2_p3,4.5
dept_2,d2_p4,6
dept_2,d2_p5,7.5
dept_2,d2_p6,9
dept_2,d2_p7,10.5
dept_2,d2_p8,12
dept_2,d2_p9,13.5
dept_2,d2_p10,15
dept_2,d2_p11,16.5
dept_2,d2_p12,17.5
dept_2,d2_p13,18.5
dept_3,d3_p1,5
dept_3,d3_p2,7
dept_3,d3_p3,10
Firgured out what was my problem. I hadn't defined the format of the values. The max function was returning the maximum number out of character values (9). I added the following piece of code prior to the domain function and everything now works fines.
csv_data.forEach(function(d) {
d.dept = d.dept;
d.Pos = d.Pos;
d.Value = +d.Value;
});
I have been trying to add labels to my bar chart as described in this question:
Adding label on a D3 bar chart
However, I can get the labels to display, but not over the appropriate bar (they are all lined up over/ on the first bar). Any help would be greatly appreciated. Here is my code:
var cdata = { title: "Sample Chart", Pod: 10, WOSNF : 201.57, SNFW: 8.89, YTDTarget: 15.14, AnnualTarget: 22.10, Max: 250 }
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// Parse the categories
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 30]);
y.domain([0, 30]);
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("data2.csv", function(error, data) {
data.forEach(function(d) {
d.value = +d.value;
console.log(d.value);
});
x.domain(data.map(function(d) { return d.Category; }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.style("text-anchor", "end")
.attr("x", width/2)
.attr("y", 30)
.attr("dx", ".71em")
.attr("transform", "translate(40,20)" )
;
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "translate(" + (width / 2) + ",-25)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "middle")
.style("font-size", "14pt")
.text("Sample Chart");
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.style("fill", "steelblue")
.style("fill-opacity", "0.5")
.attr("x", function(d) { return x(d.Category); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value) - 1;})
.attr("height", function(d) { return height - y(d.value);})
var yTextPadding = 20;
svg.selectAll("bartext")
.data(data)
.enter().append("text")
.attr("class", "bartext")
.attr("text-anchor", "middle")
.attr("fill", "black")
.attr("x", function(d, i) {
return x.rangeBand()/2;
})
.attr("y", function(d) {
return y(d.value);
})
.text(function(d){
return d.value;
});
});
var G3 = svg.append("g")
G3.append("line")
.attr("y1", y(cdata["YTDTarget"])-1)
.attr("y2", y(cdata["YTDTarget"])-1)
.attr("x1", 0)
.attr("x2", 500)
.attr("stroke-width", 2)
.attr("stroke", "black");
G3.append("text")
.attr("x",10)
.attr("y", y(cdata["YTDTarget"])+10)
.style("fill", "black")
.style("text-anchor", "start")
.text("RU YTD Target - " + cdata["YTDTarget"]);
var G4 = svg.append("g")
G4.append("line")
.attr("y1", y(cdata["AnnualTarget"])-1)
.attr("y2", y(cdata["AnnualTarget"])-1)
.attr("x1", 0)
.attr("x2", 500)
.attr("stroke-width", 2)
.attr("stroke", "black");
G4.append("text")
.attr("x", 10)
.attr("y", y(cdata["AnnualTarget"])+10)
.style("fill", "black")
.style("text-anchor", "start")
.text("RU Annual Target - " + cdata["AnnualTarget"]);
And here is the data:
Category,value
"Group1",27.2
"Group2",24.6
"Group3",27.1
The elements following the parsing of the data are to draw lines across the graph for reference.
Thanks!
You're currently setting the x position of the labels to half the width of the first bar (so they all end up on the left.
You want the x position of the bartext to start at the same spot as the current bar and add half the width of the bar:
.attr("x", function(d, i) {
return x(d.Category) + (x.rangeBand() / 2);
})
I have successfully managed to create a grouped bar chart that displays the various performance stats for soccer players over the course of one season. This data is all loaded from a csv file. I would now like to dynamically change that data whereby when a button is pressed, a new csv file is loaded with the stats corresponding to the next soccer season. I've tried to do this on my own but everytime I try reload the data, the old data as well as the old axis's remain present and the enw data loads ontop of these. It all ends up looking messy. So how do I have the old bars and axises updated in line with the new data? Here is my code:
$(document).ready(function(){
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
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("SoccerStatsCSV.csv", function(error, data) {
console.log(data);
var playerNames = d3.keys(data[0]).filter(function(key) { return key !== "Attribute"; });
console.log(playerNames);
data.forEach(function(d) {
d.Playerstats = playerNames.map(function(name) { return {name: name, value: +d[name]}; });
console.log(d.Playerstats);
});
x0.domain(data.map(function(d) { return d.Attribute; }));
x1.domain(playerNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d.Playerstats, function(d) { return d.value; }); })]);
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", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Units");
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x0(d.Attribute) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.Playerstats; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(playerNames.slice())
.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 updating button
d3.select("button")
.on('click',function(){
d3.csv("SoccerStatsCSV2008.csv", function(error, data) {
console.log(data);
var playerNames = d3.keys(data[0]).filter(function(key) { return key !== "Attribute"; });
console.log(playerNames);
data.forEach(function(d) {
d.Playerstats = playerNames.map(function(name) { return {name: name, value: +d[name]}; });
console.log(d.Playerstats);
});
x0.domain(data.map(function(d) { return d.Attribute; }));
x1.domain(playerNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d.Playerstats, function(d) { return d.value; }); })]);
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", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Units");
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x0(d.Attribute) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.Playerstats; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(playerNames.slice())
.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; });
});
});
});
I need to put a d3 chart on a HTML div using bootstrap but I can't.
I managed to attach it on body, but I don't know why I cant inside a div.
I'm using a code like this for the script:
var chart1 = d3.select("#chart1")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
and a simple way for html:
<div id="chartline1"></div>
Here is all the code:
<!DOCTYPE html>
<html>
<head>
<title>Linee1</title>
</head>
<meta charset="utf-8">
<body>
<script type="text/javascript" src="d3/d3.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/jquery.min.js"></script>
<link rel="stylesheet" href="css/style.css">
<script>
var margin = {top: 130, right: 40, bottom: 45, left: 150},
width = 1000 - margin.left - margin.right,
height = 505 - margin.top - margin.bottom;
var parseDate = d3.time.format("%d-%b-%y").parse;
var formatTime = d3.time.format("%e %B");
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").ticks(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(3);
var valueline = d3.svg.line()
.interpolate("linear-open")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
var valueline2 = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.open); });
var div = d3.select("#chartline1").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var chart1 = d3.select("#chartline1")
.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 + ")");
function make_x_axis() {
return d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5)
}
function make_y_axis() {
return d3.svg.axis()
.scale(y)
.orient("left")
.ticks(3)
}
// Get the data
d3.tsv("data/data2.tsv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
d.open = +d.open;
});
// 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.max(d.close, `d.open); })]);`
//grid
chart1.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(make_x_axis()
.tickSize(-height, 0, 0)
.tickFormat("")
)
chart1.append("g")
.attr("class", "grid")
.call(make_y_axis()
.tickSize(-width, 0, 0)
.tickFormat("")
)
chart1.append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.style("font-size", "12px") ;
chart1.append("text") // text label for the x axis
.attr("transform",
"translate(" + (width/2) + " ," + (height+margin.bottom-3) + ")")
.style("text-anchor", "middle")
.text("Tempo");
chart1.append("g") // Add the Y Axis
.attr("class", "y axis")
.call(yAxis)
.style("font-size", "12px");
chart1.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 70 - margin.left)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Valore");
chart1.append("path")
.attr("class", "line")
.attr("d", valueline(data))
.style("stroke-width", 5);
chart1.append("path")
.attr("class", "line")
.style("stroke", "#6f6f6f")
.attr("d", valueline2(data))
.style("stroke-width", 5);
;
//tooltip line 1
chart1.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5.5)
.style("fill", "#fff8ee")
.style("opacity", 1) // set the element opacity
.style("stroke", "#f93") // set the line colour
.style("stroke-width", 3.5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.close); })
.on("mouseover", function(d) {
d3.select(this).attr("r", 8).style("fill", "#f93").style("opacity", 1) ;
div.transition()
.duration(70)
.style("opacity", .8)
;
div .html(formatTime(d.date) + "<br/>" + d.close)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 64) + "px");
})
.on("mouseout", function(d) {
d3.select(this).attr("r", 5.5).style("fill", "#fff8ee");
div.transition()
.duration(200)
.style("opacity", 0) });
//tooltio line2
chart1.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5.5)
.style("fill", "#fff8ee")
.style("opacity", 1) // set the element opacity
.style("stroke", "#6f6f6f") // set the line colour
.style("stroke-width", 3.5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.open); })
.on("mouseover", function(d) {
d3.select(this).attr("r", 8).style("fill", "#6f6f6f").style("opacity", 1) ; //il punto cambia al mousover (bellissmo)
div.transition()
.duration(70)
.style("opacity", .7)
.style("border", "1px");
div .html(formatTime(d.date) + "<br/>" + d.close)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 64) + "px");
})
.on("mouseout", function(d) {
d3.select(this).attr("r", 5.5).style("fill", "#fff8ee");
div.transition()
.duration(200)
.style("opacity", 0);
});
//title
chart1.append("text")
.attr("x", (width / 6))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "20px")
.style("text-decoration", "none")
.text("Modello 1: Serie (pochi dati) ");
});
</script>
<div id="chartline1" ></div>
</body>
</html>
You must declare your div before you call the script. Put the script after it or encapsulate it in a function and call it on load.
<!DOCTYPE html>
<html>
<head>
<title>Linee1</title>
<meta charset="utf-8">
<script type="text/javascript" src="d3/d3.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/jquery.min.js"></script>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="chartline1" ></div>
</body>
<script>
var margin = {top: 130, right: 40, bottom: 45, left: 150},
width = 1000 - margin.left - margin.right,
height = 505 - margin.top - margin.bottom;
var parseDate = d3.time.format("%d-%b-%y").parse;
var formatTime = d3.time.format("%e %B");
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").ticks(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(3);
var valueline = d3.svg.line()
.interpolate("linear-open")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
var valueline2 = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.open); });
var div = d3.select("#chartline1").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var chart1 = d3.select("#chartline1")
.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 + ")");
function make_x_axis() {
return d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5)
}
function make_y_axis() {
return d3.svg.axis()
.scale(y)
.orient("left")
.ticks(3)
}
// Get the data
d3.tsv("data/data2.tsv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
d.open = +d.open;
});
// 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.max(d.close, `d.open); })]);`
//grid
chart1.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(make_x_axis()
.tickSize(-height, 0, 0)
.tickFormat("")
)
chart1.append("g")
.attr("class", "grid")
.call(make_y_axis()
.tickSize(-width, 0, 0)
.tickFormat("")
)
chart1.append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.style("font-size", "12px") ;
chart1.append("text") // text label for the x axis
.attr("transform",
"translate(" + (width/2) + " ," + (height+margin.bottom-3) + ")")
.style("text-anchor", "middle")
.text("Tempo");
chart1.append("g") // Add the Y Axis
.attr("class", "y axis")
.call(yAxis)
.style("font-size", "12px");
chart1.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 70 - margin.left)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Valore");
chart1.append("path")
.attr("class", "line")
.attr("d", valueline(data))
.style("stroke-width", 5);
chart1.append("path")
.attr("class", "line")
.style("stroke", "#6f6f6f")
.attr("d", valueline2(data))
.style("stroke-width", 5);
;
//tooltip line 1
chart1.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5.5)
.style("fill", "#fff8ee")
.style("opacity", 1) // set the element opacity
.style("stroke", "#f93") // set the line colour
.style("stroke-width", 3.5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.close); })
.on("mouseover", function(d) {
d3.select(this).attr("r", 8).style("fill", "#f93").style("opacity", 1) ;
div.transition()
.duration(70)
.style("opacity", .8)
;
div .html(formatTime(d.date) + "<br/>" + d.close)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 64) + "px");
})
.on("mouseout", function(d) {
d3.select(this).attr("r", 5.5).style("fill", "#fff8ee");
div.transition()
.duration(200)
.style("opacity", 0) });
//tooltio line2
chart1.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5.5)
.style("fill", "#fff8ee")
.style("opacity", 1) // set the element opacity
.style("stroke", "#6f6f6f") // set the line colour
.style("stroke-width", 3.5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.open); })
.on("mouseover", function(d) {
d3.select(this).attr("r", 8).style("fill", "#6f6f6f").style("opacity", 1) ; //il punto cambia al mousover (bellissmo)
div.transition()
.duration(70)
.style("opacity", .7)
.style("border", "1px");
div .html(formatTime(d.date) + "<br/>" + d.close)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 64) + "px");
})
.on("mouseout", function(d) {
d3.select(this).attr("r", 5.5).style("fill", "#fff8ee");
div.transition()
.duration(200)
.style("opacity", 0);
});
//title
chart1.append("text")
.attr("x", (width / 6))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "20px")
.style("text-decoration", "none")
.text("Modello 1: Serie (pochi dati) ");
});
</script>
</html>