d3pie error: no data supplied on d3pie.js - javascript

I am using rails, and gathering some data to make pie charts. I am just using ruby objects (so no JSON), and using d3pie. First, I make a helper function. Then I make a javascript function using that helper, and pass it in the dom. Here's my code;
helper.rb
def options_data_to_d3(options_data)
d3_data = []
options_data.each do |key, value|
d3_data.push( { label: key.option.as_json, value: value.as_json } )
end
return JSON.pretty_generate(d3_data)
end
this takes the ruby hash, and makes it into json
js function
function dataPieChart(id, data) {
var config = {
"header": {
"title": {
"text": "Quiz Questions",
"fontSize": 18,
"font": "verdana"
},
"size": {
"canvasHeight": 400,
"canvasWidth": 500
},
"data": {
"content": data
},
"labels": {
"outer": {
"pieDistance": 32
}
}
}
}
var pie = new d3pie(id, config);
}
passing into the view
<div id="quizQuestionOptionPie<%= question.id %>"></div>
<script type="text/javascript">dataPieChart("quizQuestionOptionPie<%= question.id %>", <%= raw options_data_to_d3(data[:options]) %>);
</script>
when I call a console log in the javascript function to see what data is, I get the correct output that both d3pie and d3 are looking for, yet I am still getting the error
d3pie error: no data supplied.
does anyone see something wrong with my code, or something I am missing? any help is appreciated.

You config option is bracketed incorrectly (everything is a child of "header"). You really meant:
var config = {
"header": {
"title": {
"text": "Quiz Questions",
"fontSize": 18,
"font": "verdana"
},
},
"size": {
"canvasHeight": 400,
"canvasWidth": 500
},
"data": {
"content": data
},
"labels": {
"outer": {
"pieDistance": 32
}
}
};

Related

JSON, Highcharts and Coldfusion json data

