Highcharts how to use js object in PHP widget - javascript

My question is similar to this one: Highcharts how to use JavaScript variable as series data source? - except mine is a php variable.
I'm using https://github.com/2amigos/yii2-highcharts-widget this package with Yii2 and I've generated a data array which looks like this:
Array
(
[0] => {y: 37.50, color: "#BF0B23"}
[1] => 49.25
[2] => 52
)
I cast the numbers to floats when generating this array, but I couldn't do this with the object. When the graph is rendered the columns all work fine except for the one that I am trying to change the colour for.
The JS ends up like this "data":[37.5,49.25,"{y: 52.00, color: \"#BF0B23\"}"]. The js object being quoted basically means it isn't rendered. I've tried array_values(), (casting) and some other weird and wonderful manipulation to try and remove the quotes. I'm hoping there is a way to easily remove the quotes?

I guess you are trying to convert PHP hash into JSON, which then should be rendered by highcharts?
Try json_encode php function for that - http://php.net/manual/en/function.json-encode.php

Ok, I managed to figure out how to do it. Thanks #paweł-fus because your comment got me thinking about it a different way.
In my previous non-yii2, non 2amgios package I was generating my object as a string and writing it directly into JS.
if($d['ATTENDING'] === $data['ATTENDING'])
{
$a[] = array($data['ATTENDING'] => '{y: ' . number_format($data['PERCENTAGE'], 2) . ', color: "#BF0B23"}');
} else {
$a[] = array($data['ATTENDING'] => number_format($data['PERCENTAGE'], 2));
}
So my array either showed the column value, or if the column value was special it showed the value and i also changed its colour. This was represented as a JS object.
What I need to do was this though, create an inner array for the js object in php and typecast the value so it wasn't a string.:
$a[] = array($data['ATTENDING'] => ['y' => (float) number_format($data['PERCENTAGE'], 2), 'color' => '#BF0B23']);

Related

Highcharts data from a variable is not working but from works fine from an array

