Built with blockbuilder.org
Last active
November 7, 2019 11:36
-
-
Save Kashif1Naqvi/f287f5b4e49bb9f9b3e8da5e13ab683b to your computer and use it in GitHub Desktop.
Donut Chart(Budget Planner)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const dim = { width:500 , height: 340, radius:150 } | |
const cent = {x:dim.width/2 + 5 , y:dim.height/2 + 5 } | |
const svg = d3.select(".canvas").append("svg").attr("height",dim.height+150).attr("width",dim.width+150) | |
const graph = svg.append("g").attr("transform",`translate(${cent.x},${cent.y})`) | |
const color = d3.scaleOrdinal(d3['schemeSet3']) | |
const pie = d3.pie().sort(null).value(d=>d.cost) | |
const arcPath = d3.arc().outerRadius(dim.radius).innerRadius(dim.radius/2) | |
const legendGroup = svg.append("g").attr("transform",`translate(${cent.x + 190},${cent.y-101})`) | |
const legend = d3.legendColor() | |
.shape("circle") | |
.shapePadding(10) | |
.scale(color); | |
const tip = d3.tip() | |
.attr("class","tip card") | |
.html(d=>{ | |
let content = `<div class="name" >${d.data.name}</div>` | |
content += `<div class="cost">${d.data.cost}</div>` | |
content += `<div class="text-info">Click slice to delete</div>` | |
return content; | |
}) | |
graph.call(tip) | |
var data = [] | |
const update = (data) => { | |
color.domain(data.map(d => d.name)) | |
legendGroup.call(legend).style("fill","#fff").style("font-weight","bold") | |
const path = graph.selectAll("path").data(pie(data)) | |
path.exit().transition().duration(750).attrTween("d",arcTweenExit) | |
.remove() | |
path.attr("d",arcPath) | |
.enter() | |
.append("path") | |
.attr("stroke","#fff") | |
.attr("stroke-width",1) | |
.attr("fill", d => color(d.data.name)) | |
graph.selectAll("path") | |
.on("mouseover",(d,i,n)=>{ | |
tip.show(d,n[i]) | |
handleMouseOver(d,i,n) | |
}) | |
.on("mouseout",(d,i,n)=>{ | |
tip.hide() | |
handleMouseOut(d,i,n) | |
}) | |
.on("click",handleClick) | |
.transition() | |
.duration(750) | |
.attrTween("d",arcTweenEnter) | |
} | |
db.collection("expenses").onSnapshot(res=>{ | |
console.log(res); | |
res.docChanges().map(change=>{ | |
let doc = {...change.doc.data(), id: change.doc.id} | |
switch (change.type) { | |
case 'added': | |
data.push(doc) | |
break; | |
case 'modified': | |
let index = data.findIndex(item => item.id == doc.id ); | |
data[index] = doc; | |
break; | |
case "removed": | |
data = data.filter(item => item.id !== doc.id) | |
break; | |
default: | |
break; | |
} | |
}) | |
update(data) | |
}) | |
const arcTweenEnter = (d) => { | |
let i = d3.interpolate(d.endAngle , d.startAngle); | |
return function(t){ | |
d.startAngle = i(t) | |
return arcPath(d) | |
} | |
} | |
const arcTweenExit = (d) => { | |
let i = d3.interpolate(d.startAngle , d.endAngle); | |
return function(t){ | |
d.startAngle = i(t) | |
return arcPath(d) | |
} | |
} | |
const handleMouseOver = (d,i,n)=>{ | |
d3.select(n[i]).transition("changeSliceFill").duration(400).attr("fill","white") | |
} | |
const handleMouseOut = (d,i,n)=>{ | |
d3.select(n[i]).transition("changeSliceFill").duration(400).attr("fill",color(d.data.name)) | |
} | |
const handleClick = (d) =>{ | |
console.log(d.data.id); | |
let id = d.data.id | |
db.collection("expenses").doc(id).delete() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en" dir="ltr"> | |
<head> | |
<meta charset="utf-8"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> | |
<title>Dont charset</title> | |
</head> | |
<body class="bg-dark" > | |
<style> | |
.text-line { | |
background-color: transparent; | |
color: #000; | |
outline: none; | |
outline-style: none; | |
border-top: none; | |
border-left: none; | |
border-right: none; | |
border-bottom: solid #eeeddd 2px; | |
padding: 13px 13px; | |
} | |
.tip { | |
pointer-events:none; | |
position:absolute; | |
margin:1px; | |
padding-bottom: : 5px; | |
opacity: .9; | |
padding:0px; | |
background: none repeat scroll 0 white; | |
border:solid none; | |
box-shadow: 0px 3px 15px #888888; | |
color:#8f8e8c; | |
font: 14px sans-serif; | |
width:100px; | |
height:inherit; | |
text-align: center; | |
font-weight: normal; | |
border-radius: 3px; | |
/* font-family: 'Staatliches', cursive; */ | |
font-family: 'Liu Jian Mao Cao', cursive; | |
font-family: 'Courgette', cursive; | |
} | |
.tip ::after { | |
content: ""; | |
position: absolute; | |
top: 100%; | |
left: 80%; | |
margin-left:-35px; | |
border-width:10px; | |
border-style: solid; | |
border-color: white transparent transparent transparent; | |
} | |
</style> | |
<div class="container" > | |
<header class="bg-light" > | |
<h2 class="text-center p-4" >Tracker</h2> | |
<p class="text-center p-4" >Monthly Money Tracker</p> | |
</header> | |
<div class="row"> | |
<div class="col-12 col-sm-6 col-lg-6 col-md-6 col-xl-6"> | |
<form class="card p-3 m-4" > | |
<div class="card-body" > | |
<div class="form-group" > | |
<label for="name"></label> | |
<input type="text" class="text-line" placeholder="Name" id="name"> | |
</div> | |
<div class="form-group"> | |
<label for="cost"></label> | |
<input type="text" id="cost" class="text-line" placeholder="Cost" > | |
</div> | |
<p id="error" class="alert-danger mt-3"></p> | |
<input type="submit" value="Add item" class="btn btn-danger float-right " style="border-style:dashed;" > | |
</div> | |
</form> | |
</div> | |
<div class="col-12 col-sm-6 col-lg-6 col-md-6 col-xl-6"> | |
<div class="canvas" ></div> | |
</div> | |
</div> | |
</div> | |
<!-- The core Firebase JS SDK is always required and must be listed first --> | |
<script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-app.js"></script> | |
<script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-firestore.js"></script> | |
<!-- TODO: Add SDKs for Firebase products that you want to use | |
https://firebase.google.com/docs/web/setup#available-libraries --> | |
<script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-analytics.js"></script> | |
<script> | |
// Your web app's Firebase configuration | |
var firebaseConfig = { | |
apiKey: "AIzaSyCrJwDOd-Fu8R9i2NFTuk3adl49_5bdMME", | |
authDomain: "d3-firebase-1c3d6.firebaseapp.com", | |
databaseURL: "https://d3-firebase-1c3d6.firebaseio.com", | |
projectId: "d3-firebase-1c3d6", | |
storageBucket: "d3-firebase-1c3d6.appspot.com", | |
messagingSenderId: "776696333178", | |
appId: "1:776696333178:web:04004dafee1c4dace4ccc3", | |
measurementId: "G-9X0E1CZWNF" | |
}; | |
// Initialize Firebase | |
firebase.initializeApp(firebaseConfig); | |
firebase.analytics(); | |
let db = firebase.firestore() | |
</script> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.min.js" ></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3-tip.min.js"></script> | |
<script src="index.js" ></script> | |
<script src="graph.js" ></script> | |
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let form = document.querySelector("form") | |
let name = document.querySelector("#name") | |
let cost = document.querySelector("#cost") | |
let error = document.querySelector("#error") | |
form.addEventListener("submit",(e)=>{ | |
e.preventDefault(); | |
if(name.value && cost.value ){ | |
let item = { | |
name : name.value, | |
cost: parseInt(cost.value) | |
} | |
db.collection('expenses').add(item).then(res=>{ | |
name.value = "" | |
cost.value = "" | |
error.textContent = "" | |
} | |
) | |
}else{ | |
error.textContent = "Please enter values before submitting" | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment