I am using Flask with nvd3 to display charts. My question is similar to this one (check out the answer), except that now I want the json data variable to be initialized by passing an argument from Flask instead of hard-coding it in the javascript.
Doing data = {{data}} and rendering the template by
return render_template("display_plot.html", data=data)
where I generate the data using python e.g.
data = {"values": [{"y": 17830, "x": 1382313600000.0}, {"y": 17977, "x": 1382400000000.0}, {"y": 17633, "x": 1382486400000.0}, {"y": 17633, "x": 1382572800000.0}, {"y": 17403, "x": 1382659200000.0}, {"y": 17403, "x": 1382745600000.0}, {"y": 17142, "x": 1382832000000.0}], "key": "active_pages", "yAxis": "1"}] does not work.
In your template, you should call data as:
{{ data|tojson|safe }}
Otherwise, you will not get the correct results since the data is technically not converted to json and also the characters might be escaped by jinja.
Related
I am trying to adapt the 'simplify polygon' function from the the clipper.js library. I am not sure I understand what is wrong with the following script:
var five_pointed_star = [{
"X": 114.11152626295,
"Y": 22.213863709855
}, {
"X": 114.11262775355,
"Y": 22.214272283475
}, {
"X": 114.1133008867,
"Y": 22.214885143905
}, {
"X": 114.1133008867,
"Y": 22.21619257949
}, {
"X": 114.11164865079,
"Y": 22.216233436852
}, {
"X": 114.11152626295,
"Y": 22.213863709855
}];
var ten_pointed_star = ClipperLib.Clipper.SimplifyPolygon(five_pointed_star, ClipperLib.PolyFillType.pftNonZero);
console.log(ten_pointed_star);
The code however works as expected if I change the five_pointed_star to the following:
var five_pointed_star = [{
"X": 147,
"Y": 313
}, {
"X": 247,
"Y": 34
}, {
"X": 338,
"Y": 312
}, {
"X": 86,
"Y": 123
}, {
"X": 404,
"Y": 124
}];
Any ideas what I am doing wrong?
The polygon uses a path as a parameter, and the path has the following definition in the documentation:
This structure contains a sequence of IntPoint vertices defining a single contour (see also terminology). Paths may be open and represent a series of line segments bounded by 2 or more vertices, or they may be closed and represent polygons. Whether or not a path is open depends on context. Closed paths may be 'outer' contours or 'hole' contours. Which they are depends on orientation.
And IntPoint reads:
The IntPoint structure is used to represent all vertices in the Clipper Library.
So this means that the numbers you need to give it, have to be Integers - whereas you were trying to use floating point numbers, or floats for short.
So if you use Integers it should always work fine, if your calculations return floats, you can use rounding methods like floor() to get rid of the values after the dot.
I would like to display a HighCharts dual axes chart by making a call to a local webService, which returns Json (example given below).
The HighChart should plot the following data points:
y-axis left: plots the 'Movement'
y-axis right: plots the 'EndValue'
x-axis: plots the 'DateLabel'
My Json webservice call: http://localhost/api/getData?format=jsonp
This returns the following Json:
{
"LastUpdated": "/Date(-62135596800000-0000)/",
"TotalTime": "0s584ms",
"MonthlyData": {
"GroupId": 9,
"CurrencyId": 3,
"Returns": [
{
"Movement": -0.008536959525287496,
"MovementLabel": "-0.85 %",
"DateLabel": "Jan-10",
"Date": "/Date(1264892400000-0000)/",
"EndValue": 16012000.007666545
},
{
"Movement": -0.04846365302964577,
"MovementLabel": "-4.85 %",
"DateLabel": "Feb-10",
"Date": "/Date(1267311600000-0000)/",
"EndValue": 15235999.994984308
},
{
"Value": -0.0034129684178402725,
"ValueLabel": "-0.34 %",
"DateLabel": "Mar-10",
"Date": "/Date(1269986400000-0000)/",
"StartValue": 15235999.994984308,
"EndValue": 15184000.008187212,
"CashFlows": 0
}
]
}
}
What is the jquery code needed to
- make the call to the webService (I would like to use getJson)
- transform the JSON output to the required HighCharts data, such that a dual axes chart can be shown
To get JSON you can use jQuery.ajax() function. As for the splitting data into two series linked to different yAxis, you need to parse your data. Take a look at the example below.
API Reference:
http://api.jquery.com/jquery.ajax/
http://api.highcharts.com/highcharts/xAxis.categories
http://api.highcharts.com/highcharts/yAxis.opposite
Example:
http://jsfiddle.net/dna9wqsg/
I am trying to create a moving average over the rest of the chart. I am trying to do something similar to this.
However, for my data points I continuously get the error:
"Error: Invalid value for attribute d="M1.2121212121212122,NaNL1.4141414141414141,NaNC1.6161616161616161,NaN,2.0202020202020203,NaN,2.4242424..."
I believe it is because my data isn't formatted correctly, but I don't know how to modify the function to work with my data. My data currently looks like:
var data = [ {"x": 1, "y": 113},
{"x": 6, "y": 38},
{"x": 11, "y": 108},
{"x": 16, "y": 245},
{"x": 21, "y": 155},
{"x": 26, "y": 234},
...
Thanks
Just map your [{x1,y1}, {x2,y2}, ... {xN,yN}] pairs to a [y1, y2, ... yN] series, which is what that moving average function expects:
movingAverageLine(data.map(function(d) { return d.y; }))
Here's a working fiddle: http://jsfiddle.net/yz87b53d/3/
You should accept meetamit's answer since that essentially was the issue.
movingAverageLine(data.map(function(d) { return d.y; }))
I'm having a problem adding two charts in HighCharts: one has just decades, and the other has the same decades but also with categories like "year one", etc. The two charts don't seem to be able to be put onto the same chart.
I'm getting HighCharts Error #19: Too Many Ticks.
Here are my categories:
categories: ["RNV-A", "RNV-B", "RNV-C", "RNV-D",
"RNV-E", "RNV-F", "RNV-G", "RNV-H",
"RNV-I", "P.I.", "1910", "1920",
"1930", "1940", "1950", "1960",
"1970", "1980", "1990", "2000",
"2010", "2020", "2030", "2040",
"2050", "2060"],
And the values which include all categories:
[40.510191198250766, 40.510191198250766, 40.510191198250766, 40.510191198250766, 40.510191198250766, 40.510191198250766, 40.510191198250766, 40.510191198250766, 40.510191198250766, 40.510191198250766, 42.44299597201156, 41.351219164431505, 39.776804170262345, 38.248217460058335, 36.702829971428535, 35.069195968318716, 33.79982485286693, 33.098321602721086, 32.828589353935875, 32.47115630145776, 32.06982734169106, 31.421843607968913, 30.92053153916419, 30.528508779591846, 30.199389512342062, 29.806527065694834]
And with only the decades:
[{"y": 54592.30356899987, "x": "1910"}, {"y": 53188.00565025002, "x": "1920"}, {"y": 51162.91436399994, "x": "1930"}, {"y": 49196.769708000036, "x": "1940"}, {"y": 47209.01505074996, "x": "1950"}, {"y": 45107.75331424995, "x": "1960"}, {"y": 43475.02471700008, "x": "1970"}, {"y": 42572.71616149999, "x": "1980"}, {"y": 42225.77305650002, "x": "1990"}, {"y": 41766.024792750046, "x": "2000"}, {"y": 41249.815418250124, "x": "2010"}, {"y": 40416.34634075002, "x": "2020"}, {"y": 39771.53369224994, "x": "2030"}, {"y": 39267.29441775001, "x": "2040"}, {"y": 38843.964760249975, "x": "2050"}, {"y": 38338.64543824998, "x": "2060"}]
Here's a jsfiddle that has two buttons: first one adds all the categories dataset, and the second one adds the dataset that only covers the decades:
http://jsfiddle.net/bozdoz/R82T3/
I've tried adding tickPixelInterval like the error page suggests: http://www.highcharts.com/errors/19
I've tried adding min, minTickInterval, maxTickInterval, tickInterval, as well. I've also tried adjusting the plotOptions.series.pointInterval:
http://api.highcharts.com/highcharts#plotOptions.series.pointInterval
I can't seem able to get these charts together. I think because it converts the decades to datetimes, but it doesn't convert the dataset with the strings as x-axis values.
Any help would be appreciated. Thanks.
The problem
I can't get both datasets onto the same chart. It doesn't seem able to have datasets with one as decades and the other as a mixture of decades and strings. How can I solve this?
The data does not correspond to the category by its name, but by its array index.
So, with your categories array, the x value for "RNV-A" would be 0. "RNV-B" would be 1, "RNV-C" would be 2, and so on.
1) categories - You can use label formatter and check if it is number, http://api.highcharts.com/highstock#xAxis.labels.formatter
2) X value cannot be a string, it needs to be number. In case when you would like to have datetime type of chart, you can use pointStart / pointInterval, and then set tickInterval on xAxis (time in miliseconds)
For one of my school projects, I have to create a game with Javascript. My Javascript experience is very minimal, and therefore I'm really stuck on how to create multiple levels within my game. With JSON, I load blocks for Mario to walk on:
createBlocks: function () {
console.log('game -> createBlocks');
$.getJSON('js/boxes.json', function (data) {
data.boxes.level1.forEach(function (blockData) {
this.stage.removeChild(this.block.el);
var block = new Block(blockData);
this.block.push(block);
this.stage.addChild(block.el);
}.bind(this));
}.bind(this));
}
With the function "createStars" the game loads another JSON. My goal is to have the game switch to another level with every 5 stars being collected. What is the best way to create this with JSON?
My JSON file for the blocks are created as follow:
{
"boxes": {
"level1": [
{
"x": 0,
"y": 115,
"width": 25,
"height": 25
},
{
"x": 25,
"y": 115,
"width": 25,
"height": 25
}
],
"level2": [
{
"x": 0,
"y": 95,
"width": 25,
"height": 25
}
]
}
}
Please let me know if you need my complete code to answer my question? I can also give a link to the game as it currently is hosted on my own site: http://school.carlavanloon.com/cp/
Furthermore, I'd like the game to stop the time after collecting 20 stars. This will then be the end time for the user of the game.
Many thanks in advance for your reply. And please let me know if I need to give any additional information.
Instead of making your json file around "boxes" you should design the json structure top down,
first load game json, which contains level objects - which contain boxes arrays etc. ie. something like this
var json = {
"game_data": {
"some_global_settings" : {"game_speed": 30, "theme": "dark"},
"level1": {
"boxes": [
{
"x": 0,
"y": 115,
"width": 25,
"height": 25
},
{
"x": 25,
"y": 115,
"width": 25,
"height": 25
}
],
"stars": [
{
"x": 0,
"y": 50,
"width": 25,
"height": 25
},
{
"x": 125,
"y": 120,
"width": 25,
"height": 25
}
],
"player_position" : {"x": 0,"y": 50},
"victory_condition" : {"stars_required" : 5, "time_limit" : "10min"}
},
"level2": {"same structure as above with different data" : 1}
}
}
and then make a level builder function which picks a level object and creates everything in it. To reload a new level, check the number of stars remaining, if its 0, call your createLevel(gamelevel) with n+1 for building the next level.
below is pseudo code sample.
Every time user collects a star, you will check if it was the last star required, and if so, increment the level counter and call level builder function which could be something like this
function buildLevel( levelNr ) {
var gdata = json.game_data["level"+levelNr];
//check if next level exists in game_data object
if (!gdata) {
finishGame();
return false;
}
//next level data exists, so build whats in it
//clear level from previous stuff
clearLevel();//perhaps replace canvas with new one
createBoxes( gdata.boxes);
createStars( gdata.stars);
createPlayer( gdata.player_position);
//everything is ready, add listeners / timers etc, and start the game
}