I am very new to JavaScript and Highcharts so thank you in advance. I am trying to create a simple chart using Highcharts. When I manuayy create the variable using this array the chart works:
let result = [1084.58,1084.65,1084.64]
However, when when I grab the data from JSON and put that into the variable the chart does not show the data. If I "alert" the variable that is created from the JSON is appears like this:
1084.58,1084.65,1084.64
I am guessing the format of the data from the JSON is not correct. What should I do to correct it?
When I use the manually created variable the chart appears correctly. When I create the variable from the JSON file the chart appears and the X axis has the correct labels but no data in the chart.
I did some testing and found what I think is the issue. The variable that is created from the JSON has quotes around each entry. How can I remove the quotes?
['1084.58', '1084.65', '1084.64']
You'll probably need to convert those values to Number type (using Number() or parseFloat()), you can do something like this:
variable => contains ['1084.58', '1084.65', '1084.64']
variable = variable.map(number => {return Number(number)})
Since you're new to Javascript (Welcome to this language!), I'm gonna explain how it works.
"map" is an array method which takes each element of an array and returns an value (simillar to forEach method, but forEach doesn't return anything). So when using map to return each element of an array like this you're pushing the new element to the new array, it will be something like
variable.map(number => {return Number(number)})
On the 1st element:
It returns Number('1084.58'), then it returns 1084.58 (number type)
On the 2nd element:
It returns Number('1084.65'), then it returns 1084.65 (number type)
On the 3rd element:
It returns Number('1084.64'), then it returns 1084.64 (number type)
Each return into this new variable is like an array.push(element)
Hope you got the idea

JSON decode list of lists in Django Python

I have a list of lists (e.g. [[1,2],[3,4]]) passed from a Django view to a javascript variable and submitted with jQuery. I need to parse that variable to pull indices. The basic process is:
Add as context variable (python):
resultMsgList.append(msg)
resultMsgListJson=json.dumps(resultMsgList)
resultDict['resultMsgListJson']= resultMsgListJson
Javascript:
var resultMsgList = {{resultMsgListJson}};
var data = {'resultMsgList':resultMsgList};
$.post(URL, data, function(result){
});
Google Console gives me:
Javascript:
var resultMsgList = [["View \"S03_2005_LUZ_140814_105049_with_geom\" was successfully created!", "luz_mapfile_scen_tdm_140814_105049", "S03_2005_LUZ_140814_105049_with_geom", "C:/djangoProjects/web_output/mapfiles/ATLANTA/luz_mapfile_scen_tdm_140814_105049.map", [25, 50, 498.26708421479, 131137.057816715]]];
I copied this result to a validator, which states it is correct JSON.
The post gives me:
resultMsgList[0][]:View "S03_2005_LUZ_140814_105049_with_geom" was successfully created!
resultMsgList[0][]:luz_mapfile_scen_tdm_140814_105049
resultMsgList[0][]:S03_2005_LUZ_140814_105049_with_geom
resultMsgList[0][]:C:/djangoProjects/web_output/mapfiles/ATLANTA/luz_mapfile_scen_tdm_140814_105049.map
resultMsgList[0][4][]:25
resultMsgList[0][4][]:50
resultMsgList[0][4][]:498.26708421479
resultMsgList[0][4][]:131137.057816715
I need to get elements from this list. I currently have (python):
resultMsgListContext = request.POST.get('resultMsgListJson','')
resultMsgListContext = json.loads(resultMsgListContext)
oldMapfileName=resultMsgListContext[0][2] (+ a number of similar statements)
According to this post I then need to decode the variable in python with json.loads(), but it says there is no JSON object to be decoded. Based on the examples in the Python docs, I'm not sure why this doesn't work.
I believe the problem is that it is viewing the entire resultMsgList as a string, substantiated by the fact that there is a u' xxxxx ' in the result. That's why it is saying index out of range because you're trying to access a 2D array when it is still a string. You have to convert it to an array of strings by using json.loads.
In javascript, try passing
var data = {'resultMsgListJson':resultMsgList};
instead of
var data = {'resultMsgListJson': resultMsgListJson};
resultMsgListJson isn't a javascript variable that's defined at that point, it might be getting evaluated to undefined.
In general, in python, print the contents of resultMsgListContext before trying to do json.loads on it so you can see exactly what you're trying to parse.

Append JSON data into custom JQuery function

I am attempting to load some json data into a custom JQuery function. There is probably an easy solution to this by I am admittedly learning as I go. Please advise if I am just going about it the wrong way.
As of now I am just appending it into the body to ensure that I am actually finding the data properly. I was trying to use append() to add it into the function as well but was not getting any where.
$.getJSON("designs/new.json",function(result){
$.each(result, function(i, field){
$("body").append(field['hex'] + " ");
});
});
Essentially what I'd like to do is replace the hex data values for this colorPicker function with the hex codes from my json data above. I've been messing with it for a while and can't seem to find the right approach.
$.fn.colorPicker.defaults.colors = ['000', '000', 'fff', 'fff'];
I appreciate the help in advance!
Try using alert(JSON.stringify(result)) to see if your json data is loaded properly. This code should work:
$.getJSON("t.json", function (result) {
//alert(JSON.stringify(result));
$.fn.colorPicker.defaults.colors = result.colors;
});
where t.json has the following content:
{
"colors": ['00a', '00b', 'ffa', 'ffb']
}
If I understand correctly:
1) Your JSON returns an array of objects (presumably four?) that each have a "hex" property.
2) You want to set the color picker's default colors based on these four hex properties.
So, assuming that my assumptions are correct and your array is properly ordered, you could do something like this:
$.getJSON("designs/new.json",function(result){
$.fn.colorPicker.defaults.colors = $.map(result, function(i) {
return i.hex;
});
});
I've mapped the hex properties to an array and assigned it directly to the colors. Again, this is assuming you have an array of four objects in your result object, each with a hex property.

How to dynamically update drop-down list options with values in a server-generated array

