Get selected point(s) indices on zoom in Highcharts - javascript

I want to be able to zoom upon one or more point and get the associated Y value(s) for that point. So far I have got this, but without any success: http://jsfiddle.net/animeshb/8rdkb7t4/3/
var pointValue = this.series[0].data[index].y
I am not able to find the index of the selected point or selected points. What am I missing here?

Okay, this might not be the best way, but I got it working for a single point by doing the following:
var pt = Math.ceil(event.xAxis[0].min)
pointValue = this.series[0].data[pt].y;
http://jsfiddle.net/animeshb/8rdkb7t4/5/
So, to capture multiple points, I have expanded the above a bit further like this:
var minpt = Math.ceil(event.xAxis[0].min);
var maxpt = Math.ceil(event.xAxis[0].max);
var distance = maxpt - minpt;
if (distance == 1) pointValues.push(this.series[0].data[minpt].y);
else {
for (var i = minpt; i < maxpt; i++) {
pointValues.push(this.series[0].data[i].y);
}
}
pointValues.forEach(function (item) {
console.log(item);
});
return false;
http://jsfiddle.net/animeshb/8rdkb7t4/7/
The problem with this is, I get values even if I drag the selector above or below the points/markers.
I will continue to explore this and will update here if I have a solution.

Related

Use a var from mousedown() in the mouseup() event

So to those who looked at my previous question, im building a chess board in complete JS and jQuery (or mostly at least).
So for my pieces to effectivly be restricted in the amount of squares they are allowed to move i need to know their position. (starting and ending position)
I wrote the code below to log the starting row (integer) and starting column (integer) and do that on both mousedown() and mouseup()
var piece;
$('div').mousedown(function(e) {
e.preventDefault();
var selectedRow = this.getAttribute("data-row");
var selectedColumn = this.getAttribute("data-column");
console.log(selectedRow, selectedColumn);
piece = $(this).find('.pawn');
})
.mouseup(function() {
var selectedRow = this.getAttribute("data-row");
var selectedColumn = this.getAttribute("data-column");
console.log(selectedRow, selectedColumn);
if (selectedRow === selectedRow++ || selectedColumn === selectedColumn++){
console.log('TRUE :D'); //Wont be true because both selectedRow's will be the same value
}
$(this).append(piece);
});
For as far as i can see i cant compare both values since both logs are in different events. (please keep in mind that im new to both languages and im still learning).
My question would be if its possible to collect both values (starting and ending) and then being able to compare them to each other.
The easiest approach is to make a selectedRow_down and selectedColumn_down
selectedRow_up and selectedColumn_up in global scope.
var selectedRow_down;
var selectedColumn_down;
var selectedRow_up;
var selectedColumn_up;
$('div').mousedown(function(e) {
e.preventDefault();
var selectedRow_down = this.getAttribute("data-row");
var selectedColumn_down = this.getAttribute("data-column");
piece = $(this).find('.pawn');
})
.mouseup(function() {
var selectedRow_up = this.getAttribute("data-row");
var selectedColumn_up = this.getAttribute("data-column");
console.log(selectedRow_up, selectedColumn_up);
$(this).append(piece);
});
then refer to its value as you do your mouse event
also you could make global 2 dimensional array first so could keep track of your chess pieces, see this thread how to create 2d arrays
How can I create a two dimensional array in JavaScript?

How to avoid using filter twice against the same set of elements

I'm trying to separate two types of inputs into their own jQuery wrapped sets as they need to be processed differently depending on whether the id contain '-add-new-' or not. I know I could do this using filter twice as follows:
var seriesTabInputs = $msSeriesTabs.find('input').filter(function() {
return $(this).attr('id').indexOf('-add-new-') == -1;
});
var addNewTabInputs = $msSeriesTabs.find('input').filter(function() {
return $(this).attr('id').indexOf('-add-new-') >= 0;
});
However filtering twice seems inefficient to me as I know it will require a second loop. Is there a way to avoid this?
Try like below:
var addNewTabInputs = $msSeriesTabs.find('input[id*="-add-new-"]');
var seriesTabInputs = $msSeriesTabs.find('input[id]:not([id*="-add-new-"])');
OR
var addNewTabInputs = $msSeriesTabs.find('input[id*="-add-new-"]');
var seriesTabInputs = $msSeriesTabs.find('input[id]').not(addNewTabInputs);
Just to offer an alternative to using specific selectors, you could iterate through the jQuery set and build the two collections as you go. I don't know that this would be any faster due to the different operations applied to the collections.
var $inputs = $msSeriesTabs.find('input');
var seriesTabInputs = [];
var addNewTabInputs = [];
for (var i = 0; i < $inputs.length ; i += 1)
{
var input = $($inputs[i]);
if ( $(input).attr('id').indexOf('-add-new-') >= 0 )
{ addNewTabInputs.push(input); }
else
{ seriesTabInputs.push(input); }
}
seriesTabInputs = $(seriesTabInputs);
addNewTabInputs = $(addNewTabInputs);
Avoiding filtering twice may not be so crucial unless you are dealing with an enormous amount of elements. Furthermore there is something to be said for the consistency of the code when you filter twice.
That being said there is a way to avoid filtering twice and it may even be instructional; below is some code that can be used to achieve this.
First, we create an empty wrapped set that can be added to, this is achieved by var seriesTabInputs = $(false); Please see this write-up for more information.
Then inside of the filter, we conditionally add to seriesTabInputs but note the way in which we do it: we continually re-assign with seriesTabInputs = seriesTabInputs.add($(this)); If instead you merely call seriesTabInputs.add($(this)) without assigning to seriesTabInput you will wind up with an empty array in the end. Please see the jQuery docs for .add() which gives a similar incorrect example and states that such usage "will not save the added elements, because the .add() method creates a new set".
var seriesTabInputs = $(false);
var addNewTabInputs = $msSeriesTabs.find('input').filter(function() {
if ($(this).attr('id').indexOf('-add-new') >= 0) {
return true;
}
else {
seriesTabInputs = seriesTabInputs.add($(this));
}
});

