Update variable with HTML slider - d3.js

This is my code which filters my dataset to one year, when I move my html slider I'd like to update the value. I have a variable year=1979 but when I input it into the function it doesn't work.
var yearData = data.filter(function(element) {return element.YEAR == "year"});
I think I'm missing something, can anyone point me in the right direction?
My fiddle: http://jsfiddle.net/vyab4kcf/6/

Your code that render the chart is called only once time at the request.
You need to store the data of the request and then do the same instructions that you already do in the callback.
So :
var request_data;
d3.csv('http://...', function(error, data){
// store the data
request_data = data;
// Run update for the first request
update("1979");
});
// Listen to slider changes
d3.select("#sexYear").on("input", function() {
update(this.value);
});
function update(sexYear) {
// Chart rendering code
// Do your filters on request_data here
}

Related

Load data from an object in D3.js

I'm looking at this example of D3.js version 4 and I need to load dynamic data from the same script.
What is the analogus function of d3.csv() to load data from an array or an object? I don't need an XMLHttpRequest but I need the same behavior of d3.csv().
A fiddle is at https://jsfiddle.net/i5ar/mbcu05z8/.
Here's the full fiddle: https://jsfiddle.net/mbcu05z8/27/
I stored the array in a variable just like you did:
var myArr= [{"id":"AL","Under 5":310504,"5 to 13":552339,"14 to 17":259034,"total":1121877},{"id":"AK","Under 5":52083,"5 to 13":85640,"14 to 17":42153,"total":179876},{"id":"AZ","Under 5":515910,"5 to 13":828669,"14 to 17":362642,"total":1707221}];
then I changed d3.csv to a custom function named draw() and just called it :-)
draw(myArr);
function draw(states) {
var stateById = d3.map();
states.forEach(function(d) {
stateById.set(d.id, d);
});
setTimeout(()=>{
dispatch.call("load", window, stateById);
dispatch.call("statechange", window, stateById.get("AL"));
},20);
};

ShieldUi manipulating chart as soon as it is rendered

