Why does my d3.js image appear in the wrong place? - javascript

I have been designing a gantt chart. The javascript files are located within the html body:
<body>
<section>
<div class="container">
<h1 class="arrow">Areas of Expertise</h1>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="text/javascript" src="http://static.mentful.com/gantt-chart-d3v2.js"></script>
<script type="text/javascript" src="js/gantt.js"></script>
</div>
</section>
</body>
However, when I look at the source, the svg file is located outside of the section tags:
<body>
<section>...</section>
<script>...</script>
<svg class="chart" width="777" height="827">...</svg>
</body>
I want my chart to take on the properties of the container it's in. It doesn't seem to be doing that. Here is a working example of my chart in action: http://jsbin.com/pigudeyovi/2/edit?html,output
Why is the .svg outside of the section tags?

The location of the code is not significant in deciding where its output appears -- D3 requires you to specify explicitly where to add any new elements to the DOM.
In this case, the output will always appear immediately below the body element. This is hard-coded in the Gantt chart library source code and not configurable by the user. To change that you either need to change the source code of the library or move the DOM element yourself.

The gnatt-chart plugin is appending the SVG to the body.
https://github.com/dk8996/Gantt-Chart/blob/master/gantt-chart-d3.js#L75

Related

D3.js - Add elements in HTML - <script></script> location