For Loop Manipulate Multidimensional Array Javascript

Okay so I have a 2D array that I am trying to alter using javascript. This is what I have so far:
for (var i = 0; i <= inputData.length; i++ {
inputData[0,0] = inputData[0,0];
inputData[i,0] = inputData[((i - 1) + 1/12), 0];
I want this to take array [i-1] value and then add 1/12 to it
for (j = 13; inputData.length; j += 13) {
delete inputData[j,0];
delete inputData[j,1];
}
Also, I want to delete the entire 2D array at every 13th increment value.
}
This is what I have so far. I am sure there are probably errors within it. Can you guys help me out here? Any help would be greatly appreciated.
Couple of things - you need to be careful when iterating over an array that you're removing from, your indexes will end up offset with respect to your data as soon as you do a delete. Secondly your syntax for deletion is off.
Normally in these situations I favour creating a new array containing the data I want to keep.
var inputData = [[1,1],[2,2],[3,3],[4,4]];
var b = [];
for (i=0; i < inputData.length; i++) {
if ((i + 1) % 13 != 0) {
var year_with_month = inputData[i][0] + i * 1/12;
var e = [year_with_month, inputData[i][1]]
b.push(e);
}
}
inputData = b;
Also, given a choice I'd use a library like underscore to make it easy to do the looping. I never manually write for loops anymore, took me a couple of attempts to get that one right :)

jQuery grep return on Multidimensional Array

I am learning jQuery and am having issues trying to figure out how to select elements in a multidimensional array. I have a select list with database IDs and I want to set a var with the cost field in the database according to the id that selected. I have all the pieces except for translating the selected ID to a cost. Can someone please help me with getting this right please?
var rangeListData = [{"idrange_list":"1","range_cost":"0","target_range_name":"Self Only"},{"idrange_list":"2","range_cost":"1","target_range_name":"1 Space"},{"idrange_list":"3","range_cost":"2","target_range_name":"2 Spaces"},{"idrange_list":"4","range_cost":"3","target_range_name":"3 Spaces"},{"idrange_list":"5","range_cost":"4","target_range_name":"4 Spaces"},{"idrange_list":"6","range_cost":"5","target_range_name":"5 Spaces"}];
$('#slctPowerTarget').change(function () {
var targetID = $('#slctPowerTarget').val();
var cost $.grep(rangeListData, function(e) { return e.idrange_list == targetID }); // this is the line that is wrong
$('#spanTotalEffectsCost').text(cost);
});
If I put targetID in where cost is it lists fine. But when I try to look this up nothing happens. It is not right somehow and I am not sure what else to try. I think I get how idrange_list == targetID is supposed to match them but not sure how to call the related range_cost.
Thanks for any help you can offer! I read through the docs at jquery.com but can't seem to wrap my head around them.
You can do this :-
// Get the Multidimensional Array first
var data = $.grep(rangeListData, function (e) {
return e.idrange_list === targetID
});
// Get the range cost from the array
var cost = data[0].range_cost;
// Check the value in console for debugging purpose
console.log(cost);
Here is the final code. I also added an IF clause in there in case they select the default setting. This way it will reset instead of tossing an error and keeping page calculations working no matter if they change the drop downs or go back to "Select..."
$('#slctPowerRange').change(function () {
var rangeID = $('#slctPowerRange').val();
if (rangeID > 0) {
var rdata = $.grep(rangeListData, function (e) {
return e.idrange_list === rangeID
});
var rcost = rdata[0].range_cost;
}
else {
var rcost = 0 ;
}
$('#hdnRangeCost').val(rcost);
});

JavaScript: cycle through an array (rather than pop)?

I'm creating map markers, and I want to assign a different colour to each county on the map.
I don't know in advance how many counties there will be showing on the map, so I need to figure out a way to assign an unlimited number of colours.
At the moment, I'm assigning a colour to each county using the following code, but I run into a problem when I pop() the list too many times:
var colours = ['6183A6', '3A66A7', '3B4990', '5B59BA'];
var h_colours = []; // associative array
function addMarker(county, colour) {
if (colour==undefined) {
if (h_colours[hundred]==undefined) {
h_colours[hundred] = colours.pop();
} } }
Is there a way I could cycle through the list without actually deleting items, and continuing from the start of the list when I reach the end?
thanks!
Yes.
var getNextColour = (function() {
var colours = ['6183A6', '3A66A7', '3B4990', '5B59BA'];
var cc = 0;
return function() {
var rv = colours[cc];
cc = (cc + 1) % colours.length;
return rv;
};
})();
Now you can just say:
if (colour == undefined) colour = getNextColour();
or simply
colour = colour || getNextColour();
Of course, applying the colors to the elements of the map such that you don't color adjacent areas with the same color is a considerably more interesting problem.
You can use a counter for the index in the array.
Increment whenever you fetch a color, reset it to 0 when it is the size of the array -1.

Categories

Resources