set the gridline at the back of gantt when redraw in d3 - javascript

i know this maybe super duper simple to you guyz but this is the last piece of my project and i am done so i already want to finish this. here is my problem when i first load my gantt chart i draw first the axis and the gridlines before the chart it self so it appears as i desire that the gridlines is the background of my chart but when i redraw my chart there is the problem exist the gantt draw first before the gridlines so the output is the gridlines is covering the gantt chart which looks so bad. i will post my codes so you can check it. I can't pin point where i put first the gridlines. I think i need and extra eye here..........
d3.gantt = function() {
var FIT_TIME_DOMAIN_MODE = "fit";
var FIXED_TIME_DOMAIN_MODE = "fixed";
var margin = {
top : 50,
right : 40,
bottom : 20,
left : 120
};
var timeDomainStart = d3.time.day.offset(new Date(),-3);
var timeDomainEnd = d3.time.hour.offset(new Date(),+3);
var timeDomainMode = FIT_TIME_DOMAIN_MODE;// fixed or fit
var taskTypes = [];
var height = 500 - margin.top - margin.bottom-5;
var width = 1200 - margin.right - margin.left-5;
var tickFormat = "%H:%M";
var keyFunction = function(d) {
return d.startDate + d.taskName + d.endDate;
};
var rectTransform = function(d) {
return "translate(" + x(d.startDate) + "," + y(d.taskName) + ")";
};
var x = d3.time.scale().domain([ timeDomainStart, timeDomainEnd ]).range([ 0, width ]).clamp(true);
var y = d3.scale.ordinal().domain(taskTypes).rangeRoundBands([ 0, height - margin.top - margin.bottom ], .1);
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format(tickFormat)).tickSubdivide(true).tickSize(8).tickPadding(8);
var yAxis = d3.svg.axis().scale(y).orient("left").tickSize(0);
var initTimeDomain = function(tasks) {
if (timeDomainMode === FIT_TIME_DOMAIN_MODE) {
if (tasks === undefined || tasks.length < 1) {
timeDomainStart = d3.time.day.offset(new Date(), -3);
timeDomainEnd = d3.time.hour.offset(new Date(), +3);
return;
}
tasks.sort(function(a, b) {
return a.endDate - b.endDate;
});
timeDomainEnd = tasks[tasks.length - 1].endDate;
tasks.sort(function(a, b) {
return a.startDate - b.startDate;
});
timeDomainStart = tasks[0].startDate;
}
};
var xAxisGrid = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(-height + margin.top + margin.bottom, 0, 0)
.tickFormat("");
var initAxis = function() {
x = d3.time.scale().domain([ timeDomainStart, timeDomainEnd ]).range([ 0, width ]).clamp(true);
y = d3.scale.ordinal().domain(taskTypes).rangeRoundBands([ 0, height - margin.top - margin.bottom ], .1);
xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format(tickFormat)).tickSubdivide(true)
.tickSize(8).tickPadding(8);
yAxis = d3.svg.axis().scale(y).orient("left").tickSize(0);
xAxisGrid = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(-height + margin.top + margin.bottom, 0, 0)
.tickFormat("");
};
/////////////////////////////////
//Creating the chart
////////////////////////////
function gantt(tasks) {
initTimeDomain(tasks);
initAxis();
var dateFormat = d3.time.format("%Y-%m-%d");
var svg = d3.select("#gantt_chart")
.append("svg")
.attr("class", "chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("class", "gantt-chart")
.attr("width", width + margin.left + margin.right)
.attr("height", (height + margin.top + margin.bottom) / tasks[tasks.length - 1].endDate)
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
var div = d3.select("body").append("div")
.attr("class","tooltip")
.style("opacity",0);
//this is the x-axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, " + (height - margin.top - margin.bottom) + ")")
.transition()
.call(xAxis)
.selectAll("text")
.style("text-anchor","end")
.attr("dx", 35)
.attr("dy", 5);
//.attr("dx", "-.8em")
//.attr("dy", -10)
//.attr("transform", function(d){return "rotate(-90)"});
//this is the y-axis
svg.append("g").attr("class", "y axis").transition().call(yAxis);
// title of the gantt
svg.append("g")
.append("text")
.attr("x", 300)
.attr("y", -30)
.attr("class","title")
.style("font-size",20)
.text("MINI-PM SCHEDULER GANTT CHART");
// y title
svg.append("g")
.append("text")
.attr("transform", "rotate(-90)")
.attr("dx", -220)
.attr("dy", -100)
.style("font-size",16)
.text("HANDLER ID");
//this is the legend part
var colors = [["RUNNING", "#669900"],["WARNING", "#ffbb33"],["DOWN", "#FF0000"]];
var legend = svg.append("g")
.attr("class", "legend");
var circle = legend.selectAll('circle')
.data(colors)
.enter()
.append("circle")
.attr("cx", function (d, i) {
return (i * 80)+(width/2)-125;
})
.attr("cy", 405)
.attr("r", 5)
.style("fill", function (d) {
return d[1];
});
var legendText = legend.selectAll('text')
.data(colors)
.enter()
.append("text")
.attr("x", function (d, i) {
return (i * 80)+(width/2)-115;
})
.attr("y", 410)
.text(function (d) {
return d[0];
});
// Add X Axis grid lines
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate(0, " + (height - margin.top - margin.bottom) + ")")
.call(xAxisGrid);
//this is the actual gantt
svg.selectAll(".chart")
.data(tasks, keyFunction).enter()
.append("rect")
.attr("rx", 0)
.attr("ry", 0)
.attr("class", function(d){
if(d.status > 75)
{
return "bar-failed";
}
else if (d.status >= 55 && d.status <= 75){
return "bar-killed";
}
else{
return "bar-running";
}
})
.attr("y", 0)
.attr("transform", rectTransform)
.attr("height", function(d) { return y.rangeBand(); })
.attr("width", function(d) {
return (x(d.endDate) - x(d.startDate));
})
.on("mouseover", function(d){
div.transition()
.duration(200)
.style("opacity", .9);
div.html("HandlerID: " + d.taskName + "<br>" + "startDate: " + dateFormat(d.startDate) + "<br/>" + "endDate: " + dateFormat(d.endDate) + "<br/>" + "% Insertions: " + d3.round(d.status,2) + "%")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout",function(d){
div.transition()
.duration(500)
.style("opacity", 0);
});
/*
svg.append("g")
.append("text")
.attr("x", width / 2)
.attr("y", 380)
.style("font-size",12)
.text("PERIOD"); */
return gantt;
};
gantt.redraw = function(tasks) {
initTimeDomain(tasks);
initAxis();
var dateFormat = d3.time.format("%Y-%m-%d");
var div = d3.select("body").append("div")
.attr("class","tooltip")
.style("opacity",0);
var svg = d3.select("#gantt_chart");
var ganttChartGroup = svg.select(".gantt-chart");
var rect = ganttChartGroup.selectAll("rect").data(tasks, keyFunction);
rect.enter()
.insert("rect",":first-child")
.attr("rx", 0)
.attr("ry", 0)
.attr("class", function(d){
if(d.status > 75)
{
return "bar-failed";
}
else if (d.status >= 55 && d.status <= 75){
return "bar-killed";
}
else{
return "bar-running";
}
})
.transition()
.attr("y", 0)
.attr("transform", rectTransform)
.attr("height", function(d) { return y.rangeBand(); })
.attr("width", function(d) {
return (x(d.endDate) - x(d.startDate));
});
rect.transition()
.attr("transform", rectTransform)
.attr("height", function(d) { return y.rangeBand(); })
.attr("width", function(d) {
return (x(d.endDate) - x(d.startDate));
});
rect.exit().remove();
rect
.on("mouseover", function(d){
div.transition()
.duration(200)
.style("opacity", .9);
div.html("HandlerID: " + d.taskName + "<br>" + "startDate: " + dateFormat(d.startDate) + "<br/>" + "endDate: " + dateFormat(d.endDate) + "<br/>" + "% Insertions: " + d3.round(d.status,2) + "%")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout",function(d){
div.transition()
.duration(500)
.style("opacity", 0);
});
svg.select(".grid").transition().call(xAxisGrid);
svg.select(".x").transition().call(xAxis);
svg.select(".y").transition().call(yAxis);
return gantt;
}; // end of redraw
gantt.margin = function(value) {
if (!arguments.length)
return margin;
margin = value;
return gantt;
};
gantt.timeDomain = function(value) {
if (!arguments.length)
return [ timeDomainStart, timeDomainEnd ];
timeDomainStart = +value[0], timeDomainEnd = +value[1];
return gantt;
};
/**
* #param {string}
* vale The value can be "fit" - the domain fits the data or
* "fixed" - fixed domain.
*/
gantt.timeDomainMode = function(value) {
if (!arguments.length)
return timeDomainMode;
timeDomainMode = value;
return gantt;
};
gantt.taskTypes = function(value) {
if (!arguments.length)
return taskTypes;
taskTypes = value;
return gantt;
};
gantt.taskStatus = function(value) {
if (!arguments.length)
return taskStatus;
taskStatus = value;
return gantt;
};
gantt.width = function(value) {
if (!arguments.length)
return width;
width = +value;
return gantt;
};
gantt.height = function(value) {
if (!arguments.length)
return height;
height = +value;
return gantt;
};
gantt.tickFormat = function(value) {
if (!arguments.length)
return tickFormat;
tickFormat = value;
return gantt;
};
return gantt;
};

Related

Will previous version of d3 work with latter version of d3

The data is not loading up with the newest version of d3 and its not working
Here's the link
var yMargin = 40;
var width = 800;
var height = 400;
var barWidth = width / 275;
var tooltip = d3.select(".visHolder").append("div")
.attr("id", "tooltip")
.style("opacity", 0);
var overlay = d3.select(".visHolder").append("div")
.attr("class", "overlay")
.style("opacity", 0);
var svgContainer = d3.select(".visHolder")
.append("svg")
.attr("width", width + 100).attr("height", height + 60);
d3.json('https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json', function(err, data) {
svgContainer.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -200)
.attr("y", 80)
.text("Gross Domestic Product");
svgContainer.append("text")
.attr("x", width / 2 + 120)
.attr("y", height + 50)
.text('More Information: http://www.bea.gov/national/pdf/nipaguid.pdf')
.attr("class", "info");
var years = data.data.map(function(item) {
var quarter;
var temp = item[0].substring(5, 7);
if (temp === "01") {
quarter = "Q1";
} else if (temp === "04") {
quarter = "Q2";
} else if (temp === "07") {
quarter = "Q3";
} else if (temp === "10") {
quarter = "Q4";
}
return item[0].substring(0, 4) + " " + quarter
});
var yearsDate = data.data.map(function(item) {
return new Date(item[0]);
});
var xMax = new Date(d3.max(yearsDate));
xMax.setMonth(xMax.getMonth() + 3);
var xScale = d3.scaleTime()
.domain([d3.min(yearsDate), xMax])
.range([0, width]);
var xAxis = d3.axisBottom()
.scale(xScale);
var xAxisGroup = svgContainer.append("g")
.call(xAxis)
.attr("id", "x-axis")
.attr("transform", "translate(60, 400)");
var GDP = data.data.map(function(item) {
return item[1]
});
var scaledGDP = [];
var gdpMin = d3.min(GDP);
var gdpMax = d3.max(GDP);
var linearScale = d3.scaleLinear()
.domain([0, gdpMax])
.range([0, height]);
scaledGDP = GDP.map(function(item) {
return linearScale(item);
});
var yAxisScale = d3.scaleLinear()
.domain([0, gdpMax])
.range([height, 0]);
var yAxis = d3.axisLeft(yAxisScale)
var yAxisGroup = svgContainer.append("g")
.call(yAxis)
.attr("id", "y-axis")
.attr("transform", "translate(60,0)");
d3.select("svg").selectAll("rect")
.data(scaledGDP)
.enter()
.append("rect")
.attr("date-date", function(d, i) {
return data.data[i][0]
})
.attr("data-gdp", function(d, i) {
return data.data[i][1]
})
.attr("class", "bar")
.attr("x", function(d, i) {
return xScale(yearsDate[i]);
})
.attr("y", function(d, i) {
return height - d;
})
.attr("width", barWidth)
.attr("height", function(d) {
return d;
})
.style("fill", "#FD7272")
.attr("transform", "translate(60,0)")
.on("mouseover", function(d, i) {
overlay.transition()
.duration(0)
.style("height", d + "px")
.style("width", barWidth + "px")
.style("opacity", .9)
.style("left", (i * barWidth) + 0 + "px")
.style("top", height - d + "px")
.style("transform", "translateX(60px)");
tooltip.transition()
.duration(200)
.style("opacity", .9)
tooltip.html(years[i] + "<br>" + "$" +
GDP[i].toFixed(1).replace(/(\d)(?=(\d{3})+\.)/g, "$1,") + " Billion")
.attr("date-date", data.data[i][0])
.style("left", (i * barWidth) + 30 + "px")
.style("top", height - 100 + "px")
.style("transform", "translateX(60px)");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", 0);
overlay.transition()
.duration(200)
.style("opacity", 0);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.1/d3.min.js"></script>
<div class="main">
<div class="container">
<div id="title">United States GDP</div>
<div class="visHolder"></div>
</div>
</div>
In d3 v6., the old d3.json(<src>, <callback>) has been replaced in favour of d3.json(<src>).then(<successcallback>).catch(<errorcallback>);
The old freecodecamp example was written for an older version of d3.
That is why the following works, with minimal changes:
var yMargin = 40;
var width = 800;
var height = 400;
var barWidth = width / 275;
var tooltip = d3.select(".visHolder").append("div")
.attr("id", "tooltip")
.style("opacity", 0);
var overlay = d3.select(".visHolder").append("div")
.attr("class", "overlay")
.style("opacity", 0);
var svgContainer = d3.select(".visHolder")
.append("svg")
.attr("width", width + 100).attr("height", height + 60);
d3.json('https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json').then(function(data) {
svgContainer.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -200)
.attr("y", 80)
.text("Gross Domestic Product");
svgContainer.append("text")
.attr("x", width / 2 + 120)
.attr("y", height + 50)
.text('More Information: http://www.bea.gov/national/pdf/nipaguid.pdf')
.attr("class", "info");
var years = data.data.map(function(item) {
var quarter;
var temp = item[0].substring(5, 7);
if (temp === "01") {
quarter = "Q1";
} else if (temp === "04") {
quarter = "Q2";
} else if (temp === "07") {
quarter = "Q3";
} else if (temp === "10") {
quarter = "Q4";
}
return item[0].substring(0, 4) + " " + quarter
});
var yearsDate = data.data.map(function(item) {
return new Date(item[0]);
});
var xMax = new Date(d3.max(yearsDate));
xMax.setMonth(xMax.getMonth() + 3);
var xScale = d3.scaleTime()
.domain([d3.min(yearsDate), xMax])
.range([0, width]);
var xAxis = d3.axisBottom()
.scale(xScale);
var xAxisGroup = svgContainer.append("g")
.call(xAxis)
.attr("id", "x-axis")
.attr("transform", "translate(60, 400)");
var GDP = data.data.map(function(item) {
return item[1];
});
var scaledGDP = [];
var gdpMin = d3.min(GDP);
var gdpMax = d3.max(GDP);
var linearScale = d3.scaleLinear()
.domain([0, gdpMax])
.range([0, height]);
scaledGDP = GDP.map(function(item) {
return linearScale(item);
});
var yAxisScale = d3.scaleLinear()
.domain([0, gdpMax])
.range([height, 0]);
var yAxis = d3.axisLeft(yAxisScale)
var yAxisGroup = svgContainer.append("g")
.call(yAxis)
.attr("id", "y-axis")
.attr("transform", "translate(60,0)");
d3.select("svg").selectAll("rect")
.data(scaledGDP)
.enter()
.append("rect")
.attr("date-date", function(d, i) {
return data.data[i][0]
})
.attr("data-gdp", function(d, i) {
return data.data[i][1]
})
.attr("class", "bar")
.attr("x", function(d, i) {
return xScale(yearsDate[i]);
})
.attr("y", function(d, i) {
return height - d;
})
.attr("width", barWidth)
.attr("height", function(d) {
return d;
})
.style("fill", "#FD7272")
.attr("transform", "translate(60,0)")
.on('click', function(event, d) {
console.log(d);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.1/d3.min.js"></script>
<div class="main">
<div class="container">
<div id="title">United States GDP</div>
<div class="visHolder"></div>
</div>
</div>
To use click events, as per this migration guide, the new signature passes (event, data, index), not (data, index). The above snippet contains an example, where d is logged when a bar is clicked.

my data is undefined in my d3.js data viz

I'm trying to build a line graph that when the user hovers over a part of the chart, a callout appears with the date, country and incidents data points. however currently all my data points show up as 'undefined'. does anyone know what's going on here?
here is my code.
function circleHover(chosen) {
if (modus == "incidents") {
d3.select("#callOut")
.style("top", "570px")
.style("left", "30px");
d3.select("#divCountry").html('Country: ' + chosen.country);
d3.select("#divDate").html('Date: ' + chosen.date);
d3.select("#divIncidents").html('Incidents: ' + chosen.incidents);
d3.select("#callOut")
.style("visibility","visible");
}
if (modus == "fatalities") {
d3.select("#callOut2")
.style("top", "570px")
.style("left", "30px");
d3.select("#divCountry2").html('Country: ' + chosen.country);
d3.select("#divDate2").html('Date: ' + chosen.date);
d3.select("#divFatalities2").html('Fatalities: ' + chosen.fatalities);
d3.select("#callOut2")
.style("visibility","visible");
}
if (modus == "injuries") {
d3.select("#callOut3")
.style("top", "570px")
.style("left", "30px");
d3.select("#divCountry3").html('Country: ' + chosen.country);
d3.select("#divDate3").html('Date: ' + chosen.date);
d3.select("#divInjuries3").html('Injuries: ' + chosen.injuries);
d3.select("#callOut3")
.style("visibility","visible");
}
};
function showOne(d) {
var margin = {top: 80, right: 80, bottom: 80, left: 80},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("#svg").append("svg")
.attr("width", width)
.attr("height", height);
var incidentsData = svg.append("g");
incidentsData.selectAll(".incidentsData")
.data(incidentData)
.enter()
.append('incidentsData')
.attr('class', 'incidentsData');
var fatalitiesData = svg.append("g");
fatalitiesData.selectAll(".fatalitiesData")
.data(fatalityData)
.enter()
.append('fatalitiesData')
.attr('class', 'fatalitiesData');
var injuriesData = svg.append("g");
injuriesData.selectAll(".injuriesData")
.data(injuryData)
.enter()
.append('injuriesData')
.attr('class', 'injuriesData');
var chosen = d;
var setOpacity = 0;
if (modus == "incidents") {
circleHover(chosen);
setOpacity = 0.1;
incidentsData.selectAll(".incidentsData")
.filter(function (d) { return eval("d.country") != eval("chosen.country");})
.style("fill-opacity", setOpacity);
}
if (modus == "fatalities") {
circleHover(chosen);
setOpacity = 0.1;
fatalitiesData.selectAll(".fatalitiesData")
.filter(function (d) { return eval("d.country") != eval("chosen.country");})
.style("fill-opacity", setOpacity);
}
if (modus == "injuries") {
circleHover(chosen);
setOpacity = 0.1;
injuriesData.selectAll(".injuriesData")
.filter(function (d) { return eval("d.country") != eval("chosen.country");})
.style("fill-opacity", setOpacity);
}
};
function showAll() {
var margin = {top: 80, right: 80, bottom: 80, left: 80},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("#svg").append("svg")
.attr("width", width)
.attr("height", height);
var incidentsData = svg.append("g");
incidentsData.selectAll(".incidentsData")
.data(incidentData)
.enter()
.append('incidentsData')
.attr('class', 'incidentsData');
var fatalitiesData = svg.append("g");
fatalitiesData.selectAll(".fatalitiesData")
.data(fatalityData)
.enter()
.append('fatalitiesData')
.attr('class', 'fatalitiesData');
var injuriesData = svg.append("g");
injuriesData.selectAll(".injuriesData")
.data(injuryData)
.enter()
.append('injuriesData')
.attr('class', 'injuriesData');
if (modus == "incidents") {
incidentsData.selectAll(".incidentsData")
.style("fill-opacity", 0.5);
d3.select("#callOut").style("visibility","hidden");
}
if (modus == "fatalities") {
fatalitiesData.selectAll(".fatalitiesData")
.style("fill-opacity", 0.5);
d3.select("#callOut2").style("visibility","hidden");
}
if (modus == "injuries") {
injuriesData.selectAll(".injuriesData")
.style("fill-opacity", 0.5);
d3.select("#callOut3").style("visibility","hidden");
}
};
//totalIncidents
function totalIncidentsLineGraph() {
modus = "incidents";
var margin = {top: 80, right: 80, bottom: 80, left: 80},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("#svg").append("svg")
.attr("width", width)
.attr("height", height);
var incidentsData = svg.append("g");
incidentsData.selectAll(".incidentsData")
.data(incidentData)
.enter()
.append('incidentsData')
.attr('class', 'incidentsData');
//.on("mouseover", showOne)
//.on("mouseout", showAll);
//.attr('id', function (d) { return "id_2010_" + d.rank_pop; })
//var parse = d3.time.format("%b %Y").parse;
var parse = d3.time.format("%Y").parse;
// Scales and axes. Note the inverted domain for the y-scale: bigger is up!
var x = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]),
xAxis = d3.svg.axis().scale(x).tickSize(-height).tickSubdivide(true),
yAxis = d3.svg.axis().scale(y).ticks(4).orient("right");
// An area generator, for the light fill.
var area = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.incidents); });
// A line generator, for the dark stroke.
var line = d3.svg.line()
.interpolate("monotone")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.incidents); });
// Parse dates and numbers. We assume israel are sorted by date.
function type(d) {
d.country = d.country;
d.date = parse(d.date);
d.incidents = +d.incidents
return d;
};
var data = d3.csv("static/data/israel/incidents_linechart.csv", type, function(error, data) {
console.log(data);
var israel = data.filter(function(d) {
return d.country == "Israel";
});
var unitedStates = data.filter(function(d) {
return d.country == "United States";
});
var iran = data.filter(function(d) {
return d.country == "Iran";
});
var saudiArabia = data.filter(function(d) {
return d.country == "Saudi Arabia";
});
var turkey = data.filter(function(d) {
return d.country == "Turkey";
});
var egypt = data.filter(function(d) {
return d.country == "Egypt";
});
var syria = data.filter(function(d) {
return d.country == "Syria";
});
var lebanon = data.filter(function(d) {
return d.country == "Lebanon";
});
var jordan = data.filter(function(d) {
return d.country == "Jordan";
});
var palestine = data.filter(function(d) {
return d.country == "Palestine";
});
x.domain([unitedStates[0].date, unitedStates[unitedStates.length - 1].date]);
y.domain([0, d3.max(egypt, function(d) { return d.incidents; })]).nice();
//x.domain([israel[0].date, israel[israel.length - 1].date]);
//y.domain([0, d3.max(israel, function(d) { return d.incidents; })]).nice();
// Add an SVG element with the desired dimensions and margin.
var svg = d3.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 + ")")
// Add the clip path.
svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the y-axis.
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ",0)")
.call(yAxis);
var colors = d3.scale.category10();
svg.selectAll('.line')
.data([israel, unitedStates, iran, saudiArabia, turkey, egypt, syria, lebanon, jordan, palestine]) /// can add however many i want here
.enter()
.append('path')
.attr('class', 'line')
.style('stroke', function(d) {
return colors(Math.random() * 50);
})
.attr('clip-path', 'url(#clip)')
.attr('d', function(d) {
return line(d);
})
.on("mouseover", showOne)
.on("mouseout", showAll);
/* Add 'curtain' rectangle to hide entire graph */
var curtain = svg.append('rect')
.attr('x', -1 * width)
.attr('y', -1 * height)
.attr('height', height)
.attr('width', width)
.attr('class', 'curtain')
.attr('transform', 'rotate(180)')
.style('fill', '#ffffff')
/* Optionally add a guideline */
var guideline = svg.append('line')
.attr('stroke', '#333')
.attr('stroke-width', 0)
.attr('class', 'guide')
.attr('x1', 1)
.attr('y1', 1)
.attr('x2', 1)
.attr('y2', height)
/* Create a shared transition for anything we're animating */
var t = svg.transition()
.delay(750)
.duration(6000)
.ease('linear')
.each('end', function() {
d3.select('line.guide')
.transition()
.style('opacity', 0)
.remove()
});
t.select('rect.curtain')
.attr('width', 0);
t.select('line.guide')
.attr('transform', 'translate(' + width + ', 0)')
d3.select("#show_guideline").on("change", function(e) {
guideline.attr('stroke-width', this.checked ? 1 : 0);
curtain.attr("opacity", this.checked ? 0.75 : 1);
})
});
};
here is a snippet of my data:
any help owuld be immensely appreciated.

