How can I set intervals between ticks? d3.js - d3.js

For example I have svg container with 800px width and 600px height.
I wand to add a tick every 40px, so it will be 20 ticks on x-coordinate (with numbers from 0 to 20) and 15 ticks on y-coordinate (with numbers from 0 to 15).
here is an image
How can I do it? I use d3.js v5
There is my code (with zooming and dragging):
<!DOCTYPE html>
<meta charset="utf-8">
<style>
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
border: 0;
overflow: hidden;
display: block;
}
.box, .reset, .x, .y, .board {
display: block;
}
.box {
position: relative;
width: 100%;
height: 100%;
}
.reset {
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 20px;
border-right: 1px solid #E5E5E5;
border-bottom: 1px solid #E5E5E5;
background-color: #FCFCFC;
z-index: 100;
}
.x {
position: absolute;
left: 20px;
top: 0;
width: calc(100% - 20px);
height: 20px;
background-color: #FCFCFC;
}
.y {
position: absolute;
left: 0;
top: 20px;
width: 20px;
height: calc(100% - 20px);
background-color: #FCFCFC;
}
.board {
position: absolute;
left: 0;
top: 0;
width: calc(100% - 20px);
height: calc(100% - 20px);
}
#board {
padding-left: 20px;
padding-top: 20px;
}
body {
font: 10px sans-serif;
shape-rendering: crispEdges;
background-color: #E5E5E5;
}
path.domain {
stroke: none;
}
g.tick line {
stroke: #D3D3D3;
stroke-width: 2;
}
g.tick text {
fill: #C4C4C4;
}
</style>
<body>
<div class="box">
<div class="reset"></div>
<div class="x"></div>
<div class="y"></div>
<div class="board"></div>
</div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
function isInteger(num) {
return (num ^ 0) === num;
}
var width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
var height = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
var svg = d3.select(".board").append("svg")
.attr("id", "board")
.attr("width", width - 20)
.attr("height", height - 20)
// .append("g");
var zoom = d3.zoom()
// .scaleExtent([1, 32])
.on("zoom", zoomed);
svg.call(zoom);
x_scale = d3.scaleLinear().domain([0, 20]).range([0, width]);
y_scale = d3.scaleLinear().domain([0, 20]).range([0, height]);
var x_axis = d3.axisTop(x_scale)
.ticks(?) //I dont know what do I have to write
.tickFormat(function(d, i) {
if (isInteger(d)) {
return d;
}
})
.tickSize(5)
var x_axis_group = svg.append("g")
.attr("transform", "translate(20, 0)")
.call(x_axis);
var y_axis = d3.axisLeft(y_scale)
.ticks(?) /I dont know what do I have to write
.tickFormat(function(d, i) {
if (isInteger(d)) {
return d;
}
})
.tickSize(5);
var y_axis_group = svg.append("g")
.attr("transform", "translate(0, 20)")
.call(y_axis);
function zoomed() {
var new_x_scale = d3.event.transform.rescaleX(x_scale);
var new_y_scale = d3.event.transform.rescaleY(y_scale);
x_axis_group.call(x_axis.scale(new_x_scale));
y_axis_group.call(y_axis.scale(new_y_scale));
}
</script>

Related

How to put a legend in a pie chart in d3.js

