How to put a legend in a pie chart in d3.js - 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>

Related

Call to a member function get_cellmap() on null in barryvdh/laravel-dompdf

I am using laravel version 9 for doing my project. and there is a feature that needs to let the user export the event ticket. I try to use the package barryvdh/laravel-dompdf . right now I encounter the error of
Call a member function get_cellmap() on null
I tried to read others' posts with a similar issue, but I found out most of them are using the for the view so seems like the solution working for them is not appropriate for me.here is my code :
controller
public function GenerateTicket($id)
{
$tickets = GiftGivingBeneficiaries::where('gift_giving_id', $id)->get();
# Retrieve the last batch no. from the gift giving.
$batch_no = GiftGiving::findOrFail($id)->batch_no;
GiftGiving::findOrFail($id)->update([
'last_downloaded_by' => Auth::id(),
'batch_no' => $batch_no + 1,
]);
$pdf = PDF::loadView('charity.gifts.generate_ticket', compact('tickets'));
return $pdf->download('event_tickets.pdf');
}
View Page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- This file has been downloaded from bootdey.com #bootdey on twitter -->
<!-- All snippets are MIT license http://bootdey.com/license -->
<title>Genearate Ticket</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<section class="container">
<h1>Event Tickets</h1>
#foreach ($tickets as $key=> $ticket)
<table>
</table>
<div class="row">
<input type="hidden" value="{{$key + 1}} ">
<article class="card fl-left">
<section class="date">
<time datetime="23th feb">
<span>Ticket No.</span><br>
<span>{{ $ticket->ticket_no }}</span>
</time>
</section>
<section class="card-cont">
<small>Event Name:{{ $ticket->GiftGiving->name }}</small>
<h3>{{ $ticket->name }}</h3>
<div class="even-date">
<i class="fa fa-calendar"></i>
<time>
<span>{{ $ticket->GiftGiving->start_at }}</span>
</time>
</div>
<div class="even-info">
<i class="fa fa-map-marker"></i>
<p>
{{ $ticket->GiftGiving->venue }}
</p>
</div>
Batch No.{{ $ticket->GiftGiving->batch_no }}
</section>
</article>
</div>
#if ( $key == 5 )
<div style="page-break-before:always;"> </div>
#endif
#endforeach
</div>
<style type="text/css">
#import url('https://fonts.googleapis.com/css?family=Oswald');
* {
margin: 0;
padding: 0;
border: 0;
box-sizing: border-box
}
body {
background-color: #dadde6;
font-family: arial
}
.fl-left {
float: left
}
.fl-right {
float: right
}
h1 {
text-transform: uppercase;
font-weight: 900;
border-left: 10px solid #fec500;
padding-left: 10px;
margin-bottom: 30px
}
.row {
overflow: hidden
}
.card {
display: table-row;
width: 100%;
background-color: #fff;
color: #989898;
margin-bottom:20px;
font-family: 'Oswald', sans-serif;
text-transform: uppercase;
border-radius: 4px;
position: relative;
border: #2b2b2b 1px solid;
}
.card+.card {
margin-left: 2%
}
.date {
display: table-cell;
width: 45%;
position: relative;
text-align: center;
border-right: 2px dashed #dadde6
}
.date:before,
.date:after {
content: "";
display: block;
width: 30px;
height: 30px;
background-color: #DADDE6;
position: absolute;
top: -15px;
right: -15px;
z-index: 1;
border-radius: 50%
}
.date:after {
top: auto;
bottom: -15px
}
.date time {
display: block;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%)
}
.date time span {
display: block
}
.date time span:first-child {
color: #2b2b2b;
font-weight: 600;
font-size: 150%
}
.date time span:last-child {
text-transform: uppercase;
font-weight: 600;
margin-top: -10px
}
.card-cont {
display: table-cell;
width: 75%;
font-size: 100%;
padding: 10px 10px 30px 50px
}
.card-cont h3 {
color: #3C3C3C;
font-size: 130%
}
.row:last-child .card:last-of-type .card-cont h3 {
text-decoration: line-through
}
.card-cont>div {
display: table-row
}
.card-cont .even-date i,
.card-cont .even-info i,
.card-cont .even-date time,
.card-cont .even-info p {
display: table-cell
}
.card-cont .even-date i,
.card-cont .even-info i {
padding: 5% 5% 0 0
}
.card-cont .even-info p {
padding: 30px 50px 0 0
}
.card-cont .even-date time span {
display: block
}
.card-cont a {
display: block;
text-decoration: none;
width: 80px;
height: 30px;
background-color: #D8DDE0;
color: #fff;
text-align: center;
line-height: 30px;
border-radius: 2px;
position: absolute;
right: 10px;
bottom: 10px
}
.row:last-child .card:first-child .card-cont a {
background-color: #037FDD
}
.row:last-child .card:last-child .card-cont a {
background-color: #F8504C
}
#media screen and (max-width: 860px) {
.card {
display: block;
float: none;
width: 50%;
margin-bottom: 10px
}
.card+.card {
margin-left: 0
}
.card-cont .even-date,
.card-cont .even-info {
font-size: 75%
}
}
.page-break {
page-break-after: always;
}
</style>
<script type="text/javascript">
</script>
</body>
</html>
also, this is what my view looks like. Hope to know what part did I miss for it,every answer is highly appreciated.
Not sure if this will help but the way I execute this in my app is like so:
Maybe try storing it first then accessing it? Then delete them after 1 hour?
$pdf = PDF::setOptions(['isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true])->loadView('charity.gifts.generate_ticket', compact('tickets'));
$pdf->setPaper('a4', 'landscape');
Storage::disk('reports')->put('tickets'. '.pdf', $pdf->output());
$url = Storage::disk('reports')->url('tickets'. '.pdf');

Scrolling SVG Line Drawing - svg not animating

My svg line will not amimate. I have put the svg and javascript in a codepen and it worked well. But in my html file the line won't appear and no line is drawn on the page on my local machine. Why is my javascript not running? Any help is appreciated. Am a newbie to javascript. it works fine in the snippet attached
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght#300;700&display=swap" rel="stylesheet">
<title>Your Website</title>
<style>
body {
background-color: #F0EDE7;
font-family: 'Inter', sans-serif;
margin: 0;
}
nav {
padding: 0 72px;
}
nav ul {
display: flex;
padding: 0;
align-items: flex-end;
}
nav ul li{
text-decoration: none;
list-style: none;
font-weight: 700;
padding-right: 4%;
font-size: 1.414rem;
}
nav ul svg {
height: 72px;
margin-right: 2%;
}
#journey-line {
position: absolute;
right: 8%;
width: 40%;
top: 0;
display: flex;
}
.intro {
display: flex;
width: 60%;
height: 84vh;
align-items: center;
padding: 0px 72px;
}
.intro__content {
}
h1 {
font-size: 5.653rem;
margin: 0;
}
p {
font-size: 1.999rem;
margin: 24px 0 0 0;
}
</style>
</head>
<body>
<figure id ="journey-line" >
<svg viewBox="0 0 830.17 1768.03" preserveAspectRatio="xMidYMid meet">
<path d="M680.84,0V904.51c0,55.23-44.77,100-100,100H250.42c-121.5,0-220,98.5-220,220l-.42,543.5" style="fill: none; stroke: #F0B8A3; stroke-miterlimit: 10; stroke-width: 60px;"/>
</svg>
</figure>
<section class="intro">
<artticle class="intro__content">
<h1>Title</h1>
<p>paragraph</p>
</artticle>
</section>
<script>
let path = document.querySelector("path");
let pathLength = path.getTotalLength();
path.style.strokeDasharray = pathLength + " " + pathLength;
path.style.strokeDashoffset = pathLength;
window.addEventListener("scroll", () => {
var scrollPercentage =
(document.documentElement.scrollTop + document.body.scrollTop) /
(document.documentElement.scrollHeight -
document.documentElement.clientHeight);
// Length to offset the dashes
var drawLength = pathLength * scrollPercentage;
// Draw reverse
path.style.strokeDashoffset = pathLength - drawLength;
})
</script>
</body>
</html>

Menu items don't show on large screens (pure.css)

This is pure.css framework (https://purecss.io/). I'm trying to copy a menu from their examples.
Documentation (and a working example): https://purecss.io/layouts/tucked-menu-vertical/
html
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://unpkg.com/purecss#2.0.3/build/pure-min.css" integrity="sha384-cg6SkqEOCV1NbJoCu11+bm0NvBRc8IYLRGXkmNrqUBfTjmMYwNKPWBTIKyw9mHNJ" crossorigin="anonymous">
<link rel="stylesheet" href="src/css/custom.css">
<title>Hello, world!</title>
</head>
<body>
<div class="custom-wrapper pure-g" id="menu">
<div class="pure-u-1 pure-u-md-1-3">
<div class="pure-menu">
Brand
<s class="bar"></s><s class="bar"></s>
</div>
</div>
<div class="pure-u-1 pure-u-md-1-3">
<div class="pure-menu pure-menu-horizontal custom-can-transform">
<ul class="pure-menu-list">
<li class="pure-menu-item">Home</li>
<li class="pure-menu-item">About</li>
<li class="pure-menu-item">Contact</li>
</ul>
</div>
</div>
<div class="pure-u-1 pure-u-md-1-3">
<div class="pure-menu pure-menu-horizontal custom-menu-3 custom-can-transform">
<ul class="pure-menu-list">
<li class="pure-menu-item">Yahoo</li>
<li class="pure-menu-item">W3C</li>
</ul>
</div>
</div>
</div>
<script type="text/javascript" src="src/js/main.js"></script>
</body>
</html>
css
.custom-wrapper {
background-color: #ffd390;
margin-bottom: 1em;
-webkit-font-smoothing: antialiased;
height: 2.1em;
overflow: hidden;
-webkit-transition: height 0.5s;
transition: height 0.5s;
}
.custom-wrapper.open {
height: 14em;
}
.custom-menu-3 {
text-align: right;
}
.custom-toggle {
width: 34px;
height: 34px;
position: absolute;
top: 0;
right: 0;
display: none;
}
.custom-toggle .bar {
background-color: #777;
display: block;
width: 20px;
height: 2px;
border-radius: 100px;
position: absolute;
top: 18px;
right: 7px;
-webkit-transition: all 0.5s;
transition: all 0.5s;
}
.custom-toggle .bar:first-child {
-webkit-transform: translateY(-6px);
transform: translateY(-6px);
}
.custom-toggle.x .bar {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.custom-toggle.x .bar:first-child {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
#media (max-width: 47.999em) {
.custom-menu-3 {
text-align: left;
}
.custom-toggle {
display: block;
}
}
/*# sourceMappingURL=custom.css.map */
JS
(function (window, document) {
var menu = document.getElementById('menu'),
rollback,
WINDOW_CHANGE_EVENT = ('onorientationchange' in window) ? 'orientationchange':'resize';
function toggleHorizontal() {
menu.classList.remove('closing');
[].forEach.call(
document.getElementById('menu').querySelectorAll('.custom-can-transform'),
function(el){
el.classList.toggle('pure-menu-horizontal');
}
);
};
function toggleMenu() {
// set timeout so that the panel has a chance to roll up
// before the menu switches states
if (menu.classList.contains('open')) {
menu.classList.add('closing');
rollBack = setTimeout(toggleHorizontal, 500);
}
else {
if (menu.classList.contains('closing')) {
clearTimeout(rollBack);
} else {
toggleHorizontal();
}
}
menu.classList.toggle('open');
document.getElementById('toggle').classList.toggle('x');
};
function closeMenu() {
if (menu.classList.contains('open')) {
toggleMenu();
}
}
document.getElementById('toggle').addEventListener('click', function (e) {
toggleMenu();
e.preventDefault();
});
window.addEventListener(WINDOW_CHANGE_EVENT, closeMenu);
})(this, this.document);
Codepen: https://codepen.io/Kifsif/pen/xxwMQpd
The problem is that menu items on large screens are not shown.
Remove overflow: hidden; property from custom-wrapper class and it will be shown. Although I am not sure if menu on large screen is positioned well but that is another problem.
.custom-wrapper {
background-color: #ffd390;
margin-bottom: 1em;
-webkit-font-smoothing: antialiased;
height: 2.1em;
-webkit-transition: height 0.5s;
transition: height 0.5s;
}

Kendo UI DataSource JSONP external callback function name Not Working

I put my callback call directly in the kendo datasource example and I am unable to get this to render. What am I missing?
The datasource will not load and I keep getting a type error. Any help would be appreciated.
This is the code that I entered into a kendo dojo.
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/datasource/remote-data-binding">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2015.2.805/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2015.2.805/styles/kendo.material.min.css" />
<script src="//kendo.cdn.telerik.com/2015.2.805/js/jquery.min.js"></script>
<script src="//kendo.cdn.telerik.com/2015.2.805/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example" class="k-content">
<div class="demo-section k-header wide">
<div id="products"></div>
</div>
<script type="text/x-kendo-template" id="template">
<div class="product">
<img src="../content/web/foods/#= ImageURL #.jpg" alt="#: ProductName # image" />
<h3>#:Description#</h3>
<p>#:kendo.toString(CurPrice, "c")#</p>
</div>
</script>
<script>
$(function() {
var template = kendo.template($("#template").html());
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "//justclickzmedia.net/Search/Get/?callback=callback&query=coach+handbag",
dataType: "jsonp"
}
},
requestStart: function() {
kendo.ui.progress($("#products"), true);
},
requestEnd: function() {
kendo.ui.progress($("#products"), false);
},
change: function() {
$("#products").html(kendo.render(template, this.view()));
}
});
dataSource.read();
});
</script>
<style>
#products {
padding: 10px;
margin-bottom: -1px;
/* height: 510px;
overflow: auto;*/
}
.product {
float: left;
position: relative;
width: 111px;
height: 170px;
margin: 0;
padding: 0;
}
.product img {
width: 110px;
height: 110px;
}
.product h3 {
margin: 0;
padding: 3px 5px 0 0;
max-width: 96px;
overflow: hidden;
line-height: 1.1em;
font-size: .9em;
font-weight: normal;
text-transform: uppercase;
color: #999;
}
.product p {
visibility: hidden;
}
.product:hover p {
visibility: visible;
position: absolute;
width: 110px;
height: 110px;
top: 0;
margin: 0;
padding: 0;
line-height: 110px;
vertical-align: middle;
text-align: center;
color: #fff;
background-color: rgba(0,0,0,0.75);
transition: background .2s linear, color .2s linear;
-moz-transition: background .2s linear, color .2s linear;
-webkit-transition: background .2s linear, color .2s linear;
-o-transition: background .2s linear, color .2s linear;
}
.k-listview:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
</style>
</div>
</body>
</html>
This isn't an answer for the OP but in case someone comes here getting "TypeError - kendo.data.DataSource is not a constructor." check to see if you're accidentally including kendo.core.min.js instead of kendo.ui.core.min.js

