I have a checkbox placed separately of my XY columnseries chart. The original chart has each series.stacked = true. This works fine. I have a listener on the checkbox to toggle from the stacked columns to independent columns. It sets (toggles) the same stacked property on each series. Unfortunately nothing updates. I have tried calling invalidateData() on the chart after the property assignment - but that also doesn't work to update the stacking / unstacking function.
$("#chartAssetsTimelineIndividualColumns").change(function () {
chartAssetsTimeline.series.values.forEach(function (series) {
series.stacked = !this.checked;
});
});
this doesn't refer to the input element when you're inside the forEach method as it is scoped to the window object at that point. You'll want to save a reference to it and use that instead, or just use the event object that the change method provides. Also, you should use the each function instead of iterating over the read-only values array.
$('#chartAssetsTimelineIndividualColumns').change(function() {
var that = this;
chartAssetsTimelineIndividualColumns.series.each(function(series) {
series.stacked = !that.checked;
});
});
// or
$('#chartAssetsTimelineIndividualColumns').change(function(e) {
chartAssetsTimelineIndividualColumns.series.each(function(series) {
series.stacked = !e.target.checked;
});
});
// or, preferably, with VanillaJS:
document.getElementById('chartAssetsTimelineIndividualColumns').addEventListener('change', function(e) {
chartAssetsTimelineIndividualColumns.series.each(function(series) {
series.stacked = !e.target.checked;
});
});
Related
I have kendo grid with a select option. My question is how do I get ProductName from the last selected row? Example like this. I have tried with this but row is null. Appreciate your help.
FULL DEMO IN DOJO
function onChange(e) {
var rows = e.sender.select();
rows.each(function(e) {
var grid = $("#grid").data("kendoGrid");
var row = $(e.target).closest("tr"); //<-- this value capture null
var dataItem = grid.dataItem(row);
var productName = dataItem.ProductName;
alert(productName);
})
};
You have incorrect parameters in the function in each.
This causes name masking: https://en.wikipedia.org/wiki/Name_resolution_(programming_languages)#Name_masking
At the outer level, you have:
function onChange(e) {
Then, in the third line, you have:
rows.each(function(e) {
That's two functions of e. So which e counts? The inner one masks the outer one.
The correct arguments for the inner function are:
rows.each(function(index, row) {
Now, you're already iterating over rows, so you have the row, you don't need to look for it with any closest().
You also have the grid, it's e.sender, because you're in a grid event.
That gives you the following code:
function onChange(e) {
var rows = e.sender.select();
rows.each(function(index, row) {
console.log(row);
var dataItem = e.sender.dataItem(row);
console.log(dataItem);
var productName = dataItem.ProductName;
console.log(productName);
})
};
Demo
In the future, be wary of the difference between Kendo events and jQuery events.
Just use grid.select() inside grids change function:
function onChange(e) {
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
console.log(selectedItem.ProductName)
};
Example: Get last selected item
I'm trying to add a clickable route on Geocoder example from Appcelerator. The problem is that I'm not getting any event when clicking at the route object.
Here's my code:
var cord1= {
latitude:29.078685,
longitude:-110.971205,
};
var cord2= {
latitude:29.081496,
longitude:-110.959232,
};
var route1 = [cord1, cord2];
var route = MapModule.createRoute({
points : route1,
color : "red",
width : 5.0
});
route.addEventListener('click', function(e){
Ti.APP.info(e);
});
$.mapview.addRoute(route);
The Modules.Map.Route object doesn't have any events. None of the map objects do, except the map view itself, and we can use the mapview's click event to listen for clicks, and then check the clicksource property to see what was clicked on the map.
The catch is that routes won't generate a click event, but polylines do, so the workaround is to use a polyline and look for the clicksource in the mapview's click event. Something like this should work:
var coord1 = [-110.971205, 29.078685];
var coord2 = [-110.959232, 29.081496];
var route1 = [coord1, coord2];
var route = MapModule.createPolyline({
points: route1,
strokeColor: "#ff0000",
strokeWidth: 5
});
$.mapview.addPolyline(route);
$.mapview.addEventListener('click', function (e) {
//check the clicksource for 'polyline'
console.log(e.clicksource);
});
I'm trying to link a pie chart to a map so that when you click a state the pie chart updates with the popular vote for that state.
Currently my piechart is displaying empty.
Csv is formatted like so:
state, party, votes
Alabama,dem,725704
Alabama,rep,1314431
Alabama,lib,44211
Alabama,gre,20276
Alabama,con,9341
Alaska,dem,116454
Alaska,rep,163387
Alaska,lib,18725
Alaska,gre,5735
Alaska,con,3866
Alaska,other,10441
My code:
d3.csv("elecVotes.csv", function (data) {
d3.json("us.json", function (json){
// set up crossfilter on the data.
var ndx = crossfilter(data);
// set up the dimensions
var stateDim = ndx.dimension(function (d) { return d.state; });
var party = partyDim.group().reduceSum(function(d) { return d.votes;});
var votesDim = ndx.dimension(function(d) { return d.votes; });
// set up the groups/values
var state = stateDim.group();
var party = partyDim.group();
var votes = votesDim.group();
// the 4 different charts - options are set below for each one.
var pie = dc.pieChart('#chart-pie');
var usmap = dc.geoChoroplethChart("#usmap");
//create pie from to show popular vote for each state
pie
.width(180)
.height(180)
.radius(80)
.dimension(partyDim)
.group(votes)
.renderLabel(true)
.innerRadius(10)
.transitionDuration(500)
.colorAccessor(function (d, i) { return d.value; });
//display US map
usmap
.width(900)
.height(500)
.dimension(stateDim)
.group(state)
.colors(["rgb(20,202,255)","rgb(144,211,035)"])
.overlayGeoJson(json.features, "name", function (d) { return d.properties.name; })
// at the end this needs to be called to actually go through and generate all the graphs on the page.
dc.renderAll();
});
});
I'm not sure what i'm doing wrong
I don't think you want a votesDim - that would group by the number of votes, so you would probably end up with a different bin for each count, since they are likely to be unique.
I'm guessing you probably want to count the number of votes for each party, so:
var partyGroup = partyDim.group().reduceSum(function(d) { return d.votes; });
Remember that a dimension specifies what you want to filter on, and a group is where data gets aggregated and read.
You also need to convert any numbers explicitly before you get started, since d3.csv will read every field as a string. So:
data.forEach(function(r) {
r.votes = +r.votes;
});
var ndx = crossfilter(data);
Not sure if this helps with your problem. Note that this really has nothing to do with the map; the pie chart should be able to draw itself independent of what the map is doing.
Edit
I bet the problem is those spaces in the column names. You could easily end up with fields named " party" and " votes" that way...
I am getting a list of options for a select from a server and populating an observableArray. Then I would like to set the selected item to a predefined value. I have a very simple jsFiddle that emulates pulling data from a server with a button click.
http://jsfiddle.net/JonathanN/hev1rqeu/
Here's the Javascript with the basic attempt:
(function() {
var vm = (function() {
var self = this;
self.array = ko.observableArray([]);
self.selectedValue = ko.observable();
self.useSetTimeout = ko.observable(false);
self.array.subscribe(function(newValue) {
self.selectedValue('b');
});
self.populate = function() {
self.array(['a','b','c']);
};
}());
ko.applyBindings(vm);
}());
And here's my workaround, which replaces "self.selectedValue('b');":
var waitForSelectToPopulate = function() {
self.selectedValue('b');
if(self.selectedValue() != 'b') {
setTimeout(waitForSelectToPopulate, 10);
}
};
waitForSelectToPopulate();
I am not very fond of this as a workaround. It seems like there should be a reasonable way to handle this, but just setting the value on subscribe trigger doesn't seem to work.
You need optionsAfterRender. Here's a fiddle:
http://jsfiddle.net/sifriday/hev1rqeu/4/
HTML -
<select data-bind="options: array, value: selectedValue, optionsAfterRender: setVal">
JS addition -
self.setVal = function() {
self.selectedValue('b');
}
Docs - http://knockoutjs.com/documentation/options-binding.html - and scroll down to Note 2
Once the populate event has gone and got the json and placed it into your array, why not just set the value right after? as soon as you set the data inside of self.array it will update.
(function() {
var vm = (function() {
var self = this;
self.array = ko.observableArray([]);
self.selectedValue = ko.observable();
self.populate = function() {
// magical assmagic goes and get's json, and converts it to ['a','b','c']
self.array(['a','b','c']); // dropdown is now populated
self.selectedValue('c'); // therefore we can set it to a valid value
};
}());
ko.applyBindings(vm);
}());
see the following:
http://jsfiddle.net/hev1rqeu/5/
I'm using a kendo grid.
I want to add a slide-down animation - when I click on a row in the grid it expands with animation
(the expansion happens with grid.ExpandRow function - kendo inner).
I think that I need the animation on k-detail-row element.
But I still cant find the proper place/way to do that.
Anyone did that already, and can help me with that.
Unfortunately animations are not supported for table rows. Here is a related question: How to Use slideDown (or show) function on a table row?
I had the same question, and although this is an old post, I figured someone might need it.
Unfortunately Kendo does not support this functionality as yet, however there is a solution.
Kendo uses the jquery toggle() to show and hide the detail row, thus by performing a conditional override on the jQuery you can insert animation.
jQuery(function($) {
var _oldShow = $.fn.show;
var _oldHide = $.fn.hide;
$.fn.show = function(speed, oldCallback) {
return $(this).each(function(index, item) {
var obj = $(item);
_oldShow.apply(obj, [speed, oldCallback]);
if (obj.hasClass("k-detail-row")) {
obj.find(".k-grid.k-widget").each(function () {
var grid = $(this);
grid.slideDown(300);
});
}
});
}
$.fn.hide = function (speed, oldCallback) {
return $(this).each(function () {
var obj = $(this);
if (obj.hasClass("k-detail-row")) {
obj.find(".k-grid.k-widget").each(function () {
$(this).slideUp(300, function () { _oldHide.apply(obj, [speed, oldCallback]); });
});
} else {
_oldHide.apply(obj, [speed, oldCallback]);
}
});
}
});
I ran into this issue today and managed to solve it using the detailExpand function of the grid. You can then use the Kendo Fx slidedown effect to make the detail row slide down. For example:
detailExpand: function (e) {
var detailRow = e.detailRow;
setTimeout(function () {
kendo.fx(detailRow).slideIn("down").duration(375).play();
}, 0);
}
For more information, please check:
Detailexpand documentation
Kendo Fx documentation