Morph areas into bars with D3?

I'm able to generate the following graph using D3 areas:
I want to create the following animation. When the webpage loads, you see the first figure. Then, each of the areas morphs into a bar. Finally, I would like to allow users to toggle between the two figures by clicking "B" or "D".
I was able to add the buttons and the corresponding bars to my figure, but I'm having troubles figuring out how to do the animation. This is the code that I have right now:
HTMLWidgets.widget({
name: 'IMposterior',
type: 'output',
factory: function(el, width, height) {
// TODO: define shared variables for this instance
return {
renderValue: function(opts) {
console.log("threshold: ", opts.threshold);
console.log("bars: ", opts.bars);
var margin = {left:50,right:50,top:40,bottom:125};
xMax = d3.max(opts.data, function(d) { return d.x ; });
yMax = d3.max(opts.data, function(d) { return d.y ; });
xMin = d3.min(opts.data, function(d) { return d.x ; });
yMin = d3.min(opts.data, function(d) { return d.y ; });
var y = d3.scaleLinear()
.domain([0,yMax])
.range([height-margin.bottom,0]);
var x = d3.scaleLinear()
.domain([xMin,xMax])
.range([0,width]);
var yAxis = d3.axisLeft(y);
var xAxis = d3.axisBottom(x);
var area = d3.area()
.x(function(d){ return x(d.x) ;})
.y0(height-margin.bottom)
.y1(function(d){ return y(d.y); });
var svg = d3.select(el).append('svg').attr("height","100%").attr("width","100%");
var chartGroup = svg.append("g").attr("transform","translate("+margin.left+","+margin.top+")");
chartGroup.append("path")
.attr("d", area(opts.data.filter(function(d){ return d.x< -opts.MME ;})))
.style("fill", opts.colors[0]);
if(opts.MME !==0){
chartGroup.append("path")
.attr("d", area(opts.data.filter(function(d){ return (d.x < opts.MME & d.x > -opts.MME) ;})))
.style("fill", opts.colors[1]);
}
chartGroup.append("path")
.attr("d", area(opts.data.filter(function(d){ return d.x > opts.MME ;})))
.style("fill", opts.colors[2]);
chartGroup.append("g")
.attr("class","axis x")
.attr("transform","translate(0,"+(height-margin.bottom)+")")
.call(xAxis);
var tooltip = d3.tip()
.attr('class', 'd3-tip chart-data-tip')
.offset([30, 0])
.direction('s')
.html(function(d, i) {
return "<strong>" + d + "</strong> <span style='color:" + "white" + "'>"+ "</span>";
});
svg.call(tooltip);
chartGroup.selectAll("path").data(opts.text).on('mouseover', tooltip.show).on('mouseout', tooltip.hide);
// Bars
var yBar = d3.scaleLinear()
.domain([0,1])
.range([height-margin.bottom,0]);
var xBar = d3.scaleBand()
.domain(opts.bars.map(function(d) { return d.x; }))
.rangeRound([0, width]).padding(0.1);
var yAxisBar = d3.axisLeft(yBar);
var xAxisBar = d3.axisBottom(xBar);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.append("g")
.attr("class", "axis axis--x")
.attr("transform","translate(0,"+(height-margin.bottom)+")")
.call(d3.axisBottom(xBar));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(yBar).ticks(10, "%"))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Probability");
g.selectAll(".bar")
.data(opts.bars)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xBar(d.x); })
.attr("y", function(d) { return yBar(d.y); })
.attr("width", xBar.bandwidth())
.style("fill", function(d) { return d.color; })
.attr("height", function(d) { return height - margin.bottom - yBar(d.y); });
// Add buttons
//container for all buttons
var allButtons= svg.append("g")
.attr("id","allButtons");
//fontawesome button labels
var labels= ["B", "D"];
//colors for different button states
var defaultColor= "#E0E0E0";
var hoverColor= "#808080";
var pressedColor= "#000000";
//groups for each button (which will hold a rect and text)
var buttonGroups= allButtons.selectAll("g.button")
.data(labels)
.enter()
.append("g")
.attr("class","button")
.style("cursor","pointer")
.on("click",function(d,i) {
updateButtonColors(d3.select(this), d3.select(this.parentNode));
d3.select("#numberToggle").text(i+1);
})
.on("mouseover", function() {
if (d3.select(this).select("rect").attr("fill") != pressedColor) {
d3.select(this)
.select("rect")
.attr("fill",hoverColor);
}
})
.on("mouseout", function() {
if (d3.select(this).select("rect").attr("fill") != pressedColor) {
d3.select(this)
.select("rect")
.attr("fill",defaultColor);
}
});
var bWidth= 40; //button width
var bHeight= 25; //button height
var bSpace= 10; //space between buttons
var x0= 20; //x offset
var y0= 10; //y offset
//adding a rect to each toggle button group
//rx and ry give the rect rounded corner
buttonGroups.append("rect")
.attr("class","buttonRect")
.attr("width",bWidth)
.attr("height",bHeight)
.attr("x",function(d,i) {return x0+(bWidth+bSpace)*i;})
.attr("y",y0)
.attr("rx",5) //rx and ry give the buttons rounded corners
.attr("ry",5)
.attr("fill",defaultColor);
//adding text to each toggle button group, centered
//within the toggle button rect
buttonGroups.append("text")
.attr("class","buttonText")
.attr("x",function(d,i) {
return x0 + (bWidth+bSpace)*i + bWidth/2;
})
.attr("y",y0+bHeight/2)
.attr("text-anchor","middle")
.attr("dominant-baseline","central")
.attr("fill","white")
.text(function(d) {return d;});
function updateButtonColors(button, parent) {
parent.selectAll("rect")
.attr("fill",defaultColor);
button.select("rect")
.attr("fill",pressedColor);
}
},
resize: function(width, height) {
// TODO: code to re-render the widget with a new size
}
};
}
});
And this is the figure that that code produces:
This does the trick:
HTMLWidgets.widget({
name: 'IMPosterior',
type: 'output',
factory: function(el, width, height) {
// TODO: define shared variables for this instance
return {
renderValue: function(opts) {
//transition
var transDuration = 1000;
var dataDiscrete = opts.bars.map((b, i) => {
b.y = Number(b.y);
b.desc = opts.text[i];
return b;
});
var distParams = {
min: d3.min(opts.data, d => d.x),
max: d3.max(opts.data, d => d.x)
};
distParams.cuts = [-opts.MME, opts.MME, distParams.max];
opts.data = opts.data.sort((a,b) => a.x - b.x);
var dataContinuousGroups = [];
distParams.cuts.forEach((c, i) => {
let data = opts.data.filter(d => {
if (i === 0) {
return d.x < c;
} else if (i === distParams.cuts.length - 1) {
return d.x > distParams.cuts[i - 1];
} else {
return d.x < c && d.x > distParams.cuts[i - 1];
}
});
data.unshift({x:data[0].x, y:0});
data.push({x:data[data.length - 1].x, y:0});
dataContinuousGroups.push({
color: opts.colors[i],
data: data
});
});
var margin = {
top: 50,
right: 20,
bottom: 80,
left: 70
},
dims = {
width: width - margin.left - margin.right,
height: height - margin.top - margin.bottom
};
var xContinuous = d3.scaleLinear()
.domain([distParams.min - 1, distParams.max + 1])
.range([0, dims.width]);
var xDiscrete = d3.scaleBand()
.domain(dataDiscrete.map(function(d) { return d.x; }))
.rangeRound([0, dims.width]).padding(0.1);
var y = d3.scaleLinear()
.domain([0, 1])
.range([dims.height, 0]);
var svg = d3.select(el).append("svg")
.attr("width", dims.width + margin.left + margin.right)
.attr("height", dims.height + margin.top + margin.bottom);
var g = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xAxis = d3.axisBottom()
.scale(xDiscrete);
var yAxis = d3.axisLeft()
.scale(y)
.ticks(10)
.tickFormat(d3.format(".0%"));
var yLabel = g.append("text")
.attr("class", "y-axis-label")
.attr("transform", "rotate(-90)")
.attr("y", -52)
.attr("x", -160)
.attr("dy", ".71em")
.style("text-anchor", "end")
.style("font-size", 14 + "px")
.text("Probability");
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + dims.height + ")")
.call(xAxis);
g.append("g")
.attr("class", "y axis")
.call(yAxis);
var areas = g.selectAll(".area")
.data(dataDiscrete)
.enter().append("path")
.attr("class", "area")
.style("fill", function(d) { return d.color; })
.attr("d", function(d, i) {
let numPts = dataContinuousGroups[i].data.length - 2;
var path = d3.path()
path.moveTo(xDiscrete(d.x), y(0));
for (j=0; j<numPts; j++) {
path.lineTo(xDiscrete(d.x) + j*xDiscrete.bandwidth()/(numPts-1), y(d.y))
}
path.lineTo(xDiscrete(d.x) + xDiscrete.bandwidth(), y(0));
return path.toString();
});
var tooltip = d3.tip()
.attr('class', 'd3-tip chart-data-tip')
.offset([30, 0])
.direction('s')
.html(function(d, i) {
return "<span>" + dataDiscrete[i].desc + "</span>";
});
g.call(tooltip);
areas
.on('mouseover', tooltip.show)
.on('mouseout', tooltip.hide);
var thresholdLine = g.append("line")
.attr("stroke", "black")
.style("stroke-width", "1.5px")
.style("stroke-dasharray", "5,5")
.style("opacity", 1)
.attr("x1", 0)
.attr("y1", y(opts.threshold))
.attr("x2", dims.width)
.attr("y2", y(opts.threshold));
var updateXAxis = function(type, duration) {
if (type === "continuous") {
xAxis.scale(xContinuous);
} else {
xAxis.scale(xDiscrete);
}
d3.select(".x").transition().duration(duration).call(xAxis);
};
var updateYAxis = function(data, duration) {
var extent = d3.extent(data, function(d) {
return d.y;
});
extent[0] = 0;
extent[1] = extent[1] + 0.2*(extent[1] - extent[0]);
y.domain(extent);
d3.select(".y").transition().duration(duration).call(yAxis);
};
var toggle = function(to, duration) {
if (to === "distribution") {
updateYAxis(dataContinuousGroups[0].data.concat(dataContinuousGroups[1].data).concat(dataContinuousGroups[2].data), 0);
updateXAxis("continuous", duration);
areas
.data(dataContinuousGroups)
.transition()
.duration(duration)
.attr("d", function(d) {
var gen = d3.line()
.x(function(p) {
return xContinuous(p.x);
})
.y(function(p) {
return y(p.y);
});
return gen(d.data);
});
thresholdLine
.style("opacity", 0);
g.select(".y.axis")
.style("opacity", 0);
g.select(".y-axis-label")
.style("opacity", 0);
} else {
y.domain([0, 1]);
d3.select(".y").transition().duration(duration).call(yAxis);
updateXAxis("discrete", duration);
areas
.data(dataDiscrete)
.transition()
.duration(duration)
.attr("d", function(d, i) {
let numPts = dataContinuousGroups[i].data.length - 2;
var path = d3.path()
path.moveTo(xDiscrete(d.x), y(0));
for (j=0; j<numPts; j++) {
path.lineTo(xDiscrete(d.x) + j*xDiscrete.bandwidth()/(numPts-1), y(d.y))
}
path.lineTo(xDiscrete(d.x) + xDiscrete.bandwidth(), y(0));
return path.toString();
});
thresholdLine
.transition()
.duration(0)
.delay(duration)
.style("opacity", 1)
.attr("y1", y(opts.threshold))
.attr("y2", y(opts.threshold));
g.select(".y.axis")
.transition()
.duration(0)
.delay(duration)
.style("opacity", 1);
g.select(".y-axis-label")
.transition()
.duration(0)
.delay(duration)
.style("opacity", 1);
}
};
// Add buttons
//container for all buttons
var allButtons = svg.append("g")
.attr("id", "allButtons");
//fontawesome button labels
var labels = ["B", "D"];
//colors for different button states
var defaultColor = "#E0E0E0";
var hoverColor = "#808080";
var pressedColor = "#000000";
//groups for each button (which will hold a rect and text)
var buttonGroups = allButtons.selectAll("g.button")
.data(labels)
.enter()
.append("g")
.attr("class", "button")
.style("cursor", "pointer")
.on("click", function(d, i) {
updateButtonColors(d3.select(this), d3.select(this.parentNode));
d3.select("#numberToggle").text(i + 1);
if (d === "D") {
toggle("distribution", transDuration);
} else {
toggle("discrete", transDuration);
}
})
.on("mouseover", function() {
if (d3.select(this).select("rect").attr("fill") != pressedColor) {
d3.select(this)
.select("rect")
.attr("fill", hoverColor);
}
})
.on("mouseout", function() {
if (d3.select(this).select("rect").attr("fill") != pressedColor) {
d3.select(this)
.select("rect")
.attr("fill", defaultColor);
}
});
var bWidth = 40; //button width
var bHeight = 25; //button height
var bSpace = 10; //space between buttons
var x0 = 20; //x offset
var y0 = 10; //y offset
//adding a rect to each toggle button group
//rx and ry give the rect rounded corner
buttonGroups.append("rect")
.attr("class", "buttonRect")
.attr("width", bWidth)
.attr("height", bHeight)
.attr("x", function(d, i) {
return x0 + (bWidth + bSpace) * i;
})
.attr("y", y0)
.attr("rx", 5) //rx and ry give the buttons rounded corners
.attr("ry", 5)
.attr("fill", defaultColor);
//adding text to each toggle button group, centered
//within the toggle button rect
buttonGroups.append("text")
.attr("class", "buttonText")
.attr("x", function(d, i) {
return x0 + (bWidth + bSpace) * i + bWidth / 2;
})
.attr("y", y0 + bHeight / 2)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "central")
.attr("fill", "white")
.text(function(d) {
return d;
});
function updateButtonColors(button, parent) {
parent.selectAll("rect")
.attr("fill", defaultColor);
button.select("rect")
.attr("fill", pressedColor);
}
toggle("distribution", 0);
setTimeout(() => {
toggle("discrete", transDuration);
}, 1000);
},
resize: function(width, height) {
// TODO: code to re-render the widget with a new size
}
};
}
});

