Only select subset in d3 - javascript

Is it possible to only select a subset / subgroup in d3?
right now I have
d3.selectAll(".row")
now below the rows I have cells and I want to select all cells from row 3 as shown in this image subset example.
There is no get(3) or [3] option.
Thank you for your help.
d3.selectAll(".row").selectAll(".cell")
gives me all cells

Lots of ways to do this. My favorite would be using a css :nth-child selector:
d3.select(".row:nth-child(3n)").selectAll(".cell");
Here's some others:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div class="row">
<div class="cell">a</div>
<div class="cell">b</div>
<div class="cell">c</div>
</div>
<div class="row">
<div class="cell">d</div>
<div class="cell">e</div>
<div class="cell">f</div>
</div>
<div class="row">
<div class="cell">g</div>
<div class="cell">h</div>
<div class="cell">i</div>
</div>
<div class="row">
<div class="cell">j</div>
<div class="cell">k</div>
<div class="cell">l</div>
</div>
</body>
<script>
var w1 = d3.select(document.querySelectorAll(".row")[2]).selectAll(".cell"),
w2 = d3.selectAll(".row").filter((d,i) => i === 2).selectAll(".cell"),
w3 = d3.select(d3.selectAll(".row").nodes()[2]).selectAll(".cell"),
w4 = d3.select(".row:nth-child(3n)").selectAll(".cell");
</script>
</html>

Related

How can I loop through divs and add a class if all children are set to display:none?