Cartodb torque map. Adding additional layers

Would appreciate any help with adding a second layer to my torque map in cartodb using createlayer. Sorry I'm obviously just learning and know just enough to be dangerous the following is a bootstrap page I'm messing with. Zombie Outbreak ;) Thanks in advance....
<!DOCTYPE html>
<html>
<head>
<title>OUTBREAK</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link rel="shortcut icon" href="img/tecKEY.ico">
<link href='http://fonts.googleapis.com/css?family=Share+Tech+Mono' rel='stylesheet' type='text/css'>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="style.css">
<!-- Map takes up full browser window -->
<link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/3.14/themes/css/cartodb.css" />
<style type="cartocss/text" id="cartocss">
/** torque visualization */
Map {
-torque-frame-count:303;
-torque-animation-duration:30;
-torque-time-attribute:"permit_dat";
-torque-aggregation-function:"count(tot_assess)";
-torque-resolution:3;
-torque-data-aggregation:cumulative;
}
#sfr_master2{
comp-op: lighter;
marker-fill-opacity: 0.9;
marker-line-color: #FFF;
marker-line-width: 0;
marker-line-opacity: 1;
marker-type: ellipse;
marker-width: 6;
marker-fill: #ff5c00;
[value < 12] { /* if 6 <= value < 12, color the marker red */
marker-fill: #FF5C00;
}
[value < 6 ] { /* if 3 <= value < 6, color the marker purple */
marker-fill: #FF5C00;
}
[value < 3 ] { /* if value < 3, color the marker blue */
marker-fill: #FF5C00;
}
}
#sfr_master2[frame-offset=1] {
marker-width:8;
marker-fill-opacity:0.45;
}
#sfr_master2[frame-offset=2] {
marker-width:10;
marker-fill-opacity:0.225;
}
</style>
<link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/3.14/themes/css/cartodb.css" />
</head>
<body>
<!-- Navigation -->
<header>
<nav class="navbar navbar-inverse navbar-fixed-top topnav" role="navigation">
<div class="container topnav">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<img style="max-width:100px; padding-right: 10px; margin-top: -7px;" src="img/teckey_logosmall.png">
<a class="navbar-brand topnav" href="#">Map of Infection</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li>
About
</li>
<li>
Services
</li>
<li>
Contact
</li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
</header>
<div id="map"></div>
<script src="http://libs.cartocdn.com/cartodb.js/v3/3.14/cartodb.js"></script>
<!-- place your code below -->
<script>
function main() {
// Instantiate new map object, place it in 'map' element
var map = new L.Map('map', {
center: [37.976029, -87.587514], // Western Egypt
zoom: 13,
scrollWheelZoom: true
});
// setup layer
var layerSource = {
type: 'torque',
options: {
user_name: 'rkey', // replace with your user name
table_name: 'sfr_master2',
cartocss: $("#cartocss").html()
}
}
var layer = L.tileLayer('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors, © CartoDB'
});
map.addLayer(layer);
// put torque layer on top of basemap
cartodb.createLayer(map, layerSource)
.addTo(map)
.done(function(layer) {
// do stuff
})
.error(function(err) {
console.log("Error: " + err);
});
}
window.onload = main;
</script>
<div class="container-fluid">
<div id="dumbo" class="jumbotron">
<h1>Zombie Outbreak 2015</h1>
<h2>Confirmed Infection Locations</h2>
<p>Use scroll wheele or the + - buttons top left to zoom in or out, click on a location point to view info window</p>
<p><a class="btn btn-danger btn-lg" href="#" role="button">Learn more</a></p>
</div>
</div>
</body>
</html>
CSS
html, body {
font-family: 'Share Tech Mono', ;
height: 100%;
padding: 70;
margin: 0;
overflow:hidden;
background-color: black
}
div.cartodb-timeslider {
position: absolute;
display: inline-block;
height: 40px;
width: auto!important;
margin-bottom: 30px;
padding: 0;
-webkit-box-shadow: rgba(0,0,0,.2) 0 0 4px 2px;
-moz-box-shadow: rgba(0,0,0,.2) 0 0 4px 2px;
box-shadow: rgba(0,0,0,.2) 0 0 4px 2px;
background: rgba(153, 153, 153, 0.19)!important;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
-o-border-radius: 4px;
border-radius: 4px;
border: 1px solid #9f3700!important;
text-align: left;
z-index: 105;
}
div.cartodb-timeslider .ui-slider .ui-slider-range {
position: absolute;
z-index: 100;
font-size: .7em;
display: block;
border: 0;
background-position: 0 0;
background-color: #9f3700!important;
border-radius: 2px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
-o-border-radius: 2px;
}
div.cartodb-timeslider .slider-wrapper {
display: inline-block;
zoom: 1;
vertical-align: top;
width: 275px!important;
height: 4px;
padding: 18px 15px;
}
div.cartodb-timeslider p {
width: 120px;
height: 40px;
margin: 0;
padding: 0 5px 0 0;
line-height: 40px;
font-size: 13px;
font-weight: 700;
font-family: Helvetica,Arial;
text-align: center;
color: rgb(159, 55, 0)!important;
}
.navbar-inverse {
border-bottom: 1px solid rgb(159, 55, 0);
font-size: 24px;
}
.navbar-inverse .navbar-nav>li>a:hover {
color: #9f3700;
background-color: transparent;
}
.navbar-inverse .navbar-brand {
color: #9d9d9d;
font-size: 24px;
}
.navbar-inverse .navbar-brand:hover {
color: rgb(159, 55, 0);
}
#map {
border: 1px solid rgb(159, 55, 0);
height: 460px;
width: 100%;
margin: 60px 0px 1px 0px;
}
#dumbo {
display: table;
width: 100%;
padding: 0 0;
text-align: center;
color: rgb(159, 55, 0);
position: relative;
background: url(img/dark%20grunge.jpg) no-repeat center scroll;
background-color: #000;
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
-o-background-size: cover;
z-index: 16;
}
#dumbo:after {
content: "";
background: url(img/Overlays/14.png) repeat;
top: 0;
left: 0;
bottom: 0;
right: 0;
position: absolute;
opacity: 1.0;
z-index: -1;
}
.btn-danger {
color: #070707;
background-color: rgb(82, 82, 82);
border-color: black;
}
.btn-danger:hover {
color: #ffffff;
background-color: rgb(159, 55, 0);
border-color: black;
}
You are missing one important bit of specification. You always need to specify the height and width of the div that will play the role of the container for your map otherwise it will get zero height.
Since a significant part of your screen will be used by the bootstrap nav and jumbotron, you will need to specify height less than 100%.
Add the following lines to your page at the bottom of the head block.
<style>
html, body {width:100%; height:100%; padding: 0; margin: 0;}
#map { width: 100%; height:60%; background: black;}
</style>
Also consider moving the map below the jumbotron to avoid the map controls being overflown by the top navigation.
Finally there is one little problem brought to you by bootstrap CSS. Bootstrap uses a box sizing model that is different from the default (see box-sizing in CSS TR). This breaks the computation of the cartodb timeslider width. You can quickly fix this by adding an extra CSS clause:
<style>
div.cartodb-timeslider .slider-wrapper {box-sizing: content-box;}
</style>
Update: With the CSS provided by the OP that already has all the necessary clauses and tweaks the page has a street network from CartoDB standard basemap, a set of blots from the custom layer, a jumbotron and a menu from bootstrap.

Resources