Tooltip coming out from canvas in d3.js

I have list of bars that are being displayed on the canvas and when I hover on the bar their respective values are getting displayed but that value is coming out of canvas at down. So please help and suggest thank you in advance!!
Here is my html file where I have my tooltip implementation
var margin = {
top: 20,
right: 0,
bottom: 80,
left: 40
};
var width = 700 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1);
var yScale = d3.scale.linear().range([height, 0]);
var hAxis = d3.svg.axis().scale(xScale).orient('bottom')
.ticks(4).tickSubdivide(2).tickSize(5, 5, 0)
.tickFormat(d3.time.format("%Y-%m-%d"))
var vAxis = d3.svg.axis().scale(yScale).orient('left');
var tooltip = d3.select('body').append('div')
.style('position', 'absolute')
.style('background', '#f4f4f4')
.style('padding', '5 15px')
.style('border', '1px #333 solid')
.style('border-radius', '5px')
.style('opacity', 'o');
var line = d3.svg.line()
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.value);
})
.interpolate("linear")
.tension(0.9);
function render(filterByDates) {
d3.select('svg').remove();
if (filterByDates) {
selectDate = true;
//tempData = fliterdata;
console.log("before date fliter data", fliterdata);
var date1 = new Date(document.getElementById('field1').value);
var date2 = new Date(document.getElementById('field2').value);
tempData = fliterdata.filter(function(d) {
console.log(date1, date2);
// alert(date1);
return d.date >= date1 && d.date <= date2;
});
console.log("After date tempData", tempData);
}
xScale.domain(tempData.map(function(d) {
return d.date;
}) .sort(function(a, b) {
return a - b;
}
)
);
yScale.domain([0, d3.max(tempData, function(d) {
return +d.value;
})]);
var svg = d3.select('#chart').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 + ")")
.call(hAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg
.append('g')
.attr("class", "yaxis")
.call(vAxis)
if (chartType == 'bar') {
svg
.selectAll(".bar") //makes bar
.data(tempData)
.enter().append("rect")
.attr("class", "bar")
.style("fill", "teal")
.attr("x", function(d) {
return xScale(d.date);
}).attr("width", xScale.rangeBand())
.attr("y", function(d) {
return yScale(d.value);
}).attr("height", function(d) {
console.log("as", d.value);
return height - yScale(d.value);
})
//.text(function(d){return d.value + "%";})
.on('mouseover', function(d) {
tooltip.transition()
.style('opacity', 3)
tooltip.html(d.value)
.style('left', (d3.event.pageX) + 'px')
.style('top', (d3.event.pagey) + 'px')
d3.select(this).style('opacity', 0.5)
}).on('mouseout', function(d) {
tooltip.transition()
.style('opacity', 0)
d3.select(this).style('opacity', 1)
});
}
if (chartType == 'line') {
svg.append("path") // Add the line path.
.data(tempData)
.attr("class", "line")
.attr("d", line(tempData));
}
}
d3.json(jsonURL, function(data) {
myData = data; //data from json in mydata
myData.forEach(function(d) {
d.date = new Date(d.date);
d.date = new Date(d.date + " UTC");
});
console.log( 'mydatajson', myData);
$("#listbox").on("click", function() {
var key = $(this).val();
//console.log("key:", key);
var value = $('#listbox option:selected').text();
selectop = String(key);
selectop= "val0"+selectop;
fliterdata=myData.filter(function(d){
return d[key].slice(3) ==value;
}).map(function(d){
return {date:d.date,value:d[selectop].toString().replace(",",".")};
});
tempData=fliterdata;
if (selectDate)
render(true);
});
});
function selectChartType(type) {
chartType = type;
render(true);
}
</script>

