Say I have a list of a serie name outside the plot, when I hover at one of them I want to set one of the series highlighted(hovered).
This is AFTER the the plot is rendered.
How can I achieve this(I am also using jQuery)
Thank for #Paweł Fus's help.
Finally, I use below way to solve this problem. Since I do not have id in my series array, I use $each() to compare the name
var chart = $plotResult.highcharts();//get the chart object
var highlightSerieCallback = function(e){//mouse in callback
var seriesName = $(this).find(':first-child').text();
console.log('serieName hightLight',seriesName);
$.each(chart.series, function(i, s) {
if(s.name == seriesName){
s.onMouseOver();
return false;//break the each
}
});
};
var disHighlightSerieCallback = function(e){//mouse leave callback
var seriesName = $(this).find(':first-child').text();
console.log('serieName DisHightLight',seriesName);
$.each(chart.series, function(i, s) {
if(s.name == seriesName){
s.onMouseOut();
return false;//break the each
}
});
};
$sumAndAvgResultWrap.find('tr:not(:first-child)').hover(highlightSerieCallback,disHighlightSerieCallback);//bind the callback
Related
I need add row in datatable, but the number the colums is variable.
I try two each but not run because row.add need all row not 1 to 1.
var obj = $.parseJSON(res);
$.each(obj, function (index) {
$.each(obj[index], function (value) {
table.row.add([obj[index][value]]).draw();
});
});
Is possible add row without knowing the number of columns?
Edit:
So If you have a variable number of columns the only way you'd be able to still use the datatable most likely is by inserting blank values into the columns of rows which don't posess the maximum amount of values, ex:
table.row.add(['a','b','c','d']).draw();
//Above is a row which has all the 4 column values
//Beneath is a row with 3 out of 4 column values
table.row.add(['a','b',null,'d']).draw()
/*or*/
table.row.add(['a','b','','d']).draw()
I'm not quite sure where you've gotten the idea that row.add() needs all rows added at once.
https://datatables.net/reference/api/row.add() according to the official documentation this method is able to add single rows to your table without any problem.
Here a JSFiddle proving that a single row can be added to the already existing ones:
myTable.row.add(["Airi Satou", "This was", "added", "later", "EXAMPLE", "ITEM"]).draw();
http://jsfiddle.net/bbLjzspf/8709/
Firstly, there is an error in your script, perhaps a typo, there is an extra square bracket after [obj][index][value] "]".
var obj = $.parseJSON(res);
$.each(obj, function (index) {
$.each(obj[index], function (value) {
table.row.add(
[obj[index][value] >]<-- One too many brackets ).draw();
});
});
Then my suggestion.
First I make two little helpers...
One to count the number of columns:
$.fn.DTbl_columnCount = function () {
return $('th', $(this).find('thead')).length;
};
And since I've got no idea what kind of data is coming, the next one is all belts and buckles, erm, in a "whatever" version, that also accepts arrays ;)
$.fn.DTbl_createDataColumns = function (whatever) {
var temp = new Array($(this).DTbl_columnCount());
var value = "";
var type = jQuery.type(whatever);
var isArray = (type == "array");
if (!isArray && type != undefined)
value = whatever;
for (var i = 0; i < temp.length; i++) {
if (isArray)
if (whatever.length > i)
value = whatever[i];
temp[i] = '' + value;
value = "";
}
return temp;
};
And then to your problem, since these additions are not really part of DataTables we need to fetch the DataTable Id in the function call of DTbl_createDataColumns, here using the standard reference "#example".
var obj = $.parseJSON(res);
$.each(obj, function (index) {
$.each(obj[index], function (value) {
table.row.add(
$("#example").DTbl_createDataColumns([obj[index][value])
).draw();
});
});
So this would also work:
var myArray = ["Dodaa", "Dodee"];
table.row.add( $("#example").DTbl_getDataColumns(myArray) );
table.row.add(['a','b','','d']).draw()
didn't work for me.
I have to do
table.row.add([['a','b','','d']]).draw()
Also it is important to be consistent between data types of dictionary and array. DataTable does NOT like it if we mix dictonaries and arrays in different calls. For example we might need to do (if it is initialized with an array of dictionaries).
table.row.add([{'hdrCol1': 'a', 'hdrCol2':'b','hdrOfCol3':'', 'hdrCol4':'d'}]).draw()
I need to save all the color values of the elements in the pages of my site and put them in a database. I thought I'd do it this way:
First thing I'm going to pick up the rgb values of each element so
$("*").each(function(e){
createColorArray($(this).css('backgroundColor'));
});
then in the function createColorArray store into an array all the values that are passed
function createColorArray(rgbColor)
{
//Create rgb array
}
and finally remove duplicate items from my array
function removeDoupe(ar) {
var temp = {};
for (var i = 0; i < ar.length; i++)
temp[ar[i]] = true;
var r = [];
for (var k in temp)
r.push(k);
return r;
}
now my question is,
how recommended to create the array? directly inside the $ ("*") or in a dedicated function as I'm thinking? also i need than once removed duplicates in the new array "clean" as well as the rgb value I would have also given the number of times that value was in the original.
Some example code?
As I mentioned in the comments, why not check for duplicates earlier? A simple example:
var colors = [];
$('*').each(function(i, el){
var $element = $(el),
color = $element.css('background-color');
if(!~$.inArray(color, colors))
colors.push(color);
});
console.log(colors);
http://jsfiddle.net/sL9oeywk/
The best way to do this is to do it all while you are working on it. Heres a way you could potentially do it:
var colors = new Array();
var tempColors = {};
$(".colors").each(function(){
var c = $(this).val();
// check if the color exists without looping
if(typeof tempColors[c] == "undefined"){
// if it doesn't, add it to both variables.
tempColors[c] = true;
colors.push(c);
}
});
This will result in two variables: one is an object that you don't have to loop through to find out if you defined it before, one is a colors array that you push to using standard javascript.
You shouldn't make it a dedicated function if you are not reusing it, but you could make it an object like this:
var colors = function(){
var self = this;
self.array = new Array();
// this is a dedicated check function so we don't need separate variables.
// returns true if the color exists, false otherwise
self.check = function(color){
for(var i =0; i < self.array.length; i++){
if(self.array[i] === color) return true;
}
return false;
}
self.add = function(color){
// use the check function, if it returns false, the color does not exist yet.
if(!self.check(color)){
self.array.push(c);
}
}
}
You can then instantiate a colorlist using var colorlist = new colors(); and add colors using colorlist.add("dd0300"). Accessing the array can be done by requesting colorlist.array.
I am having some problems with my JavaScript and amCharts graph.
What I am trying to achieve is to reload an amChart line graph with new data from a DIV element. In my final page this DIV element will be dynamically updated and hidden so will not been seen by the end user. The graph needs to be redrawn without reloading the page.
I have an JSFiddle page with an example of my attempts to reload the data.
http://jsfiddle.net/gnuoynomis/Se2UE/1/
I have tried to:
Make objects of the points and add them into a string creating a string of objects but this does not seem to load into the graph.
function LoadNewDataFromDIV_V1()
{
//This function attempts to use a string of objects to pass to the dataprovider setting
var ChartData = document.getElementById("NewData").innerHTML;
var CD = ChartData.split("},{"); //Split the string on the different day elements
var NewChartData = "";
for(i=0; i<CD.length; i++)
{
var D = CD[i];
D = D.replace("{",""); //Remove any additional { that may exist to help with the formating later
D = D.replace("}",""); //Remove any additional } that may exist to help with the formating later
D = "{" + D + "}"; //Add a { and } to reformat the line correctly from the splitting
if(NewChartData != "")
NewChartData += ",";
NewChartData += JSON.parse(D); //Add the parsed object to the data string
}
chart.dataProvider = NewChartData; //Update graph data
chart.validateData(); //Revalidate chart data
}
I have also tried adding the objects into an array and tried passing this but still no luck.
function LoadNewDataFromDIV_V2()
{
//This function attempts to use an array to store the data and pass this to the dataprovider setting
var ChartData = document.getElementById("NewData").innerHTML;
var CD = ChartData.split("},{"); //Split the string on the different day elements
var NewChartDataArray = [];
for(i=0; i<CD.length; i++)
{
var D = CD[i];
D = D.replace("{",""); //Remove any additional { that may exist to help with the formating later
D = D.replace("}",""); //Remove any additional } that may exist to help with the formating later
D = "{" + D + "}"; //Add a { and } to reformat the line correctly from the splitting
NewChartDataArray.push(D); //Push the data to the array
}
chart.dataProvider = NewChartDataArray; //Update graph data
chart.validateData(); //Revalidate chart data
}
My reset of the graph works perfectly if I add the entire string straight in manually and this is what I am trying to replicate with the other methods.
If anyone is able to point out what I am doing wrong then I would be most grateful. I am also open to any suggestions if you think that I could be doing this in a better way.
working fiddle
http://jsfiddle.net/Se2UE/2/
the core of my change is here
var NewChartDataArray = [];
for(i=0; i<CD.length; i++)
{
var D = CD[i];
D = D.replace("{","");
D = D.replace("}","");
D = "{" + D + "}";
NewChartDataArray.push(JSON.parse(D));
}
declare NewChartDataArray as array and not string then add an object to array.
You had an array of strings, your library expects an array of objects
refer this
I have 2 arrays, one with cities, and another array with ID's...
I would like to loop both, and then output some HTML
Right now im only looping cities, and then appending some HTML to a as following:
if ($jq(".area").length > 0) {
var region = $jq(".hiddenFieldRegion").val();
var cityIDs = $jq(".hiddenFieldChosenAreas").val();
var strcities = $jq(".hiddenFieldChosenCities").val();
//var cities = strcities.split('|');
//Set region to be marked
if (region) {
$jq(".mapdk").attr("class", region);
}
//Appending to searchform
if (strcities) {
$jq.each(strcities.toString().split("|"), function (k, v) {
var v = v.split("|");
$jq("<option selected />").text(v[0]).appendTo("select.chosen-cities");
});
}
}
I would like the place where im appending to the searchform, add an attribute value, with an ID from the cityIDs array...
So i get some HTML like:
<option value="XXX">CityName</option>
Is that possible?
Assuming your cities IDs and your cities names are orderred in the same way, you can access each name/id by this index in the arrays :
var cityIDs = $jq(".hiddenFieldChosenAreas").val();
var strcities = $jq(".hiddenFieldChosenCities").val();
var cityIDs_array = cityIds.split("|");
var strcities_array = strcities.split("|");
....
if (strcities) {
$jq.each(strcities_array, function (k, v) {
//var v = v.split("|"); Unnecessary if strcities is like "city1|city2|city3"
$jq("<option value='"+cityIDs_array[k]+"' />").text(v).appendTo("select.chosen-cities");
});
}
In this, way, you can access each city ID in your loop.
But I think you should store city name and city id in the same string. For example "city1:1|city2:2|city3:3". Then, with some use of split function, you'll get id and name.
Assuming the order is the same in both arrays you can use the index parameter (k) of the each function:
if (strcities) {
var aCityIDs = cityIDs.split("|");
$jq.each(strcities.toString().split("|"), function (k, v) {
var v = v.split("|");
var id = aCityIDs[k];
$jq("<option selected value='"+id+"' />").text(v[0]).appendTo("select.chosen-cities");
});
}
This is easy enough if your two arrays are in parity with one another with regards to indexing - loop over one, then look up a value in the other array at the same index.
//simulate environment
var strcities = 'one|two|three',
cityIDs = '1|2|3';
//main code
var ids = cityIDs.split('|');
$.each(strcities.toString().split("|"), function (index, val) {
var opt = $("<option />", {value: ids[index], text: val}).appendTo("select.chosen-cities");
/* if (index == 2) opt.prop('selected', 'selected'); /*
});
A few points of note:
you were splitting on | once in the $.each and again inside it. Since this would be illogical (any | would have disappeared after the first split) I removed it.
you were adding selected to each option. If you simply want the first option to be selected, you don't need to add anything in. If you want a specific option to be selected, see the line I commented out, which selects the 3rd element.
http://jsfiddle.net/DhH3U/
Another example:
var strict = ('aaa|eeee|dddd').split('|');
var id = ('1|2|3').split('|');
$.each(strict, function (k) {
$("<option selected />").text(strict[k]).appendTo("select.chosen-cities").attr('value',id[k]);
});
What is the certified way to determine the index of the currently selected item in a ComboBox in ExtJS?
Is there a difference on how to do this between ExtJS 3.x and 4?
var combo = new Ext.form.ComboBox(config);
var selectedIndex = combo.selectedIndex; // TODO: Implement
if(selectedIndex > 2) {
// Do something
}
Bonus-points for how to add it as a property to the ComboBox-object.
I think you'll have to use the combo's store for that. Combos have a private findRecord method that'll do a simple search over the store by property and value. You can see an example in the sourcecode itself (Combo.js line 1119).
1) Based on this you could find the selected index this way :
var v = combobox.getValue();
var record = combobox.findRecord(combobox.valueField || combobox.displayField, v);
var index = combobox.store.indexOf(record);
2) Or you could bind yourself to the "select" event which is fired with the combo, the record selected and its index as a parameter.
3) You could also access the view's getSelectedIndexes() but I doubt it's a good solution (in that I'm not sure it's available all the time)
Finally if you want to extend the combobox object I think this should work (if you go with the first solution) :
Ext.override(Ext.form.ComboBox({
getSelectedIndex: function() {
var v = this.getValue();
var r = this.findRecord(this.valueField || this.displayField, v);
return(this.store.indexOf(r));
}
});
In Ext 4.0.2 the same code would look like:
Ext.override(Ext.form.ComboBox, {
getSelectedIndex: function() {
var v = this.getValue();
var r = this.findRecord(this.valueField || this.displayField, v);
return(this.store.indexOf(r));
}
});
Jad, you're missing a closing parenthesis on your return statement... just thought you should know.
If you have a combo where valueField is the id used by the combo's store, you can simply avoid the search:
var v = combobox.getValue();
var record = combobox.findRecord(combobox.valueField || combobox.displayField, v);
var index = combobox.store.indexOf(record);
using this:
var id = combobox.getValue();
var record = store_combobox.getById(id);