I have this pie chart created in d3.js and want to put some legend on it. But the is almost all of the documentation i've read so far is only for d3.js version 3 and a lot has changed for v5. Some says that there is already a built in legend maker of d3 which i don't understand how to use it. Please help.
Below is my code snippet of the pie chart:
/** START OF PIE CHART */
var data = [{"region_iso_code":"PH-00","total_up_percentage":97.69},{"region_iso_code":"PH-01","total_up_percentage":99.83},{"region_iso_code":"PH-02","total_up_percentage":97.96},{"region_iso_code":"PH-03","total_up_percentage":99.29},{"region_iso_code":"PH-04","total_up_percentage":98.36},{"region_iso_code":"PH-05","total_up_percentage":98.02},{"region_iso_code":"PH-06","total_up_percentage":96.91},{"region_iso_code":"PH-07","total_up_percentage":99.75},{"region_iso_code":"PH-LAG","total_up_percentage":98.84}]
var svgCirWidth = 600, svgCirHeight = 300, radius = Math.min(svgCirWidth, svgCirHeight) / 2;
const pieContainer = d3.select("#pieChart")
.append("svg")
.attr("width", svgCirWidth)
.attr("height", svgCirHeight);
//create group element to hold pie chart
var g = pieContainer.append("g")
.attr("transform", "translate(" + 250 + "," + radius + ")");
var color = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])
var pie = d3.pie().value(function (d) {
return d.total_up_percentage;
});
var path = d3.arc()
.outerRadius(radius)
.innerRadius(0);
var arc = g.selectAll("arc")
.data(pie(data))
.enter() //means keeps looping in the data
.append("g");
arc.append("path")
.attr("d", path)
.attr("fill", function (d) {
return color(d.data.total_up_percentage);
})
.append("text")
.text("afdaf");
var label = d3.arc()
.outerRadius(radius)
.innerRadius(0);
arc.append("text")
.attr("transform", (d) => {
return "translate(" + label.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.text((d) => {
return d.data.total_up_percentage + "%"
});
/* END OF PIE CHART */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DASHBOARD</title>
<!--Lib css-->
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!--fontawesome-->
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<!--jquery-->
<script src="https://code.jquery.com/jquery-3.5.0.js"
integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>
<!--own css-->
<style>
#import "https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700";
body {
font-family: 'Poppins', sans-serif;
background: #fafafa;
}
p {
font-family: 'Poppins', sans-serif;
font-size: 1.1em;
font-weight: 300;
line-height: 1.7em;
color: #999;
}
a,
a:hover,
a:focus {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
.navbar {
padding: 15px 10px;
background: #fff;
border: none;
border-radius: 0;
margin-bottom: 40px;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
}
.navbar-btn {
box-shadow: none;
outline: none !important;
border: none;
}
/* ---------------------------------------------------
SIDEBAR STYLE
----------------------------------------------------- */
.wrapper {
display: flex;
width: 100%;
align-items: stretch;
}
#sidebar {
min-width: 250px;
max-width: 250px;
background: rgb(60, 95, 238);
color: #fff;
transition: all 0.3s;
}
#sidebar.active {
margin-left: -250px;
}
#sidebar .sidebar-header {
padding: 20px;
background: rgb(90, 121, 243);
}
#sidebar ul.components {
padding: 20px 0;
border-bottom: 1px solid #47748b;
}
#sidebar ul p {
color: #fff;
padding: 10px;
}
#sidebar ul li a {
padding: 10px;
font-size: 1.1em;
display: block;
}
#sidebar ul li a:hover {
color: #7386D5;
background: #fff;
}
#sidebar ul li.active>a,
a[aria-expanded="true"] {
color: #fff;
background: #6d7fcc;
}
a[data-toggle="collapse"] {
position: relative;
}
.dropdown-toggle::after {
display: block;
position: absolute;
top: 50%;
right: 20px;
transform: translateY(-50%);
}
ul ul a {
font-size: 0.9em !important;
padding-left: 30px !important;
background: #6d7fcc;
}
ul.CTAs {
padding: 20px;
}
ul.CTAs a {
text-align: center;
font-size: 0.9em !important;
display: block;
border-radius: 5px;
margin-bottom: 5px;
}
a.download {
background: #fff;
color: #7386D5;
}
a.article,
a.article:hover {
background: #6d7fcc !important;
color: #fff !important;
}
/* ---------------------------------------------------
CONTENT STYLE
----------------------------------------------------- */
#content {
width: 100%;
padding: 20px;
min-height: 100vh;
transition: all 0.3s;
}
/* ---------------------------------------------------
MEDIAQUERIES
----------------------------------------------------- */
#media (max-width: 768px) {
#sidebar {
margin-left: -250px;
}
#sidebar.active {
margin-left: 0;
}
#sidebarCollapse span {
display: none;
}
}
/* ---------------------------------------------------
CHART STYLE
-----------------------------------------------------
/* LINE CHART STYLE */
.axis--x path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
</style>
<!--lib js-->
<!--bootstrap-->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"></script>
<!--fontawesome js-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
<!--d3(chart) js-->
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div class="wrapper">
<!-- Sidebar -->
<nav id="sidebar">
<ul class="list-unstyled components">
<li class="active">
DASHBOARD
</li>
</ul>
<!--End of nav.sidebar-->
</nav>
<!--Page content-->
<div id="content">
<!-- navbar -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<button type="button" id="sidebarCollapse" class="btn btn-info">
<i class="fas fa-align-justify"></i>
</button>
</div>
</nav>
<!--End of div.row-->
<div class="row">
<div class="col-12">
<div class="card shadow mb-5">
<div class="card-body">
<div id="pieChart">
</div>
</div>
</div>
</div>
</div>
<!--End of div.row-->
</div>
</div>
</div>
<!--End of div.wrapper-->
<script src="js/script.js"></script>
</body>
</html>
Just a draft version to answer your question, please make changes and tweak values as per your requirements.
/** START OF PIE CHART */
var data = [{"region_iso_code":"PH-00","total_up_percentage":97.69},{"region_iso_code":"PH-01","total_up_percentage":99.83},{"region_iso_code":"PH-02","total_up_percentage":97.96},{"region_iso_code":"PH-03","total_up_percentage":99.29},{"region_iso_code":"PH-04","total_up_percentage":98.36},{"region_iso_code":"PH-05","total_up_percentage":98.02},{"region_iso_code":"PH-06","total_up_percentage":96.91},{"region_iso_code":"PH-07","total_up_percentage":99.75},{"region_iso_code":"PH-LAG","total_up_percentage":98.84}]
var svgCirWidth = 600, svgCirHeight = 300, radius = Math.min(svgCirWidth, svgCirHeight) / 2;
const pieContainer = d3.select("#pieChart")
.append("svg")
.attr("width", svgCirWidth)
.attr("height", svgCirHeight);
//create group element to hold pie chart
var g = pieContainer.append("g")
.attr("transform", "translate(" + 250 + "," + radius + ")");
var color = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])
var pie = d3.pie().value(function (d) {
return d.total_up_percentage;
});
var path = d3.arc()
.outerRadius(radius)
.innerRadius(0);
var arc = g.selectAll("arc")
.data(pie(data))
.enter() //means keeps looping in the data
.append("g");
arc.append("path")
.attr("d", path)
.attr("fill", function (d) {
return color(d.data.total_up_percentage);
})
.append("text")
.text("afdaf");
var label = d3.arc()
.outerRadius(radius)
.innerRadius(0);
arc.append("text")
.attr("transform", (d) => {
return "translate(" + label.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.text((d) => {
return d.data.total_up_percentage + "%"
});
//console.log(pie(data))
var legendG = g.selectAll(".legend")
.data(pie(data))
.enter()
.append("g")
.attr("transform", function(d,i){
return "translate(" + (-250) + "," + (i * 15 + 20) + ")";
})
.attr("class", "legend");
legendG.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("fill", function(d) {
return color(d.value);
});
legendG.append("text")
.text(function(d){
return d.data.region_iso_code;
})
.style("font-size", 12)
.attr("y", 10)
.attr("x", 11);
/* END OF PIE CHART */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DASHBOARD</title>
<!--Lib css-->
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!--fontawesome-->
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<!--jquery-->
<script src="https://code.jquery.com/jquery-3.5.0.js"
integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>
<!--own css-->
<style>
#import "https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700";
body {
font-family: 'Poppins', sans-serif;
background: #fafafa;
}
p {
font-family: 'Poppins', sans-serif;
font-size: 1.1em;
font-weight: 300;
line-height: 1.7em;
color: #999;
}
a,
a:hover,
a:focus {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
.navbar {
padding: 15px 10px;
background: #fff;
border: none;
border-radius: 0;
margin-bottom: 40px;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
}
.navbar-btn {
box-shadow: none;
outline: none !important;
border: none;
}
/* ---------------------------------------------------
SIDEBAR STYLE
----------------------------------------------------- */
.wrapper {
display: flex;
width: 100%;
align-items: stretch;
}
#sidebar {
min-width: 250px;
max-width: 250px;
background: rgb(60, 95, 238);
color: #fff;
transition: all 0.3s;
}
#sidebar.active {
margin-left: -250px;
}
#sidebar .sidebar-header {
padding: 20px;
background: rgb(90, 121, 243);
}
#sidebar ul.components {
padding: 20px 0;
border-bottom: 1px solid #47748b;
}
#sidebar ul p {
color: #fff;
padding: 10px;
}
#sidebar ul li a {
padding: 10px;
font-size: 1.1em;
display: block;
}
#sidebar ul li a:hover {
color: #7386D5;
background: #fff;
}
#sidebar ul li.active>a,
a[aria-expanded="true"] {
color: #fff;
background: #6d7fcc;
}
a[data-toggle="collapse"] {
position: relative;
}
.dropdown-toggle::after {
display: block;
position: absolute;
top: 50%;
right: 20px;
transform: translateY(-50%);
}
ul ul a {
font-size: 0.9em !important;
padding-left: 30px !important;
background: #6d7fcc;
}
ul.CTAs {
padding: 20px;
}
ul.CTAs a {
text-align: center;
font-size: 0.9em !important;
display: block;
border-radius: 5px;
margin-bottom: 5px;
}
a.download {
background: #fff;
color: #7386D5;
}
a.article,
a.article:hover {
background: #6d7fcc !important;
color: #fff !important;
}
/* ---------------------------------------------------
CONTENT STYLE
----------------------------------------------------- */
#content {
width: 100%;
padding: 20px;
min-height: 100vh;
transition: all 0.3s;
}
/* ---------------------------------------------------
MEDIAQUERIES
----------------------------------------------------- */
#media (max-width: 768px) {
#sidebar {
margin-left: -250px;
}
#sidebar.active {
margin-left: 0;
}
#sidebarCollapse span {
display: none;
}
}
/* ---------------------------------------------------
CHART STYLE
-----------------------------------------------------
/* LINE CHART STYLE */
.axis--x path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
</style>
<!--lib js-->
<!--bootstrap-->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"></script>
<!--fontawesome js-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
<!--d3(chart) js-->
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div class="wrapper">
<!-- Sidebar -->
<nav id="sidebar">
<ul class="list-unstyled components">
<li class="active">
DASHBOARD
</li>
</ul>
<!--End of nav.sidebar-->
</nav>
<!--Page content-->
<div id="content">
<!-- navbar -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<button type="button" id="sidebarCollapse" class="btn btn-info">
<i class="fas fa-align-justify"></i>
</button>
</div>
</nav>
<!--End of div.row-->
<div class="row">
<div class="col-12">
<div class="card shadow mb-5">
<div class="card-body">
<div id="pieChart">
</div>
</div>
</div>
</div>
</div>
<!--End of div.row-->
</div>
</div>
</div>
<!--End of div.wrapper-->
<script src="js/script.js"></script>
</body>
</html>