Display Pie chart, Grouped and Stacked bar chart in one page

I want to display two charts in one page.The Pie chart gets displayed but the Grouped and Stacked bar chart is not displaying . I tried to change the Id name in but no luck :( . Will appreciate if anyone helps me with the code correction .
/* Display Matrix Chart ,Pie chart, Grouped and Stacked bar chart in one page */
<apex:page showHeader="false">
<apex:includeScript value="{!URLFOR($Resource.jquery1)}"/>
<apex:includeScript value="{!URLFOR($Resource.D3)}"/>
<apex:includeScript value="{!URLFOR($Resource.nvD3)}"/>
<div id="body" height="50%" width="100px" ></div> // Id for Pie chart
<div id="body1" height="30%" width="90px"></div> // Id for Stacked and Grouped bar chart
<script>
// Matrix Chart starts here
var drawChart = function(divId,matrixReportId) {
$.ajax('/services/data/v29.0/analytics/reports/'+matrixReportId,
{
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', 'Bearer {!$Api.Session_ID}');
},
success: function(response) {
console.log(response);
var chart = nv.models.multiBarChart();
var chartData = [];
document.getElementById(divId).innerHTML = '';
$.each(response.groupingsDown.groupings, function(di, de) {
var values = [];
chartData.push({"key":de.label, "values": values});
$.each(response.groupingsAcross.groupings, function(ai, ae) {
values.push({"x": ae.label, "y": response.factMap[de.key+"!"+ae.key].aggregates[0].value});
});
});
d3.select('#'+divId).datum(chartData).transition().duration(100).call(chart);
window.setTimeout(function(){
drawChart(divId,matrixReportId);
}, 5000);
}
}
);
};
$(document).ready(function(){
drawChart('chart','00O90000005SSHv');
});
// Pie Chart Starts here
var width =250 ,
height = 450,
radius = Math.min(width, height) / 2;
var data = [{"age":"<5","population":2704659},{"age":"14-17","population":2159981},
{"age":"14-17","population":2159981},{"age":"18-24","population":3853788},
{"age":"25-44","population":14106543},{"age":"45-64","population":8819342},
{"age":">65","population":612463}];
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.svg.arc().outerRadius(radius - 10).innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.population; });
var svg = d3.select("#body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
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.age); });
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.age; });
// Grouped and Stacked Bar Chart starts here
var n = 2, // number of layers
m = 10, // number of samples per layer
stack = d3.layout.stack(),
layers = stack(d3.range(n).map(function() { return bumpLayer(m, .1); })),
yGroupMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y; }); }),
yStackMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); });
var margin = {top: 40, right: 10, bottom: 20, left: 10},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.domain(d3.range(m))
.rangeRoundBands([0, width], .08);
var y = d3.scale.linear()
.domain([0, yStackMax])
.range([height, 0]);
var color = d3.scale.linear()
.domain([0, n - 1])
.range(["#aad", "#556"]);
var xAxis = d3.svg.axis()
.scale(x)
.tickSize(0)
.tickPadding(6)
.orient("bottom");
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 + ")");
var layer = svg.selectAll(".layer")
.data(layers)
.enter().append("g")
.attr("class", "layer")
.style("fill", function(d, i) { return color(i); });
var rect = layer.selectAll("rect")
.data(function(d) { return d; })
.enter().append("rect")
.attr("x", function(d) { return x(d.x); })
.attr("y", height)
.attr("width", x.rangeBand())
.attr("height", 0);
rect.transition()
.delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.y0 + d.y); })
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
d3.selectAll("input").on("change", change);
var timeout = setTimeout(function() {
d3.select("input[value=\"grouped\"]").property("checked", true).each(change);
}, 2000);
function change() {
clearTimeout(timeout);
if (this.value === "grouped") transitionGrouped();
else transitionStacked();
}
function transitionGrouped() {
y.domain([0, yGroupMax]);
rect.transition()
.duration(500)
.delay(function(d, i) { return i * 10; })
.attr("x", function(d, i, j) { return x(d.x) + x.rangeBand() / n * j; })
.attr("width", x.rangeBand() / n)
.transition()
.attr("y", function(d) { return y(d.y); })
.attr("height", function(d) { return height - y(d.y); });
}
function transitionStacked() {
y.domain([0, yStackMax]);
rect.transition()
.duration(500)
.delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.y0 + d.y); })
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
.transition()
.attr("x", function(d) { return x(d.x); })
.attr("width", x.rangeBand());
}
// Inspired by Lee Byron's test data generator.
function bumpLayer(n, o) {
function bump(a) {
var x = 1/(.1 + Math.random()),
y = 2*Math.random()-.5,
z = 10/(.1 + Math.random());
for (var i = 0; i < n; i++) {
var w = (i/n- y) * z;
a[i] += x * Math.exp(-w * w);
}
}
var a=[],i;
for (i = 0; i < n; ++i) a[i] = o + o * Math.random();
for (i = 0; i < 5; ++i) bump(a);
return a.map(function(d, i) { return {x: i, y: Math.max(0, d)}; });
}
</script>
<svg id="chart" height="50%" width="500px" ></svg> // Id for Matrix chart
</apex:page>
Thanks in advance
first, as we discussed here (d3 Donut chart does not render), you should position your
<div id="body1" height="30%" width="90px"></div>
above the script.
second, you are missing the # in your second svg-declaration to correctly select the div by its id, it has to be
var svg = d3.select("#body1").append("svg")
you could also think about naming the second svg differently (eg svg2) so you don't override your first svg-variable (in case you want to do something with it later).

Categories

Resources