I was working with the following tutorial of D3.js: https://www.tutorialspoint.com/d3js/index.htm.
My issue is as follows:
I'm aware of that the location inside the HTML is at the end of the . I mean, I usually put it here:
<body>
<!-- HTML code -->
<script>
<!-- JS code or external JS link -->
</script>
</body>
With this practice, what I'm looking is to run JS after the HTML content renders.
But! When I follow this practice using D3.js, what I discover is that D3.js renders what I add (using d3("html").append(something to append), after the script tags.
For example!
<!DOCTYPE html>
<head>
<title>D3.js Test</title>
</head>
<body>
<div class="div_test">
<h1>I want the D3.js content after this div (but not inside the div)</h1>
</div>
<script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
<script>
d3.select("html").append("p").text("I get this text after the script tags");
</script>
</body>
</html>
I'm getting the content as follows:
<!DOCTYPE html>
<html>
<head>
<title>D3.js Test</title>
</head>
<body>
<div class="div_test">
<h1>I want the D3.js content after this div (but not inside the div)</h1>
</div>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script>
d3.select("html").append("p").text("I get this text after the script tags");
</script>`
</body><p>I get this text after the script tags</p></html>
Questions!
Is the position of the tag correct?
Is there a possibility to keep the flow without adding a to anchor the expected new tag?
Thanks!!!
You can use selection.insert() to insert an element instead of appending it to the DOM. The second argument to that method determines where the newly created element is put into the DOM tree. If you just want to put it in front of the first <script> element you can do something like:
d3.select("body").insert("p", "script") // <-- insert before first <script>
If you need to place it after the <div>, no matter what the next element might look like, you can use the adjacent sibling combinator to select the sibling element directly following the <div> like so:
d3.select("body").insert("p", "div + *") // <-- insert before next element following div

How do you activate alpinejs?

I'm trying to add AlpineJS to a very simple html page that I'm working on and the package is being executed (from cdn) but it doesn't seem to get activated correctly. Even on this small snippet of HTML, it doesn't work:
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js" defer></script>
</head>
<body>
<h1 x-show="false">hide me</h1> <!-- doesn't work-->
</body>
<script type="text/javascript">
console.log($el); //undefined
</script>
</html>
This is also loaded into a codepen where the problem can be observed: https://codepen.io/dwarburt/pen/gOgZyeR
I'm sure I've just missed a step, but what could it be? AlpineJS is executing its initialization routines, you can tell from the debugger.
To initialise an AlpineJs component you'll need an x-data attribute on the parent container:
<div x-data="{
isShowing: false
}">
<h1 x-show="isShowing">I am hidden</h1>
</div>
This contains an object with properties and functions you can use within the component instance.
It's definitely worth reading through the docs in the repo here: https://github.com/alpinejs/alpine#use
I have adjusted your example in order to achieve the result you require, along with an additional example so you can see how multiple object properties can exist and used within your Alpine.js components.
x-data does not need to be initiated on the body tag, however nested components will retrieve the object property from the closest x-data property match.
You can access from child nodes of nested x-data objects the properties.
Careful of your property naming conventions if you don't wish to overwrite proceeding object properties.
I would also suggest reading Build a Drop Down along with Toggle Element
Reading these points will be helpful in understanding the below example in further detail.
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js" defer></script>
</head>
<body x-data="{show: false, button: 'Toggle'}">
<button #click="show = ! show" x-text="button"></button>
<span x-show="show">
<h1 #click.outside="show = false">hide me</h1> <!-- doesn't work-->
</span>
</body>
</html>

Why does this JS file have no effect on DOM?

I am trying to teach myself how to modify the DOM using JavaScript. I am at a loss about the following.
This is an HTML snippet.
<html>
<body>
<h1>A heading</h1>
<div id="myDIV"></div>
<script type="text/javascript" src="thejs.js"></script>
<script type="text/javascript">
document.getElementById("myDIV").innerHTML="<p>Try this one comes from script inside html source</p>"
</script>
</body>
</html>
I expect to get a similar result from the external js file linked in the script, which contains this:
document.getElementById("myDIV").innerHTML="<p>While this one comes from a separate JS file</p>";
But nothing happens... I realise this is probably silly, I apologize.
The first script runs and sets the content of the div to "While this one comes from a separate…"
Then, after some time which is imperceptible to a human, passes the second script runs and sets the content of the div to "Try this one comes from script…".
If you want both paragraphs to appear you need to append (e.g. with +=) the data instead of replacing it.
That said, appending chunks of HTML with innerHTML += can cause some issues (it's inefficient as that whole chuck of DOM has to be regenerated and it will blow away inline event handlers) so you are usually better off using the insertAdjacentHTML method instead.
The output depends on where you have included the external js. If you have included it before your embedded script, it will not have any effect, as eventually, it will be overridden by your embedded script. However, if you include the external js after your embedded js, it will work as you want to.
<html>
<body>
<h1>A heading</h1>
<div id="myDIV"></div>
<script type="text/javascript" src="thejs.js"></script>
<script type="text/javascript">
document.getElementById("myDIV").innerHTML="<p>Try this one comes from script inside html source</p>"
</script>
<script type="text/javascript" src="external.js"></script>
</body>
</html>

Adding a drop down menu in the force-layout (d3.js)

Based on this example: http://bl.ocks.org/jfreels/6734245
When i use a code that contains this single line in D3.js, :
<script>
var select = d3.select('body').append('select')
</script>
Then an empty drop down menu on the upper left side of the screen appears.
So my plan was to copy and paste the drop down menu in a force-direct layout based on this example: https://bl.ocks.org/mbostock/4062045
But unfortunaly it did not worked. Is it because i use d3.select('body') to create the drop down menu?
Yes.
It works perfectly fine when you add the <body> tag.
Your code would look something like (excluding scripts, and style):
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<body>
<svg width="960" height="600"></svg>
<script type='text/javascript' src='script.js'></script>
</body>
Make sure have the script.js file in the right directory. Else copy the code into a <script> </script>tag. I cannot recommend this though.

How to attach an HTML element or a DocumentFragment to the DOM?

I’ve got an HTML fragment like <p>Hello, World!</p> and want to attach it to the container HTML page that includes
<script src="lib/kotlin.js"></script>
<script src="my-app.js"></script>
There are two package that came to my mind:
kotlin.js.dom.html.window.document.*
kotlin.browser.document.*
Which should I use and how do I access the document’s root? I’ve already tried document.getElementById("container") whereby container is the id of a DIV. But this returns null. I also tried document.appendChild(node)...
Also which of the above packages should I prefer?
I just figured out that the JS output of the compiled app needs to be below the element that is referenced inside the app.
I’ve created a demo case that illustrates this:
<!DOCTYPE html>
<meta charset="utf-8"/>
<script src="lib/kotlin.js"></script>
<p>Look inside the JavaScript Console of your browser…</p>
<div id="container"></div>
<script>
console.log("Native JavaScript");
</script>
<!-- This script tag was misplaced. It needs to be placed after all elements you want to access in your DOM -->
<script src="kotlin-javascript-hello-world.js"></script>

Categories

Resources