Pie Chart not rendering in dashboard area using D3 v5

I have been trying to render a simple two value pie chart using D3.JS v5 in the lower right corner to no avail. Can someone please assist me with this - the code can be found here:
Codepen
<body>
<div id = "orgChart"></div>
<div id = "mapChart"></div>
<div id = "pieChart"></div>
<script>
/******************************************************************************
Pie Chart
******************************************************************************/
function makePie() {
var widthPie = (window.innerWidth * 0.3) ,
heightPie = (window.innerHeight * 0.3);
var data = [
{name: "Males", count: 43, percent: 61 }
, {name: "Females", count: 27, percent: 39}
];
var pie = d3.pie().value(d=>d.count).padAngle(0.025)(data);
var arcMkr = d3.arc().innerRadius(20).outerRadius(35)
.cornerRadius(4);
var scC = d3.scaleOrdinal(d3.schemePastel1)
.domain(pie.map(d=>d.index));
var g = d3.select("#pieChart")
.append("g").attr("transform", "translate(widthPie/2, heightPie/2)");
g.selectAll("path.x").data(pie).enter().append("path")
.attr("d", arcMkr)
.attr("fill", d=> scC(d.index)).attr("stroke", "grey");
g.selectAll("text.x" ).data( pie ).enter().append( "text")
.text(d => d.data.name +": " + d.data.percent + "%")
.attr("x", d=>arcMkr.innerRadius(20).centroid(d)[0])
.attr("y", d=>arcMkr.innerRadius(20).centroid(d)[1])
.attr("font-family", "sans-serif").attr( "font-size", 8)
.attr("text-anchor", "middle")
;
}
makePie();
</script>
As #Tom Shanley has indicated in the comments, the reason of why your pie chart is not rendered as expected is because you need to create a SVG first.
Notice that I've also changed some CSS properties of #pieChart for improving the snippet visibility, although it is not necessary for your purposes.
<!DOCTYPE html>
<html lang = 'en'>
<head>
<meta charset = 'utf-8'>
<meta name = 'viewport' content = 'width = device-width, initial-scale = 1.0'>
<meta http-equiv = 'X-UA-Compatible' content = 'ie=edge'>
<meta name = 'author' content = "Tom Bellmer">
<meta name = 'date.created' content="03/05/2020">
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<title>Org Chart</title>
<style>
body{
background-color: #faf2e4;
font-family: sans-serif;
font-size: 1.2em;
}
text{font-size: .6em}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1px;
}
.node text {
font: 9px sans-serif;
font-weight: normal;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1px;
}
#orgChart{
position:absolute;
top: 10px;
left: 10px;
width: 65%;
height: 85%;
}
#mapChart{
position:absolute;
top: 10px;
left: 66%;
width: 34%;
height: 50%;
}
#pieChart{
position:absolute;
top: 51%;
left: 66%;
width: 34%;
height: 55%;
background-color: crimson;
}
circle {
/* fill: #FF8533; */
fill: steelblue;
fill-opacity: .8;
stroke: #fff;
}
circle:hover { fill: red;}
div.tooltip {
position: absolute;
text-align: center;
width: 130px;
height: 14px;
padding: 2px;
font: 11px sans-serif;
background: dodgerblue;
color: white;
border: 0px;
pointer-events: none;
}
svg g{
fill: white;
stroke: black;
}
svg text{fill: black;}
</style>
</head>
<body>
<div id = "orgChart"></div>
<div id = "mapChart"></div>
<div id = "pieChart"></div>
<script>
/******************************************************************************
Pie Chart
******************************************************************************/
function makePie() {
var widthPie = (window.innerWidth * 0.5) ,
heightPie = (window.innerHeight * 0.5);
var data = [
{name: "Males", count: 43, percent: 61 },
{name: "Females", count: 27, percent: 39}
];
var pie = d3.pie().value(d=>d.count).padAngle(0.025)(data);
var arcMkr = d3.arc().innerRadius(20).outerRadius(35)
.cornerRadius(4);
var scC = d3.scaleOrdinal(d3.schemePastel1)
.domain(pie.map(d=>d.index));
// Modified ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var svg = d3.select("#pieChart")
.append("svg")
.attr("width", widthPie)
.attr("height", heightPie);
var g = svg.append("g").attr("transform", `translate(${widthPie/2}, ${heightPie/2})`);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
g.selectAll("path.x").data(pie).enter().append("path")
.attr("d", arcMkr)
.attr("fill", d=> scC(d.index)).attr("stroke", "grey");
g.selectAll("text.x" ).data( pie ).enter().append( "text")
.text(d => d.data.name +": " + d.data.percent + "%")
.attr("x", d=>arcMkr.innerRadius(20).centroid(d)[0])
.attr("y", d=>arcMkr.innerRadius(20).centroid(d)[1])
.attr("font-family", "sans-serif").attr( "font-size", 8)
.attr("text-anchor", "middle");
}
makePie();
</script>
</body>