I have been trying to make this work for sometime and its I cannot seem to find the solution to make this work.
I am able to output JSON with my coldfusion CFC without issue, not I am trying to use this JSON with Highcharts.js. I have verified that the JSON is valid but highcharts seems to have an issue because in the series data there is double quotes surrounding the data. I've looked everywhere for a solution and I cannot seem to find any help that can set me on the right path. If I remove the double quotes from around the array in the series.data the chart loads in fine but I get away from it being dynamic.
Here is my JSON output from my CFC:`
{
"series": [{
"data": "[[Date.UTC(2017,05,21),2.9],[Date.UTC(2017,05,28),2.9],[Date.UTC(2017,06,04),3.1],[Date.UTC(2017,06,11),2.9]]",
"name": "ATC Main Pod A - B - C"
}, {
"data": "[[Date.UTC(2017,05,21),2.8],[Date.UTC(2017,05,28),2.6],[Date.UTC(2017,06,04),2.9],[Date.UTC(2017,06,11),2.9]]",
"name": "ATC Mays (ACB Blue)"
}, {
"data": "[[Date.UTC(2017,05,21),2.4],[Date.UTC(2017,05,28),2.6],[Date.UTC(2017,06,04),3],[Date.UTC(2017,06,11),3.2]]",
"name": "ATC Mays (ACB Purple)"
}, {
"data": "[[Date.UTC(2017,05,21),3.3],[Date.UTC(2017,05,28),3.3],[Date.UTC(2017,06,04),3.4],[Date.UTC(2017,06,11),3.3]]",
"name": "ATC R10 Pod D"
}, {
"data": "[[Date.UTC(2017,05,21),3.3],[Date.UTC(2017,05,28),3.4],[Date.UTC(2017,06,04),2.8],[Date.UTC(2017,06,11),1.9]]",
"name": "ATC TU Pod A - B"
}, {
"data": "[[Date.UTC(2017,05,21),2.9],[Date.UTC(2017,05,28),2.9],[Date.UTC(2017,06,04),3.1],[Date.UTC(2017,06,11),3.4]]",
"name": "CTRC 1st Floor"
}, {
"data": "[[Date.UTC(2017,05,21),2.9],[Date.UTC(2017,05,28),3.3],[Date.UTC(2017,06,04),3.2],[Date.UTC(2017,06,11),2.3]]",
"name": "CTRC 2nd Floor"
}]
}
Here is what my ajax call looks like:
function loadChartData(c){
$.ajax({type: "POST", url: "CFCs/survey.cfc", data: {method:"results_RLU", CENTERID: c},dataType: 'json',success: function(data){
options.series = data.series
var chart = new Highcharts.Chart(options)
}
});
}
Not a problem!
Simply iterate each item in the series and parse the data to valid JSON object.
Enjoy :)
function loadChartData(c){
$.ajax({type: "POST", url: "CFCs/survey.cfc", data: {method:"results_RLU", CENTERID: c},dataType: 'json',success: function(data){
options.series = data.series.map(function(item)
{
item.data = JSON.parse(item.data);
return item;
});
var chart = new Highcharts.Chart(options)
}
});
}

invalid character javascript error while using JSON.parse

I am trying to convert a json string to object format read from a .js file.
Below is the JSON string in document.js
[
{
"type": "TableShape",
"id": "63c0f27a-716e-804c-6873-cd99b945b63f",
"x": 80,
"y": 59,
"width": 99,
"height": 107,
"name": "Group",
"entities": [
{
"text": "id",
"id": "49be7d78-4dcf-38ab-3733-b4108701f1"
},
{
"text": "employee_fk",
"id": "49be7d78-4dcf-38ab-3733-b4108701fce4"
}
]
}
];
now i am calling the document.js in window load using AJAX like below
$(window).load(function () {
$.ajax({
url: "JS/Draw2d/SampleData/document.js",
async: false,
success: function (result) {
debugger;
jsonStringFromServer = JSON.parse(result);//Here Javascript error stating invalid character
alert(jsonStringFromServer);
}
});
});
When the $.ajax function receives JSON, it automatically deserialises it for you. The error you're seeing is being cause because you're passing an object to JSON.parse, not a JSON formatted string - you don't need to use JSON.parse at all. Try this:
success: function (result) {
debugger;
console.log(result); // = the received object
}
I would also strongly suggest you remove async: false as it is extremely bad practice to use it.

Zingcharts live feed not rendering chart

So I have been trying out ZingCharts which in general I like a ton. But now I am trying to create a live feed and the documentation isn't all that clear. I am trying to use HTTP to update a chart with new values. It seems that I need to have a page that is sending the chart data with updated values and that is what I am doing. This chart renders correctly when I past the JSON directly in the browser but not as a live feed, it now only emphasized textcorrectly pulls from the /metrics_feed and renders the outline of the chart but it is all grey. The JSON I am sending over HTTP is:
{
"crosshair-x": {},
"legend": {},
"plot": {
"valueBox": {
"placement": "top",
"type": "max, min",
"visible": false
}
},
"scaleX": {
"label": {
"text": "Metric count"
}
},
"scaleY": {
"label": {
"text": "Metric value"
}
},
"series": [
{
"text": "data point",
"values": [
-4.69283003950355,
-4.692830039503548,
-4.6928300395035505
]
}
],
"title": {
"text": "metrics over time"
},
"tooltip": {},
"type": "line"
}
And I am planning to update those values every second or so. Here is my HTML side code:
<head>
...
<script type="text/javascript">
var myChart = {"refresh":{
"type":"feed",
"transport":"http",
"url":"/metrics_feed",
"interval":1000
}
};
window.onload=function(){
zingchart.render({
id:"myChartDiv",
data:myChart,
height:600,
width:"100%"
});
};
</script>
</head>
<body>
<div id="myChartDiv"></div>
</body>
And this all works when I copy the direct JSON in there instead of sending it over HTTP so there is something I am missing in the Zingcharts documentation I suppose.
I'm on the ZingChart support team, and I'm happy to help you figure this out. You'll want to configure most of your chart settings and objects in your page, so in the myChart object. That means crosshair-x, legend, plot, etc... should all be static in the page and not passed via HTTP. In the JSON object, create empty series objects within the series array for each series that you will be passing to the chart. So, if you will only have one series plotted:
{
"type": "line",
"title": {
"text": "metrics over time"
},
/* Additional objects (tooltip, legend, crosshair, etc...) omitted for brevity */
"series": [
{
"values": []
}
]
}
And if you will be passing 2 series values:
{
"type": "line",
"title": {
"text": "metrics over time"
},
/* Additional objects (tooltip, legend, crosshair, etc...) omitted for brevity */
"series": [
{
"values": []
},
{
"values": []
}
]
}
The "refresh" object should also be placed in the myData object, in the top level:
{
"type": "line",
"title": {
"text": "metrics over time"
},
/* Additional objects (tooltip, legend, crosshair, etc...) omitted for brevity */
"refresh":{
"type":"feed",
"transport":"http",
"url":"/metrics_feed",
"interval":1000
},
"series": [
{
"values": []
},
{
"values": []
}
]
}
Depending on how many series objects you want in your chart, configure your script to pass values in the following format:
[ { "plot0" : 27, "plot1" : 34 } ]
Here's the feeds.php script that we use for the chart under the HTTP section of our feeds article:
<?php
$min = isset($_GET['min'])?intval($_GET['min']):0;
$max = isset($_GET['max'])?intval($_GET['max']):50;
$plots = isset($_GET['plots'])?intval($_GET['plots']):1;
?>
[
{
<?php
for ($plot=0;$plot<$plots;$plot++) {
?>
"plot<?php echo $plot; ?>" : <?php echo rand($min, $max); ?>,
<?php
}
?>
"scale-x" : "<?php echo date('H:i:s'); ?>"
}
]
This script also returns a timestamp that gets injected to an empty values array in our scale-x object. You can see a sample response here.
I apologize if our docs did not make this clear, I'll be updating them with added clarification soon. Anyway, I hope that helps you! Let me know if you need some more help.

Correct render of js object with nodejs express

I have some structure that I want to render to my JADE page, so I decided to make JSON-like object to render some kind of data (variables, text, js objects), this JSON object looks like :
var dataSet1 = {
meta: {
"name": "Some text",
"minimum": mini_2,
"maximum": maxi_2,
"currentValue": last_data_2
},
data: {
"values": dataTwo,
"corridor": {
"x1": xc,
"x2": yc2,
"yw": yw2
}
}
};
My render line:
res.render('index', {
data_to_draw: JSON.stringify(dataSet1)
});
Then I`m using this rendered data on my JADE:
displayGraphExampleOne("#graph",
!{data_to_draw.data.values},
!{data_to_draw.meta.currentValue},
!{data_to_draw.meta.minimum},
!{data_to_draw.meta.maximum},
!{data_to_draw.meta.name},
!{data_to_draw.data.corridor.x1},
!{data_to_draw.data.corridor.x2},
!{data_to_draw.data.corridor.yw2});
Cannot read property 'values' of undefined
Im getting such type of error.
Im new with JS , so Im trying to decide what i`m doing wrong. If I will pass data not in js object - it works well, but i need such type of passing data.
thanx
Don't JSON.stringify the object, instead pass the object itself, otherwise you are trying to access the properties of a string, which obviously don't exist.
Just need to format code like this:
var dataSet1= [
{
"meta": {
"name": "Veocity variance",
"minimum": mini_1,
"maximum": maxi_1,
"currentValue": last_data_1
},
"data": {
"values": dataOne,
"corridor": {
"x1": xc,
"x2": yc1,
"yw": yw1
}
}
}
];
And use such call:
displayGraphExampleOne("#graph",
!{first_set}[0][0].data.values,
!{first_set}[0][0].meta.currentValue,
!{first_set}[0][0].meta.minimum,
!{first_set}[0][0].meta.maximum,
!{first_set}[0][0].meta.name,
!{first_set}[0][0].data.corridor.x1,
!{first_set}[0][0].data.corridor.x2,
!{first_set}[0][0].data.corridor.yw);
But not forget to render:
res.render('index', {
first_set: JSON.stringify([dataSet1, dataSet2, dataSet3]),
second_set: JSON.stringify([dataSet1, dataSet2, dataSet3]),
third_set: JSON.stringify([dataSet1, dataSet2, dataSet3])
});

Declaration 2d array containing multiple objects for graph plugin?

I using igDoughnutChart for my web-page, I want a graph which shows the following hierarchy
source of attack (inside)
login abuse
dos
spyware
worm
outside attackers
spying
social attacks
The current object array looks like (also demo)
var data = [
{ "attacksource": 43, "attacktype": 60, "AT":"DoS","Label": "iNISDE" },
{ "attacksource": 29, "attacktype": 40, "AT":"login abuse","Label": "outside" }
];
I want to change this to do following:- (also shown above)
Where I have a parent and child values in 2d array so above code is to transform as
var data =
[
[{"attacksource": 43,"Label":"Inside"}],
[
{"attacktype": 13,"Label":"dos"},
{"attacktype": 13,"Label":"virus"}...
]
];
I'm not sure If I have initialized / assigned 2d using objects correctly.I appreciate If someone can look at the code, and let me know if I'm doing this right.
UPDATE
The jsbin example is just something to illustrate my requirements for the new code. For e.g "Label":"virus" is currently hardcoded, in real code (which I cannot do on jsbin) is I will get the values from DB.
VISUAL EXAMPLE
I don't think the chart you are trying to use support what you want to do. That being said there is somewhat of a hack to make it work:
$(function () {
var data = [
{ "label": "Inside", "attacks": 8 },
{ "label": "Outside", "attacks": 6 },
// Inside
{ "label": "Dos", vector: "Inside", "dummyValue": 6 },
{ "label": "siem", detect: "Dos", "detectValue": 3 },
{ "label": "user", detect: "Dos", "detectValue": 3 },
{ "label": "Worm", vector: "Inside", "dummyValue": 2 },
{ "label": "siem", detect: "Worm", "detectValue": 1 },
{ "label": "user", detect: "Worm", "detectValue": 1 },
// Outside
{ "label": "Spying", vector: "Outside", "dummyValue": 3 },
{ "label": "siem", detect: "Spying", "detectValue": 1.5 },
{ "label": "user", detect: "Spying", "detectValue": 1.5 },
{ "label": "Social", vector: "Outside", "dummyValue": 3},
{ "label": "siem", detect: "Social", "detectValue": 1.5 },
{ "label": "user", detect: "Social", "detectValue": 1.5 },
];
$("#chart").igDoughnutChart({
width: "100%",
height: "550px",
innerExtent: 6,
series:
[
{
name: "Attack Type",
labelMemberPath: "label",
valueMemberPath: "attacks",
dataSource: data,
labelsPosition: "center"
},
{
name: "Attack Vector",
labelMemberPath: "label",
valueMemberPath: "dummyValue",
dataSource: data,
labelsPosition: "center"
},
{
name: "detect Vector",
labelMemberPath: "label",
valueMemberPath: "detectValue",
dataSource: data,
labelsPosition: "center"
}
]
});
});
The order of the data and series arrays matter (not completely, just partially). Here is a jsFiddle that demonstrates this. Disclaimer: I'm not saying this will always work, as it makes the big assumption that igniteUI will always parse and display the data in the same way.
Also I'm not familiar with the library but I would bet there is a way to customize the colors of each section of the chart. If so you could just make the color a function that returns a color based on the vector property.
Some alternatives:
Highcharts
D3 - this would be my preferred approach. Browse the gallery, there a few examples that apply here.

Categories