I want to serialize a JSON string but when I pass JSON to view I see that my properties in code are in string format, that's probably why my code didn't work.
Serialization of my code in code behind:
var data = new ChartData
{
labels = new ChartLabels
{
labels = new string[3] {"Open", "Close", "Nothing"}
},
datasets = new ChartDatasets
{
data = new int[3] {20, 10, 3},
backgroundColor = new string[3] {"#ccf9d6", "#ccf9d6", "#ccf9d6"},
borderWidth = 1
}
};
var json = new JavaScriptSerializer().Serialize(data);
ScriptManager.RegisterStartupScript(
this,
GetType(),
"ServerControlScript",
"addChart(" + json + ");",
false);
And I want to use it in my JavaScript function:
function addChart(data) {
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, data);
EDIT:
Json looks like below:
{"labels":
{
"fontSize":0,
"boxWidth":0,
"labels":["Open","Close","Nothing"]},
"datasets":{"label":null,"data":[20,10,3],
"backgroundColor":["#ccf9d6","#ccf9d6","#ccf9d6"],
"borderWidth":1
}
}
Is there any way to convert it to correct format? Or just put it to a JavaScript variable?
As stated on MDN,
The JSON.parse() method parses a JSON string, constructing the
JavaScript value or object described by the string.
Seeing as the addChart javascript method call is being executed, but is getting a string instead of the expected JSON object, that string has to be parsed.
Without knowing the broader context of the application it is hard to give a great answer as there are a few ways you could accomplish your goal. The simplest though would be to change the line "addChart(" + json + ");", to "addChart(JSON.parse(" + json + "));", so that when the application executes this javascript, the json string will be parsed by the javascript engine and made into a javascript object the addChart method is expecting.
I am not hip to the ScriptManager and I kind of like things to appear as I expect when I do my debugging in Chrome so this is how I would attack it using an asp:Literal on the page.
ASP Page:
<script src="assets/js/bootstrap.js" type="text/javascript">
</script>
<asp:Literal runat="server" ID="aspchartdata"></asp:Literal>
Code Behind:
var data = new ChartData
{
labels = new ChartLabels
{
labels = new string[3] {"Open", "Close", "Nothing"}
},
datasets = new ChartDatasets
{
data = new int[3] {20, 10, 3},
backgroundColor = new string[3] {"#ccf9d6", "#ccf9d6", "#ccf9d6"},
borderWidth = 1
}
};
aspchartdata.Text = "<script> var data=" + JsonConvert.SerializeObject(data); + "</script>";
Now you have a data variable in Javascript to use.
On the server side your literal is replaced by your new script to define the variable and now you can handle the onload running and such from within the ASPX page in a neat fashion.
Related
It is to draw a plot graph on a web page using Python and js code.
Here's my python code
from bottle import route, run, request, redirect, template
import pymysql as sql
#route('/print')
def show_print():
db = sql.connect(host='localhost', user='root', password='1234', db='testdb')
if db is None:
return template("index.tpl", text="Non", x_value=[], y_value=[])
else:
query = "select * from testdata;"
cur = db.cursor()
n = cur.execute(query)
tpl_no=[]
tpl_date=[]
tpl_hum=[]
tpl_tmp=[]
for i in range(n):
value = cur.fetchone()
tpl_no.append(value[0])
tpl_hum.append(value[2])
return template("index.tpl", x_value = tpl_no, y_value = tpl_hum)
db.close
And MySQL test data table content:
enter image description here
and plotly.js
<h1> {{x_value}} Hi There</h1>
<h1> {{y_value}} Hi There</h1>
<div id="myPlot" style="width:200;height:800px;"></div>
<script type="text/javascript">
var x_arry = new Array();
var y_arry = new Array();
for(var i = 0; i < {{x_value}}.length; i++){
x_arry.push({{x_value}}[i]);
}
for(var i = 0; i < {{y_value}}.length; i++){
y_arry.push({{y_value}}[i]);
}
var data = [{
x: x_arry,
y: y_arry,
mode: "lines"
}];
var layout = {
xaxis:{title:"X: Number"},
yaxis:{title:"Y: Hum"},
title:"This is my graph"
};
Plotly.newPlot("myPlot", data, layout);
I made it like this. But I can't see the plot graph on the web page
The x_arry value has been output normally in the js code.
However, the plot graph is not drawn on the web page because the y_arry value is not printed. I want to solve this.
I would recommend making two changes to your code.
Firstly, you'll need to convert the Decimal values you are getting from the database to Python floats, by replacing the line
tpl_hum.append(value[2])
with
tpl_hum.append(float(value[2]))
Secondly, the most reliable way to get data from your Python code to your JavaScript code is to get Python to serialize the data as a JSON string, and put this in your template. Try replacing the following line in your Python code
return template("index.tpl", x_value = tpl_no, y_value = tpl_hum)
with
json_data = json.dumps({"x_array": tpl_no, "y_array": tpl_hum})
return template("index.tpl", json_data=json_data)
You'll also need to add import json to your Python code.
The JavaScript within your template then becomes:
var jsonData = {{json_data}};
var data = [{
x: jsonData.x_array,
y: jsonData.y_array,
mode: "lines"
}];
var layout = {
xaxis:{title:"X: Number"},
yaxis:{title:"Y: Hum"},
title:"This is my graph"
};
Plotly.newPlot("myPlot", data, layout);
You don't need the loops to read the data into variables such as x_arry and y_arry. (In fact, it's arguable you wouldn't have needed them before.)
Disclaimer: I haven't tested this.
I'm trying to port the following code to use JSON files http://malamas.com/jsuc/jsuc.html
Currently i have managed to take the 'unit' and 'factor' parts of this:
property[0] = "Acceleration";
unit[0] = new Array("Meter/sq.sec (m/sec^2)", "Foot/sq.sec (ft/sec^2)", "G (g)", "Galileo (gal)", "Inch/sq.sec (in/sec^2)");
factor[0] = new Array(1, .3048, 9.806650, .01, 2.54E-02);
and put them into a JSON line:
var text = '{"Accelleration": { "unit":"\\"Meter/sq.sec (m/sec^2)\\", \\"Foot/sq.sec (ft/sec^2)\\", \\"G (g)\\", \\"Galileo (gal)\\", \\"Inch/sq.sec (in/sec^2)\\"", "factor":"1, .3048, 9.806650, .01, 2.54E-02"}}'
var obj = JSON.parse(text);
Which i can have output as a string like this
"Meter/sq.sec (m/sec^2)", "Foot/sq.sec (ft/sec^2)", "G (g)", "Galileo (gal)", "Inch/sq.sec (in/sec^2)"
but i want to be able to feed it into the top code by doing this:
property[0] = "Acceleration";
unit[0] = new Array(obj.Accelleration.unit);
factor[0] = new Array(obj.Accelleration.factor);
Unfortunately, when i do that, unit[0][0] brings up the same thing;
"Meter/sq.sec (m/sec^2)", "Foot/sq.sec (ft/sec^2)", "G (g)", "Galileo (gal)", "Inch/sq.sec (in/sec^2)"
How can i make it so it works as an array? Thanks!
What you have in your JSON is a string that contains some representation of strings. As that representation is not JSON, you can't parse it directly (but you could by adding brackets around it to turn it into JSON).
Instead of having a string that contains strings, make it an array that contains strings. Then when you parse it, you will already have the array:
var text = '{"Accelleration": { '+
'"unit": ["Meter/sq.sec (m/sec^2)", "Foot/sq.sec (ft/sec^2)", "G (g)", "Galileo (gal)", "Inch/sq.sec (in/sec^2)" ], '+
'"factor": [ 1, .3048, 9.806650, .01, 2.54E-02 ]'+
'}}'
var obj = JSON.parse(text);
Now you have your arrays, without having to do anything more than getting them from the object:
unit[0] = obj.Accelleration.unit;
factor[0] = obj.Accelleration.factor;
I have a website that uses AJAX to deliver a JSON formatted string to a HighCharts chart.
You can see this as the middle JSON code part at:
http://jsfiddle.net/1Loag7pv/
$('#container').highcharts(
//JSON Start
{
"plotOptions": {
"series": {"animation": {"duration": 500}}
,"pie": {
"allowPointSelect": true,
"cursor": "pointer",
"dataLabels": {"formatter":function(){return this.point.name+': '+this.percentage.toFixed(1) + '%';}}
}
},
"chart":{"renderTo":"divReportChart"}
,"title":{"text":"Sales Totals"}
,"xAxis":{"title":{"text":"Item"}, "categories":["Taxes","Discounts","NetSalesTotal"], "gridLineWidth":1}
,"yAxis":[{"title":{"text":"Amount"}, "gridLineWidth":1}]
,"series":[{"name":"Amount","type":"pie", "startAngle": -60,"yAxis": 0,"data":[["Taxes",17.8700],["Discounts",36.0000],["NetSalesTotal",377.9500]]}]
}
//JSON end
);
The problem is that the function part...
"dataLabels": {"formatter":function(){return this.point.name+': '+this.percentage.toFixed(1) + '%';}}
is not being transferred via the JSON
All research tells me that there is NO WAY to do this.
IE... Is it valid to define functions in JSON results?
Anybody got an idea on how to get around this limitation?
It is true that you cannot pass functions in JSON. Javascript is a superset of JSON.
A common approach is for the chart to be defined in javascript (e.g. during the page load), and the page then requests just the data via Ajax. When the data is returned it can be added to the chart object, either before it is rendered or afterwards using the highcharts API.
If you really want to pass the formatter function from the server with the chart, send it as a string, and then turn it into a function like this:
var fn = Function(mystring);
and use it in highcharts like:
chart.plotOptions.pie.dataLabels = {"formatter":fn};
I've re-factored your example to show the approach: http://jsfiddle.net/wo7zn0bw/
I had a similar conundrum. I wanted to create the JSON server side (ruby on rails) so I could create images of charts for a web API and also present it on the client web browser with the same code. This is similar to SteveP's answer.
To conform with JSON standards, I changed all formatter functions to strings
{"formatter": "function(){ return this.point.name+':'+this.percentage.toFixed(1) + '%';}"}
On the web side, I navigate the hash looking for formatter keys and replace them with the function using this code (may be a better way!?). javascript:
function HashNavigator(){
this.navigateAndReplace = function(hash, key){
if (!this.isObject(hash)){
//Nice if only navigated hashes and arrays
return;
}
var keys = Object.keys(hash);
for(var i = 0; i< keys.length; i++){
if (keys[i] == key){
//convert string to js function
hash[keys[i]] = this.parseFunction(hash[keys[i]]);
} else if (this.isObject(hash[keys[i]])){
//navigate hash tree
this.navigateAndReplace(hash[keys[i]], key);
} else {
//continue
}
}
};
this.isObject = function(testVar) {
return testVar !== null && typeof testVar === 'object'
}
//http://stackoverflow.com/questions/7650071/is-there-a-way-to-create-a-function-from-a-string-with-javascript
this.parseFunction = function(fstring){
var funcReg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
var match = funcReg.exec(fstring.replace(/\n/g, ' '));
if(match) {
return new Function(match[1].split(','), match[2]);
}
return null;
};
}
To use this, would be something similar to this javascript:
hashNavigator = new HashNavigator();
hashNavigator.navigateAndReplace(myHighchartsHash, "formatter")
At that point the hash/js-object is Highcharts ready
Similar idea was used for the web image API.
I was really hoping that hacking at the JSON was not the only solution, but it works!
I used a different approach. I created a JSON like below
{"formatter": "function(){ return this.point.name+':'+this.percentage.toFixed(1) + '%';}"}
When I came to evaluating the expression, I used (assuming that the value of the 'formatter' is formatterValueString)
formatterValueString = formatterValueString.replace('function()', '');
let opts = (new Function(formatterValueString)).call(this);
formatterValue = opts;
The reason to use this approach was it became hard to bind 'this' with the function. The eval() function did not go well with accessing variable this. I am sure there are ways to do it. Just thought this was quick.
I'm getting a JSON response from my service. Following the tutorial, I created response for binding data in datatables jquery plugin.
Client Side code :
var test_reports = jsonResp.reports;
var aDataSet = [test_reports];
$('#example').dataTable( {
"aaData": aDataSet,
"aoColumns": [{ "sTitle": "Tests" },
{ "sTitle": "Reports"}]
});
In console, my "test_reports" shows :
['TEST_1','1'] ['TEST_2','1']
But while binding this data to tables, it throws error. If I copy this cosole output into aaData, it creates the table. I understood that my "test_reports" is a string and this plugin is expecting an array of values. Any ideas of making this work!!
Server side code which gives this json response :
testcasesCountRS = statement.executeQuery(testcasesQuery);
while(testcasesCountRS.next()){
String test_name = testcasesCountRS.getString("test_name");
String test_count = testcasesCountRS.getString("test_count");
testResults.put(test_name, test_count);
resBuffer.append("[\'" + test_name + "\',\'" + test_count + "\'],");
}
resBuffer = resBuffer.deleteCharAt(resBuffer.lastIndexOf(","));
reports.put("reports", resBuffer);
Is there any alternative in my server side code to send the response as an array object to the datatables plugin.
You server response should be an array of array.
[['TEST_1','1'],['TEST_2','1']]
Change your code to
resBuffer.append("[");
while(testcasesCountRS.next()){
String test_name = testcasesCountRS.getString("test_name");
String test_count = testcasesCountRS.getString("test_count");
testResults.put(test_name, test_count);
resBuffer.append("[\'" + test_name + "\',\'" + test_count + "\'],");
}
resBuffer = resBuffer.deleteCharAt(resBuffer.lastIndexOf(","));
resBuffer.append("]");
The above code is untested. But hope you get the idea.
Documentation link
I made it work the following way :
JSONArray testCaseArray = new JSONArray();
while(testcasesCountRS.next()){
JSONArray testCase = new JSONArray();
String test_name = testcasesCountRS.getString("test_name");
String test_count = testcasesCountRS.getString("test_count");
testCase.add(test_name);
testCase.add(test_count);
testCaseArray.add(testCase);
}
reports.put("reports", testCaseArray);
The only thing thats bothering me is, it so stupid code that I need to create a new Array every time in my loop. And adding these arrays to my main Array object. There should be some work around to make it simple. Please suggest some efficient methodology.
I want to encode a Javascript object into a JSON string and I am having considerable difficulties.
The Object looks something like this
new_tweets[k]['tweet_id'] = 98745521;
new_tweets[k]['user_id'] = 54875;
new_tweets[k]['data']['in_reply_to_screen_name'] = "other_user";
new_tweets[k]['data']['text'] = "tweet text";
I want to get this into a JSON string to put it into an ajax request.
{'k':{'tweet_id':98745521,'user_id':54875, 'data':{...}}}
you get the picture. No matter what I do, it just doesn't work. All the JSON encoders like json2 and such produce
[]
Well, that does not help me. Basically I would like to have something like the php encodejson function.
Unless the variable k is defined, that's probably what's causing your trouble. Something like this will do what you want:
var new_tweets = { };
new_tweets.k = { };
new_tweets.k.tweet_id = 98745521;
new_tweets.k.user_id = 54875;
new_tweets.k.data = { };
new_tweets.k.data.in_reply_to_screen_name = 'other_user';
new_tweets.k.data.text = 'tweet text';
// Will create the JSON string you're looking for.
var json = JSON.stringify(new_tweets);
You can also do it all at once:
var new_tweets = {
k: {
tweet_id: 98745521,
user_id: 54875,
data: {
in_reply_to_screen_name: 'other_user',
text: 'tweet_text'
}
}
}
You can use JSON.stringify like:
JSON.stringify(new_tweets);