d3.geo.albersUsa() not function

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Store Location</title>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script src="http://d3js.org/queue.v1.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
.boundary {
fill: none;
stroke: #dfdfdf;
stroke-linejoin: round;
}
#map {
text-align: center;
}
circle {
fill: blue;
opacity:.9;
}
text{
font-family: 'PT Sans', sans-serif;
font-weight: 300;
font-size: 12px;
z-index: 900;
}
#tooltip {
position: absolute;
width: 200px;
height: auto;
padding: 10px;
background-color: #ff9436;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
pointer-events: none;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0;
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
}
</style>
</head>
<body>
<div id="tooltip" >
<p><strong>Store name and address:</strong></p>
<p><span id="value"></span></p>
<svg id="spendChart"></svg>
</div>
<div id="map"></div>
<script>
var height = 600;
var width = 900, centered;
var projection = d3.geo.albersUsa()
.scale(1200)
.translate([width/2, height/2]);
console.log("working..!!!")
var path = d3.geo.path().projection(projection);
var svg = d3.select("#map")
.append("svg")
.attr("width", width)
.attr("height", height);
var map = svg.append("g")
.attr("class", "boundary");
var usa, usData, spendData, locationData;
var monthParser = d3.time.format("%b");
d3.select("#tooltip").classed("hidden", true);
queue()
.defer(d3.json, 'us.json')
.defer(d3.json, 'newstorelocations.json')
.defer(d3.json, 'newstorespend.json')
.await(ready);
function onHover(location) {
var pos = projection([location.lon, location.lat]),
html = location.name +
"<br />located at: <br />" +
location.AddressLine1 +
",<br />" +
location.City +
"<br />" +
location.StateCode;
d3.select("#value").html(html);
d3.select("#tooltip").attr("left", pos[0] + "px").attr("top", pos[1] + "px").classed("hidden", false);
d3.select(this).style("fill", "red");
var locationSpendData = spendData.filter(function(d) { return d.StoreDescription == location.StoreDescription; });
locationSpendData.forEach(function(d) {
d.month = monthParser.parse(d.MonthName);
});
var chartHeight = 150, chartWidth = 200,
x = d3.time.scale().domain(d3.extent(locationSpendData, function(d) { return d.month; }))
.range([0, chartWidth]),
y = d3.scale.linear().domain([0, d3.max(locationSpendData, function(d) { return d.TotalSpend; })])
.range([chartHeight, 0]);
chart = d3.select("svg#spendChart").attr("height", chartHeight)
.attr("width", chartWidth);
chart.selectAll("rect.bar")
.data(locationSpendData)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.month); })
.attr("y", function(d) { return y(d.TotalSpend); })
.attr("width", chartWidth / locationSpendData.length)
.attr("height", function(d) { return height - y(d.TotalSpend); });
}
function offHover() {
d3.select(this).style("fill", "blue");
d3.select("#spendChart").html("");
d3.select("#tooltip").classed("hidden", true);
}
function ready(error, us, locations, spend) {
usData = us;
locationData = locations;
spendData = spend;
usa = map.selectAll('path')
.data(topojson.feature(usData, usData.objects.states).features);
usa.enter()
.append('path')
.attr('d', path)
.attr('fill', 'gray');
svg.selectAll('circle')
.data(locationData)
.enter()
.append('circle')
.attr('cx', function(d) {return projection([d.lon, d.lat])[0]})
.attr('cy', function(d) {return projection([d.lon, d.lat])[1]})
.attr('r', 4)
.on("mouseover", onHover)
.on("mouseout", offHover);
};
</script>
</body>
</html>
i am creating USA map and location of store on it...
but i getting an error as shown in the image that
i added to us.json and to another .json file for location ...
but no output is getting shown in browser.
i am getting error like this.. .
Uncaught TypeError: Cannot read property 'objects' of undefined