I'm facing shieldUI wicket integration and I'm trying to get base 64 image dfom a shieldUi chart using this tutorial: https://www.shieldui.com/documentation/javascript.chart/exporting
I tried to run the code below:
function render_image_box(chart_id) {
var result = false;
var svg_chart = $("#" + chart_id);
if (svg_chart) {
var chart = svg_chart.swidget();
if (chart != null) {
chart.exportToImage();
result = true;
}
}
// setTimeout(find_image_source, 100) // wait before continuing
return chart;
}
in both the $(document).ready(..) and $(window).load(...) functions and the load event raised from the library (https://www.shieldui.com/documentation/javascript.chart/events/load) as well.
In none of these function chart is rendered yet, so the svg_chart.swidget() returns null.
Is there any other event to use to accomplish my goal or any other way to get the image source?
Thanks in advance,
Laura
You can access the chart instance using .swidget() only after you have initialized it with the .shieldChart() constructor.
To make your code work, you should also turn off animation for the chart, because right after you initialize it, the rendering will not be over and there will be no image contents.
Here is a complete JSBin to get you started...

Add or trigger event after inner content to page

I have links on a table to edit or delete elements, that elements can be filtered. I filtered and get the result using ajax and get functions. After that I added (display) the result on the table using inner.html, the issue here is that after filtering the links on the elements not work, cause a have the dojo function like this
dojo.ready(function(){
dojo.query(".delete-link").onclick(function(el){
var rowToDelete = dojo.attr(this,"name");
if(confirm("Really delete?")){
.......
}
});
I need to trigger the event after filtering, any idea?
(I'm assuming that you're using Dojo <= 1.5 here.)
The quick answer is that you need to extract the code in your dojo.ready into a separate function, and call that function at the end of your Ajax call's load() callback. For example, make a function like this:
var attachDeleteEvents = function()
dojo.query(".delete-link").onclick(function(el){
var rowToDelete = dojo.attr(this,"name");
if(confirm("Really delete?")){
.......
}
});
};
Then you call this function both in dojo.ready and when your Ajax call completes:
dojo.ready(function() { attachDeleteEvents(); });
....
var filter = function(someFilter) {
dojo.xhrGet({
url: "some/url.html?filter=someFilter",
handleAs: "text",
load: function(newRows) {
getTableBody().innerHTML = newRows;
attachDeleteEvents();
}
});
};
That was the quick answer. Another thing that you may want to look into is event delegation. What happens in the code above is that every row gets an onclick event handler. You could just as well have a single event handler on the table itself. That would mean there would be no need to reattach event handlers to the new rows when you filter the table.
In recent versions of Dojo, you could get some help from dojo/on - something along the lines of:
require(["dojo/on"], function(on) {
on(document.getElementById("theTableBody"), "a:click", function(evt) {...});
This would be a single event handler on the whole table body, but your event listener would only be called for clicks on the <a> element.
Because (I'm assuming) you're using 1.5 or below, you'll have to do it a bit differently. We'll still only get one event listener for the whole table body, but we have to make sure we only act on clicks on the <a> (or a child element) ourselves.
dojo.connect(tableBody, "click", function(evt) {
var a = null, name = null;
// Bubble up the DOM to find the actual link element (which
// has the data attribute), because the evt.target may be a
// child element (e.g. the span). We also guard against
// bubbling beyond the table body itself.
for(a = evt.target;
a != tableBody && a.nodeName !== "A";
a = a.parentNode);
name = dojo.attr(a, "data-yourapp-name");
if(name && confirm("Really delete " + name + "?")) {
alert("Will delete " + name);
}
});
Example: http://fiddle.jshell.net/qCZhs/1/

Ajax URL # isn't updating

I have a little problem with my script here. For some reason, it doesn't enable the #-tags and I don't know why. I created this javascript using the help of this tutorial. (The loading of the pages works well with no problems at all.)
Could someone please look it over and tell me why it doesn't work?
var default_content="";
$(document).ready(function(){ //executed after the page has loaded
checkURL(); //check if the URL has a reference to a page and load it
$('ul li a').click(function (e){ //traverse through all our navigation links..
checkURL(this.hash); //.. and assign them a new onclick event, using their own hash as a parameter (#page1 for example)
});
setInterval("checkURL()",250); //check for a change in the URL every 250 ms to detect if the history buttons have been used
});
var lasturl=""; //here we store the current URL hash
function checkURL(hash)
{
if(!hash) hash=window.location.hash; //if no parameter is provided, use the hash value from the current address
if(hash != lasturl) // if the hash value has changed
{
lasturl=hash; //update the current hash
loadPage(hash); // and load the new page
}
}
function loadPage(url) //the function that loads pages via AJAX
{
// Instead of stripping off #page, only
// strip off the # to use the rest of the URL
url=url.replace('#','');
$('#loading').css('visibility','visible'); //show the rotating gif animation
$.ajax({
type: "POST",
url: "load_page.php",
data: 'page='+url,
dataType: "html",
success: function(msg){
if(parseInt(msg)!=0) //if no errors
{
$('#content').html(msg); //load the returned html into pageContet
} $('#loading').css('visibility','hidden');//and hide the rotating gif
}
});
}
You can simplify this immensely by adding a function to listen to the hashchange event, like this:
$(window).on("hashchange", function() {
loadPage(window.location.hash);
});
This way you don't need to deal with timers or overriding click events on anchors.
You also don't need to keep track of lasthash since the hashchange even will only fire when the hash changes.

jQuery stops working after ajax request that adds fields to a form in Drupal 7

I don't think this is a Drupal-specific question, but more of a general jquery/ajax issue:
Basically, I'm trying to use javascript to add up form fields and display the result in a "subtotal" field within the same form. Everything is working fine until i click the option to add another field (via ajax), which then changes my "subtotal" field to zero, and won't work again until I remove the field.
Here is the function that adds up the fields:
function calculateInvoiceFields(){
var total = 0;
var rate = 0;
var quantity = 0;
var i = 0;
var $ = jQuery;
$("#field-aminvoice-data-values tr").each(function(){
// quantity field number
quantity = $("#edit-field-aminvoice-data-und-"+i+"-field-aminvoice-quantity-und-0-value").val();
// rate field as number
rate = $("#edit-field-aminvoice-data-und-"+i+"-field-aminvoice-rate-und-0-value").val();
if(!isNaN(quantity) && !isNaN(rate)){
total += quantity*rate;
}
i++;
});
return total;
}
And here are the functions that get fired for .ready and .live:
jQuery(document).ready(function(){
var $ = jQuery;
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
jQuery(function(){
var $ = jQuery;
$(".form-text").live('change', function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
});
Any ideas would be a big help. Thanks in advance!
I recommend using 'on' for any binding statement. and 'off' for unbinding.
The reason it doesn't work after an AJAX call, is because you need to be watching for that element to be added to the DOM, and an event attached to it after it gets loaded. If you load a new element in, and there is nothing watching for it, it won't add the event watch to that new DOM element.
As below:
function calculateInvoiceFields(){
/*..*/
return total;
}
$(document).ready(function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
$("body").on('change', ".form-text", function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
});
usually it stops working when an error has been thrown. did you check out your javascript console (firefox firebug, or built in for chrome) for any indication of an error?

Resources