I am trying to hide a paragraph tag if all the children of its sibling are set to display none.
Here is an example of some of my code (the rest is just more of the same divs):
var templateheading = $('.js-template-heading');
var templategrid = templateheading.next();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="c-templates-wrapper">
<p class="js-template-heading">These themes are available on <strong>Starter</strong> website packages.</p>
<div class="c-templates-grid">
<div class="js-template">Starter 1</div>
<div class="js-template">Starter 2</div>
<div class="js-template">Starter 3</div>
</div>
</div>
<div class="c-templates-wrapper">
<p class="js-template-heading">These themes are available on <strong>Pro</strong> website packages.</p>
<div class="c-templates-grid">
<div class="js-template">Pro 1</div>
<div class="js-template">Pro 2</div>
<div class="js-template">Pro 3</div>
</div>
</div>
Just to store the paragraphs and the grids in their own variables.
So basically, I need to loop through every templategrid and if ALL of the children within it are set to display none via a style tag (done with a filter), add a class to either c-templates-wrapper or js-template-heading (I basically just want to hide the corresponding paragraph it if theres nothing to show within the grid below it).
I hope that makes sense and I hope someone can help.
You could use something like this:
$('.c-templates-wrapper p.js-template-heading').filter(function() {
return $(this).next().find(".js-template:visible").length == 0
}).hide()
Demo
$(".c-templates-wrapper:first .js-template").hide()
$('.c-templates-wrapper p.js-template-heading').filter(function() {
return $(this).next().find(".js-template:visible").length == 0
}).hide()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="c-templates-wrapper">
<p class="js-template-heading">These themes are available on <strong>Starter</strong> website packages.</p>
<div class="c-templates-grid">
<div class="js-template">Starter 1</div>
<div class="js-template">Starter 2</div>
<div class="js-template">Starter 3</div>
</div>
</div>
<div class="c-templates-wrapper">
<p class="js-template-heading">These themes are available on <strong>Pro</strong> website packages.</p>
<div class="c-templates-grid">
<div class="js-template">Pro 1</div>
<div class="js-template">Pro 2</div>
<div class="js-template">Pro 3</div>
</div>
</div>
I have coded. But if I hide the paragraph, on display:none of sibling's children then you cannot see anything because everything will get hidden. So, I modified the code. But you can easily set it according to your need.
I just use CSS to display:none to children. And then on display:none, I change the background-color of Paragraph to red.
$(document).ready(function(){
var paragraph = $(".js-template-heading");
if(paragraph.siblings().children().css("display")=="none"){
paragraph.css("background-color","red");
}
});
.js-template{
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="c-templates-wrapper">
<p class="js-template-heading">These themes are available on <strong>Starter</strong> website packages.</p>
<div class="c-templates-grid">
<div class="js-template">Starter 1</div>
<div class="js-template">Starter 2</div>
<div class="js-template">Starter 3</div>
</div>
</div>
</body>
</html>

Displaying data from API in accordion

I have some data from an API which I'm displaying on my web page. I've also got some simple HTML for an accordion. I have 4 lots of data and I want to display only one lot per slide on the accordion.
How would I do this? I would like to know how to separate the data for each slide based on my code.
$( function() {
$( "#top-stories" ).accordion();
});
fetch('https://api.nytimes.com/svc/topstories/v2/technology.json?api-key='')
.then((resp) => resp.json())
.then(function(data) {
const accordionSlides = document.querySelectorAll(".accordion-slide");
data.results.slice(0, 4).forEach((accordion, i) => {
accordionSlides[i].innerHTML = `
<h1>${accordion.title}</h1>
<p>${accordion.url}</p>
<p>${accordion.abstract}</p>
<p>${accordion.published_date}</p>
<img src="${accordion.multimedia[4].url}"/>`;
})
})
<html>
<head>
<link rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="index.js"></script>
</head>
<body>
<div id="top-stories">Top Stories</h1>
<h3 class="accordion">Story 1</h3>
<div class="panel">
<div class="accordion-title"></div>
</div>
<h3 class="accordion">Story 2 - Collapsed</h3>
<div class="panel">
<div class="accordion-title"></div>
</div>
<h3 class="accordion">Story 3 - Collapsed</h3>
<div class="panel">
<div class="accordion-title"></div>
</div>
<h3 class="accordion">Story 4 - Collapsed</h3>
<div class="panel">
<div class="accordion-title"></div>
</div>
</body>
</html>
If you're open to using jquery-ui library, the following should work.
First of all, your HTML should be something as below:
<html>
<head>
<link rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="index.js"></script>
</head>
<body>
<div id="top-stories">Top Stories</h1>
<h3 class="accordion">Story 1</h3>
<div class="panel">
<div class="accordion-slide"></div>
</div>
<h3 class="accordion">Story 2 - Collapsed</h3>
<div class="panel">
<div class="accordion-slide"></div>
</div>
<h3 class="accordion">Story 3 - Collapsed</h3>
<div class="panel">
<div class="accordion-slide"></div>
</div>
<h3 class="accordion">Story 4 - Collapsed</h3>
<div class="panel">
<div class="accordion-slide"></div>
</div>
</body>
</html>
I've changed the ID's to classes and replaced buttons with h3 tags. Also, I've added a link to the jquery-ui library.
And then the JS would mostly be as suggested by #marzelin with the addition jquery-ui accordin library initialization:
$( function() {
$( "#top-stories" ).accordion();
});
fetch('https://api.nytimes.com/svc/topstories/v2/technology.json?api-key="."')
.then((resp) => resp.json())
.then(function(data) {
const accordionSlides = document.querySelectorAll(".accordion-slide");
data.results.slice(0, 4).forEach((accordion, i) => {
accordionSlides[i].innerHTML = `
<h1>${accordion.title}</h1>
<p>${accordion.url}</p>
<p>${accordion.abstract}</p>
<p>${accordion.published_date}</p>
<img src="${accordion.multimedia[4].url}"/>`;
})
})
change <div id="accordion"></div> to <div class="accordion-slide"></div> and then:
fetch('https://api.nytimes.com/svc/topstories/v2/technology.json?api-key="."')
.then((resp) => resp.json())
.then(function(data) {
// get all slides
const accordionSlides = document.querySelectorAll(".accordion-slide");
data.results.slice(0, 4).forEach((accordion, i) => {
// insert content into a given slide
accordionSlides[i].innerHTML = `
<h1>${accordion.title}</h1>
<p>${accordion.url}</p>
<p>${accordion.abstract}</p>
<p>${accordion.published_date}</p>
<img src="${accordion.multimedia[4].url}"/>`;
})
})

How to change div order in javascript

I want to change the div order through JavaScript. i didn't know how to do that
This is the two div which implement in html, but i want div id="navigation" show in html after div class="row subheader".
<div id="navigation">
<div class="item" style="display:inline;">
Home
</div>
<div class="item" style="display:inline;">Blog: Kannu</div>
</div>
<div class="row subheader">
<div class="container">
<div id="blogsubheader">My Blog</div>
</div>
</div>
I want like this from javascript please check follow.
<div class="row subheader">
<div class="container">
<div id="blogsubheader">My Blog</div>
</div>
</div>
<div id="navigation">
<div class="item" style="display:inline;">
Home
</div>
<div class="item" style="display:inline;">Blog: Kannu</div>
</div>
Thanks in advance
Assuming you're using jQuery, then use this :
$('#navigation').insertAfter( ".container" );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="navigation">
<div class="item" style="display:inline;">
Home
</div>
<div class="item" style="display:inline;">Blog: Kannu</div>
</div>
<div class="row subheader">
<div class="container">
<div id="blogsubheader">My Blog</div>
</div>
</div>
</body>
</html>
As you want to change the DOM. First you need to clone the first section and store it in a variable. Then remove the first element from the DOM. And append this element after the 2nd element.
To do so using jQuery
var nav = $('#navigation').clone(true);
$('#navigation').remove();
nav.insertAfter('.subheader');
In JavaScript
var nav = document.getElementById('navigation');
var subHeader = document.getElementsByClassName('subheader');
subHeader[0].after(nav);
Here is the fiddle link https://jsfiddle.net/moshiuramit/xm85h29g/7/
How about this?
var navigation = document.getElementById('navigation');
var rowSubheader = document.getElementById('row-subheader');
rowSubheader.after(navigation);
You'll have to add an id here though, as I did:
<div class="row subheader" id="row-subheader">
https://jsfiddle.net/zmve7xyc/
If you are changing the order just for the view consider using Flex css property (after checking browser compatibility). DOM manipulation is an intensive operation and you shouldn't do it until absolute necessity.
Simply wrap both div in a wrapper div and toggle class for changing flex-direction of wrapper div
You can use appendTo also in JQuery.
Ex :
var nav = $('#navigation').clone(true);
$('#navigation').remove();
nav.appendTo('.subheader');

How to get an array from html using javascript?

I have an HTML like this:
<div class='item'>
<h1 id="Python">Python</h1>
</div>
<div class='item'>
<h1 id="C++">C++</h1>
</div>
<div class='item'>
<h1 id="PHP">PHP</h1>
</div>
How to use javascript to get an array like [Python, C++, PHP]?
I tried and wrote like this:
var myList = document.getElementsByTagName('h1');
console.log(myList.length)
But the Output is 0, it's strange.
Your code logs 3: http://jsfiddle.net/t0ho10hw/
To get an array of languages you can convert the HTMLCollection to an actual Array, then .map it to get languages:
var myList = document.getElementsByTagName('h1');
var languages = [].slice.call( myList ).map( function( item ){
return item.innerHTML;
});
http://jsfiddle.net/t0ho10hw/1/
Or the "classic" way from before Array.map:
var languages = [];
for( var i=0; i<myList.length; i++){
languages.push( myList[i].innerHTML );
}
http://jsfiddle.net/t0ho10hw/2/
Using JQuery you could use this code :
var tab = [];
$(".item h1").each(function() {
tab.push($(this).text());
});
see Get an array of list element contents in jQuery
You need to be careful where and when you do your JS computation
<!DOCTYPE html>
<html>
<head>
<script>
var myList = document.getElementsByTagName('h1');
console.log(myList.length)
</script>
</head>
<body>
<div class='item'>
<h1 id="Python">Python</h1>
</div>
<div class='item'>
<h1 id="C++">C++</h1>
</div>
<div class='item'>
<h1 id="PHP">PHP</h1>
</div>
</style>
</body>
</html>
Will give you 0, because the Javascript is called before any parsing of the HTML body by your browser.
You need either :
- to wait the page load
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function(){
var myList = document.getElementsByTagName('h1');
console.log(myList.length)
}
</script>
</head>
<body>
<div class='item'>
<h1 id="Python">Python</h1>
</div>
<div class='item'>
<h1 id="C++">C++</h1>
</div>
<div class='item'>
<h1 id="PHP">PHP</h1>
</div>
</style>
</body>
</html>
or write this javascript at the end of the page :
<!DOCTYPE html>
<html>
<head>
<script>
var myList = document.getElementsByTagName('h1');
console.log(myList.length)
</script>
</head>
<body>
<div class='item'>
<h1 id="Python">Python</h1>
</div>
<div class='item'>
<h1 id="C++">C++</h1>
</div>
<div class='item'>
<h1 id="PHP">PHP</h1>
</div>
</style>
</body>
</html>
Even better is to write it at the end of the page with the window.onload. It will be shorter to reach the HTML part of your page and rendering would be faster (this is significant for large amount of JS, but in this case, you should do file inclusion)

Does anyone know why my canvas tag won't show up in IE 8? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I use the HTML5 canvas element in IE?
I'm not sure what I'm doing wrong. I did what it said to do but nothing works. I'm using a grid system, but I don't think that's the problem. And I don't think it's my security settings either. Here's my HTML and Javascript if that helps.
HTML
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Zack Vivier</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!--[if IE]><script type="text/javascript" src="js/excanvas.js"></script><![endif]-->
<!-- enable HTML5 elements in IE7+8 -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<![endif]-->
<!-- 1140px Grid styles for IE -->
<!--[if lte IE 9]><link rel="stylesheet" href="styles/ie.css" type="text/css" media="screen" /><![endif]-->
<link href="styles/styles.css" rel="stylesheet" type="text/css">
<link href="styles/1140.css" rel="stylesheet" type="text/css">
<!--css3-mediaqueries-js - http://code.google.com/p/css3-mediaqueries-js/ - Enables media queries in some unsupported browsers-->
<script type="text/javascript" src="js/css3-mediaqueries.js"></script>
<script src="js/js.js"></script>
</head>
<body>
<header>
<h1 class="hidden">Zack Vivier Home</h1>
<div class="container">
<div class="row">
<div class="fivecol">
<div class="logo"><img src="images/logo.png" alt="zack vivier logo"></div>
</div>
<div class="sevencol last">
<nav>
<h2 class="hidden">Site Navigation</h2>
<ul>
<li>Home</li>
<li>Information</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
</nav>
</div>
</div>
</div>
</header>
<div class="container">
<div class="row">
<div class="twelvecol last">
<div class="lineone"></div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="twelvecol last">
<div class="caption">
<h4 id="tagLine">Image Number</h4>
</div>
<div class="slideshow">
<canvas id='showCanvas' width='1022' height='397'>Canvas Not Supported</canvas>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="threecol last">
<div class="about"><h2>About Me</h2></div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="twelvecol last">
<div class="linetwo"></div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="sevencol last">
<div class="contenthome">
<p> My Name is Zack Vivier; currently I am 19</p>
<p>years old and attend Fanshawe College for Interactive</p>
<p>Media Design and Production. I am a Designer,</p
<p>Programmer, Musician, Video Editor, and Animator.</p>
</div>
</div>
</div>
</div>
<h1 class="hidden">footer</h1>
<div class="container">
<div class="row">
<div class="twelvecol last">
<div class="footer">
<h3>Copyright © 2012 Zack Vivier. All Rights Reserved.</h3>
</div>
</div>
</div>
</div>
</body>
</html>
Javascript
// JavaScript Document
var imagePaths = new Array("images/photo_1.png", "images/game_web.jpg", "images/tattoo.jpg");
var whichImage = new Array("Graffti Project", "Game WebSite", "Tattoo Project");
var showCanvas;
var showCanvasCtx;
var imageText;
var currentImage = 0;
var currentImageText = 0;
var img = document.createElement("img");
function init() {
imageText=document.getElementById('tagLine');
showCanvas = document.getElementById('showCanvas');
showCanvasCtx = showCanvas.getContext('2d');
img.setAttribute('width','1022');
img.setAttribute('height','397');
switchImage();
setInterval(switchImage, 2500);
}
function switchImage() {
imageText.innerHTML = whichImage[currentImageText++];
img.setAttribute('src',imagePaths[currentImage++]);
img.onload = function() {
if (currentImage >= imagePaths.length) {
currentImage = 0;
currentImageText = 0;
}
showCanvasCtx.drawImage(img,0,0,1022,397);
}
window.onload = init();
Canvas is a HTML5 element which IE8 doesn't supports.
Your doctype is also wrong since you're using HTML5 set it to: "".
As said in the comments: IE8 won't support the canvas tag. However there are some plugins that mimic it's behavior. I've used this one once: http://flashcanvas.net/ and it does the job, there's another called http://code.google.com/p/explorercanvas/. but i have no comment on that one, never used, don't know what to expect.
Just one note: the fallbacks will have their limitations, but as far as 2D drawing concerns, I think these will work out for you

Categories

Resources