D3JS: Unable to append a text element only once

I have this code which generates 9 donuts charts. the thing is that the SVG canvas gets appended so many times to the DOM, as many as donuts charts are drawn, and when I try to place a single text element on the top of the screen (as a big title which explain the graphics), it gets appended 9 times as well (in every SVG canvas which hold each donut). I need to have only one SVG canvas and inside it the 9 donuts, but I'm having a hard time trying to achieve it.
Here's a running snippet of what I have so far.
$("#chartdiv").empty()
var dataObj = {
data1: [19, 81],
data2: [15, 85],
data3: [13, 91],
data4: [8, 92],
data5: [7, 93],
data7: [6, 94],
data8: [5, 95],
data9: [4, 96],
data10: [3, 97],
data11: [2, 98],
data11: [1, 99],
data12: [0, 100],
};
var newarr = ["Manufacturing", "Technology", "Other", "Engineering", "Automotive", "Consulting/professiona services", "Entertaiment and media", "Financial services", "Apparel and textile", "Construction", "Academic and educational", "Legal services"]
var width = 140,
height = 140,
radius = (Math.min(width, height) / 2.8);
function drawDonut(data, divchart, index, chartName) {
var color = ["#00338D", "#dedede"];
var pie = d3.pie()
.sortValues(null)
.value(function(d) {
return d
})(data);
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(radius - (radius / 1.9));
var labelArc = d3.arc()
.outerRadius(radius - 31)
.innerRadius(radius - 31);
var svg = d3.select("#chartdiv")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + 75 + "," + 50 + ")");
var g = svg.selectAll("arc")
.data(pie)
.enter().append("g")
.attr("class", "arc");
function easeInverse(ease) {
return function(e) {
var min = 0,
max = 1;
while (max - min > 1e-3) {
var mid = (max + min) * 0.5;
emid = ease(mid);
if (emid > e) {
max = mid;
} else {
min = mid;
}
}
return max;
}
}
var inverseCubic = easeInverse(d3.easeCubic);
var oneOver2Pi = 1.0 / (2 * Math.PI);
var total_msec = 900;
g.append("path")
.style("fill", function(d, i) {
return color[i];
})
.transition()
.ease(d3.easeLinear)
.delay(function(d) {
return total_msec * inverseCubic(d.startAngle * oneOver2Pi);
})
.duration(function(d) {
return total_msec * (inverseCubic(d.endAngle * oneOver2Pi) - inverseCubic(d.startAngle * oneOver2Pi));
})
.attrTween("d", arcTween);
function arcTween(d) {
var i = d3.interpolate(inverseCubic(d.startAngle * oneOver2Pi), inverseCubic(d.endAngle * oneOver2Pi));
return function(t) {
d.endAngle = 2 * Math.PI * d3.easeCubic(i(t));
return arc(d);
}
}
g.append("text")
.attr("transform", "translate(0,5) scale(1.4)")
.attr("font-weight", "bold")
.attr("class", "st0 donutsTextElemnt")
.attr("font-size", "11px")
.attr("text-anchor", "middle")
.html(data[0] + "%");
svg.append("foreignObject")
.attr("transform", "translate(-30,50) scale(.75)")
.attr("width", 120)
.attr("height", 80)
.attr("class", "caption 3rForeignObj")
.append("xhtml:body")
.html(newarr[index])
.style("background", "white");
var lastDonut = $("#donutdiv").children().eq(6)
lastDonut.css({
'transform': 'translate(0 , 20px)'
});
}
Object.keys(dataObj).forEach(function(d, i) {
drawDonut(dataObj[d], '#pie' + (i + 1), i, 'chart' + (i + 1));
});
body {
background: rgb(92, 29, 186);
height: 100vh;
}
* {
box-sizing: border-box;
}
.list-group-item {
font-size: 24px;
background: inherit;
border: none;
color: #fff!important;
}
/* .action{
font-size: 14px!important;
background: inherit;
border: none;
color:#fff!important;
} */
.list-group-item:hover {
color: black!important;
}
.firstPage {
background: #470a68;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
}
.secondPage {
background: #00A3A1;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
;
-o-transform: translate(-50%, -50%);
;
transform: translate(-50%, -50%);
;
}
.thirdPage {
background: #00A3A1;
}
.fourthPage {
background: #f45f42;
}
.submenuTitle p {
font-size: 30px;
color: #fff;
}
.sectionsTitle {
font-size: 52px!important;
}
.inactive {
display: none;
}
.active {
display: block;
}
#chartdiv {
background: #fff;
}
.chart {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.heightZero {
height: 0;
overflow: hidden
}
#keyframes slideUp {
to {
height: 100%
}
}
.slideUp {
animation: slideUp .6s ease-in forwards;
}
.thirdDonutsDiv {
display: inline
}
a {
font-size: 16px!important;
}
.back {
transform: scale(.7)
}
.container-fluid {
width: 512px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
}
.sectionsTitle {
font-family: KPMG Extralight;
color: white;
font-weight: bold;
}
p.mainTitle {
color: #fff;
font-size: 115px;
font-family: KPMG Extralight;
margin-top: 5px;
}
p.standardP {
color: #fff;
font-family: univers;
font-size: 1.666rem;
line-height: 1.2;
margin: 1rem 1;
margin-top: 30px;
}
h3.mainTitle {
color: #fff;
font-family: KPMG;
margin-top: 14px;
margin-bottom: 14px;
font-size: 3.8rem;
font-weight: bolder;
}
p.standardP {
color: #fff;
font-family: univers;
font-size: 1.666rem;
line-height: 1.2;
margin: 1rem 1;
margin-top: 30px;
}
ul {
list-style-type: none;
padding: 0;
margin-right: 10px;
margin-left: 10px;
}
label {
width: 100%;
height: 100%;
padding: 0.85rem 1rem;
background-color: hsla(0, 0%, 100%, 0);
color: #fff;
cursor: pointer;
border-radius: 4px;
margin-bottom: 11px;
transition: all .4s;
font-size: 16px;
font-weight: normal;
}
label:hover {
background-color: white;
color: #000;
transition: background-color .2s
}
.labelUnselected {
background-color: hsla(0, 0%, 100%, .6);
color: #fff;
}
div.mainDiv p {
word-wrap: break-word;
line-height: 100%;
}
input {
display: none;
}
.backSubMenu1 {
text-align: center;
}
/* donut chart 4*/
.st0 {
fill: #00338D;
}
#fourtySeven {
transform: translate(50px, 0px)
}
#twentyEight {
transform: translate(-63.104974985120286px, 86.28081103480314px)
}
.icon2 {
opacity: 0;
animation: fadeIn 1s linear 1.5s forwards;
transform: translate(-50px, -45px)
}
#keyframes fadeIn {
to {
opacity: 1;
}
}
.rect {
opacity: 0;
animation: fadeIn 1.3s linear 1.5s forwards;
}
#keyframes fadeIn {
to {
opacity: 1;
}
}
.ifram {
width: 512px;
}
.iconXY {
opacity: 0;
animation: fadeIn 1.5s linear 1.8s forwards;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<div class="row">
<div class="col-sm-12" id="chartdiv"></div>
<div class="text-left backSubMenu1">
<i class="fas fa-chevron-left back" style="font-size: 40px;color:aliceblue" targetX="secondPage">
</i>
</div>
<div id="pie1" class="thirdDonutsDiv"></div>
<div id="pie2" class="thirdDonutsDiv"></div>
<div id="pie3" class="thirdDonutsDiv"></div>
<div id="pie4" class="thirdDonutsDiv"></div>
<div id="pie5" class="thirdDonutsDiv"></div>
<div id="pie6" class="thirdDonutsDiv"></div>
<div id="pie7" class="thirdDonutsDiv"></div>
<div id="pie8" class="thirdDonutsDiv"></div>
<div id="pie9" class="thirdDonutsDiv"></div>
</div>
Here's a more d3ish refactor that achieves your goal of one SVG containing all pie charts:
<!DOCTYPE html>
<html>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<div class="row">
<div class="col-sm-12" id="chartdiv">
</div>
</div>
<script>
var dataObj = {
data1: [19, 81],
data2: [15, 85],
data3: [13, 91],
data4: [8, 92],
data5: [7, 93],
data7: [6, 94],
data8: [5, 95],
data9: [4, 96],
data10: [3, 97],
data11: [2, 98],
data11: [1, 99],
data12: [0, 100],
};
var newarr = ["Manufacturing", "Technology", "Other", "Engineering", "Automotive", "Consulting/professiona services", "Entertaiment and media", "Financial services", "Apparel and textile", "Construction", "Academic and educational", "Legal services"]
var width = 140,
height = 140,
radius = (Math.min(width, height) / 2.8),
numCol = 4;
var svg = d3.select("#chartdiv")
.append("svg")
.attr("width", width * numCol)
.attr("height", height * (newarr.length / numCol));
svg.selectAll(".donut")
.data(d3.values(dataObj))
.enter()
.append("g")
.attr("class", "donut")
.each(drawDonut);
function drawDonut(data, index) {
var color = ["#00338D", "#dedede"];
var pie = d3.pie()
.sortValues(null)
.value(function(d) {
return d
})(data);
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(radius - (radius / 1.9));
var labelArc = d3.arc()
.outerRadius(radius - 31)
.innerRadius(radius - 31);
var xPos = 75 + ((index % numCol) * width),
yPos = 50 + (Math.floor(index / numCol) * height);
var group = svg
.append("g")
.attr("transform", "translate(" + xPos + "," + yPos + ")");
var g = group.selectAll("arc")
.data(pie)
.enter().append("g")
.attr("class", "arc");
function easeInverse(ease) {
return function(e) {
var min = 0,
max = 1;
while (max - min > 1e-3) {
var mid = (max + min) * 0.5;
emid = ease(mid);
if (emid > e) {
max = mid;
} else {
min = mid;
}
}
return max;
}
}
var inverseCubic = easeInverse(d3.easeCubic);
var oneOver2Pi = 1.0 / (2 * Math.PI);
var total_msec = 900;
g.append("path")
.style("fill", function(d, i) {
return color[i];
})
.transition()
.ease(d3.easeLinear)
.delay(function(d) {
return total_msec * inverseCubic(d.startAngle * oneOver2Pi);
})
.duration(function(d) {
return total_msec * (inverseCubic(d.endAngle * oneOver2Pi) - inverseCubic(d.startAngle * oneOver2Pi));
})
.attrTween("d", arcTween);
function arcTween(d) {
var i = d3.interpolate(inverseCubic(d.startAngle * oneOver2Pi), inverseCubic(d.endAngle * oneOver2Pi));
return function(t) {
d.endAngle = 2 * Math.PI * d3.easeCubic(i(t));
return arc(d);
}
}
g.append("text")
.attr("transform", "translate(0,5) scale(1.4)")
.attr("font-weight", "bold")
.attr("class", "st0 donutsTextElemnt")
.attr("font-size", "11px")
.attr("text-anchor", "middle")
.html(data[0] + "%");
svg.append("text")
.attr("transform", "translate(" + (xPos) + "," + (yPos + height / 2.4) + ") scale(.75)")
.attr("text-anchor", "middle")
.text(newarr[index]);
}
</script>
</body>
</html>

Fix tooltips on horizontal bar chart d3.js

I want to make a similar tooltip like this example but in my chart the tooltips do not show at the end of each bar. I was trying to fix it by adjusting offset([-10, 350]). I can see the tooltips moved but not all of them appear at the end. Anyone can tell me how to fix it? Thanks a lot!
<!DOCTYPE html>
<html>
<style>
.axis {
font-family: Helvetica;
font-size: 1em;
font-weight: bold;
color: #444444;
}
.axis path,
.axis line {
fill: none;
stroke: white;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.bar:hover {
opacity: 0.7;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: #aaaaaa;
color: #aa123f;
border-radius: 6px;
font-family: Helvetica;
}
/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: #aaaaaa;
content: "\25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
</style>
<head>
<!-- D3.js -->
<script src='http://d3js.org/d3.v3.min.js'></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
</head>
<body>
<div id="barChart"></div>
<script>
var data = [
{y:"Group1", x: 3.5},
{y:"Group2", x: 4.5},
{y:"Group3", x: 3.8}
];
var margin = {top: 40, right: 20, bottom: 30, left: 80},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.
linear().
range([0, width]);
var y = d3.scale.
ordinal().
rangeRoundBands([0, height], 0.3);
var xAxis = d3.
svg.
axis().
scale(x).
orient("bottom");
var yAxis = d3.svg.axis().
scale(y).
orient("left");
x.domain([1, 5]);
y.domain(data.map(function(d) { return d.y; }));
var tipBars = d3.tip().
attr('class', 'd3-tip').
offset([-10, 350]).
html(function(d) {
return '<strong style="color:grey">Result:</strong> <span style="color:grey">' + d.x +
'</span>';
});
var svg = d3.select("#barChart").
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 plot = svg.
append("g").
attr('transform', 'translate(' + 0 + ',' + 0 + ')');
var plotBars = plot.selectAll("g").
data(data).
enter().
append("g").
attr('class', 'bars');
svg.call(tipBars);
var bars = plotBars.
append("rect").
attr("x", function(d) { return 0; }).
attr("width",function(d) { return x(d.x);}).
attr("y", function(d) { return y(d.y);}).
attr("height", y.rangeBand()).
attr("class", "bar").
attr("fill","grey").
on('mouseover', tipBars.show).
on('mouseout', tipBars.hide);
svg.append("g").
attr("class", "x axis").
style('font-family', ' Helvetica').
call(xAxis);
svg.append("g").
attr("class", "y axis").
style('font-family', ' Helvetica').
call(yAxis);
</script>
</body>
</html>
Use d3.tip.direction() to set the positioning. Docs
var tipBars = d3.tip()
.attr('class', 'd3-tip')
.direction('e')
.html(function(d) {
return '<strong style="color:grey">Result:</strong> <span style="color:grey">' + d.x +
'</span>';
});

Resources