I have a web form with two drop-down boxes, and I'm looking for a way to dynamically update the options of the second box based on selections from the first.
The first box represents a data type, and the second box is a list of databases associated with the selected type.
I have the basic code running smoothly here:
var TypeA_DbSuffixList = ['Test1', 'Test2', 'Test3'];
var TypeB_DbSuffixList = ['TestA', 'TestB', 'TestC'];
function fill_dbSuffixList(){
document.getElementById("dbSuffixList").options.length = 0;
var suffixMenu = document.getElementById("dbSuffixList");
var dataFormat = document.getElementById("dataFormatType");
var suffixList = dataFormat.value + "dbSuffixList";
if (suffixList == 'TypeA_dbSuffixList') {
for(index in TypeA_dbSuffixList) {
suffixMenu.options[suffixMenu.options.length] = new Option(TypeA_dbSuffixList[index], index);
}
}
if (suffixList == 'TypeB_dbSuffixList') {
for(index in TypeB_dbSuffixList) {
suffixMenu.options[suffixMenu.options.length] = new Option(TypeB_dbSuffixList[index], index);
}
}
}
That code (activated whenever a selection is made in the dataType box) clears the existing list of options and repopulates the list based on the selected value of the "dataFormatType" box.
The problem that I face is that the actual lists of database tables are not hard coded and are instead generated with the following calls to the server to avoid repetitive editing of the page every time a new database is added:
var TypeA_dbSuffixList = ${TypeA_dbSuffixList};
var TypeB_dbSuffixList = ${TypeB_dbSuffixList};
These calls return the following code:
var TypeA_dbSuffixList = [Test1, Test2, Test3];
var TypeB_dbSuffixList = [TestA, TestB, TestC];
With the above code, the initial function treats each entry in the type arrays as an undefined variable, and nothing is ever written to the drop-down list.
If I were to add
var Test1 = "Apple";
var Test2 = "Orange";
var Test3 = "Grape";
prior to the "for" loop for TypeA, then selecting TypeA from the dataType drop-down list returns "Apple", "Orange", and "Grape" as the available databases for TypeA.
Visually, I see what needs to be changed. The [Test1, Test2, Test3] returns need to be ['Test1', 'Test2', 'Test3']. I'm just unsure exactly how to go about changing it, and have exhausted every web search I can think of.
Is there a way to either change the format of the returned arrays, or use the existing format and pass variable names as drop-down selections instead of using variable values?
Any help is greatly appreciated. I will continue to search for an answer on my own as well and will post it here should I find one.
I think the cleanest solution would be to change the code on the server-side to generate a proper JavaScript array of Strings, with the values enclosed in single or double quotes.
If that's not possible for some reason, and you want a pure-JavaScript solution, then I suggest you wrap the entire JSP/ASP/PHP variable (not sure what framework you're using) in double quotes, strip the string of brackets and spaces using a regex, and then split it into a string array using the comma as a delimiter.
So in your JavaScript, this:
var TypeA_dbSuffixList = ${TypeA_dbSuffixList};
would become this:
var TypeA_dbSuffixList = "${TypeA_dbSuffixList}".replace(/[\[\]\s]/g,"").split(",");
I think the best way to convert data in a server side language into something to be used in JavaScript is to JSON encode your objects.
I'm not sure what language your using on the server, but in PHP you can do the following
var arr = <?php echo json_encode( array ('abc', 'def', 'ghi') ); ?> ;
And your output will be
var arr = ['abc', 'def', 'ghi'] ;
This will make sure that strings with embedded new lines, tabs, quotes are properly escaped.
JSP
You said you're using JSP but the code you have looks more like velocity or free marker inside JSP. In JSP you could use the following, provided you download Gson
var TypeA_dbSuffixList = <%= new Gson().toJson(TypeA_dbSuffixList) %>;

jQuery: $.getJSON sorting the data on Chrome / IE?

I'm passing an associative array (id => val) using Ajax and receiving it with jQuery's $.getJSON which read the data properly and prepared the object. There is, however, very annoying sorting issue.
It appears that on Chrome and IE the data becomes sorted by the id part of the associate array. So if the array should be (5=> 'xxx', 3 => 'fff') it actually becomes (3 => 'fff',5=> 'xxx'). On FireFox it works as expected, i.e. not sorted.
Any ideas?
You can add a leading 0 for all integer indexes.
var json = { '05' => 'xxx', '03' => 'fff' };
Seems the best way is to avoid associative arrays at all. When you want to send an associate array simply send it as two separate arrays - one of keys and one of values. Here's the PHP code to do that:
$arWrapper = array();
$arWrapper['k'] = array_keys($arChoices);
$arWrapper['v'] = array_values($arChoices);
$json = json_encode($arWrapper);
and the simple JavaScript code to do whatever you'd like with it
for (i=0; i < data['k'].length; i++) {
console.log('key:' + data['k'][i] + ' val:' + data['v'][i]);
}
Another option is to return the data as an array of objects. That will ensure that the objects stay in the order that you return them.
Edit:
Basically, for each key > value pair, push it to a new array and json_encode that array.

Categories