I am trying to populate a DOJO pie chart from a json array created by a url - json

I am trying to populate a dojo pie chart from a json array created by a url.
the url returns an array that looks like this
{"pieItems":[["IPv4 TCP",475919493840],["IPv6 TCP",37443255432],["IPv4 UDP",34595392128],["IPv6 ICMP",14496],["IPv4 ICMP",46560],["IP Other",12385112]]}
I have attempted to redo the format of the array changing it to one that looks like this
{"IPv4 TCP":[475919493840],"IPv6 TCP":[37443255432],"IPv4 UDP":[34595392128],"IPv6 ICMP":[14496],"IPv4 ICMP":[46560],"IP Other":[12385112]} .
the code I used to change the format is:
var len = responseObj.pieItems.length, i, hash = {};
for (i = 0; i < len; i++) {
hash[responseObj.pieItems[i][0]] = responseObj.pieItems[i][1];
}
After changing the format I can only populate the chart with on item by adding the series and specifying the name.
chart1.addSeries("IP Other", hash["IPv6 ICMP"])
This populates the chart with that one item but if i try to add another series for example
chart1.addSeries("IP Other", hash["IPv4 Other"])
It overwrites the chart and shows the data for IP Other instead of adding another slice.
How can I add all the items in the array into the pie chart?

Pie chart supports just one series object by definition. You should add different data points for different slices. A sketch:
chart.addSeries("IP", dojo.map(responseObj, function(p){
return {
y: p[1], // value
text: p[0] // label
};
});

Related

Bing Maps Layers - Finding information on segment

I have a large object, full of WKT information from a GIS system. I'm looping over the data and mapping it into layers, then pushing those layers onto the map. This is working fine and I'm getting the right data showing up.
for (var j = 0; j < 10; j++) {
var dataLayer = new Microsoft.Maps.Layer($scope.thing);
for (var i = 0; i < bArray.length; i++) {
if (bArray[i].count == $scope.thing) {
dataLayer.add(new Microsoft.Maps.WellKnownText.read(bArray[i].wkt);
dataLayer.item = bArray[i].count;
}
}
Microsoft.Maps.Events.addHandler(dataLayer, "click", polylineClicked);
$scope.map.layers.insert(dataLayer);
$scope.map.layers[j].setVisible(false);
$scope.thing++;
}
The data in each layer breaks down into different categories, stored in the field "item", and I show those categories in a side legend.
My question is how do I find "item" for each segment on the map? When I view the map object I can see the layers, when I go into the layers I can see the primitives, but when I enter the primitive, they all have the same category in "item", instead of what they should have.
How do I find "item" for each segment?
Thanks
Docmur
First off, use the metadata property of the layer to store custom info, otherwise you risk overwriting one of the internal properties of the layer class. For example: dataLayer.metadata = { item: "custom data" };
That said, your item property is on the dataLayer, not on the individual primitives. It also looks like you are adding the same value to it over an over again on the inner loop so you will end up with a lot of values that are the same. Can you provide more details on what you want to achieve as there likely is a much cleaner way to do this.

Add in a where clause

I have this foreach function, but I need to add a where clause.
I have added a checkboxlist in Umbraco called "show"
Values if this is
"EN"
"SP"
"US"
...
Let us say I have checked EN and SP.
I only want a slide to be visible if the slide is Visible as now, and if the field show are "EN" is checked and true. How can i add this in my code?
#foreach (var Slider in Umbraco.ContentSingleAtXPath("//HomePage/SliderArea").Children.Where("Visible").OrderBy("CreateDate
desc").Take(4))
The code you have is using Dynamics and therefore you're restricted to using the pseudo-Linq extensions like .Where("Visible"). You'll find it much easier to manipulate the list of items if you use the Typed objects instead.
Change this:
// Returns IPublishedContent as dynamic
Umbraco.ContentSingleAtXPath("//HomePage/SliderArea")
to this:
// Returns fully typed IPublishedContent
Umbraco.TypedContentSingleAtXPath("//HomePage/SliderArea")
Then you'll be able to use the full power of Linq to do this:
var area = Umbraco.TypedContentSingleAtXPath("//HomePage/SliderArea");
// returns a filtered IEnumerable<IPublishedContent>
var sliders = area.Children.Where(c => c.IsVisible() && c.GetPropertyValue<string>("show") == "EN");
#foreach (IPublishedContent slider in sliders.OrderByDescending(c => c.CreateDate).Take(4))
{
// You can get the dynamic equivalent of the IPublishedContent like this if you wish:
dynamic dSlider = slider.AsDynamic();
// ...
}

D3 reusable multi-line chart with JSON data

I'm trying to do some re-factoring on my charts to make them re-usable using this as a guide: http://bost.ocks.org/mike/chart/
I'm having problems drawing the lines in my multi-line graph though - specifically passing the data to the x and y values. If I hard code the element names it works, but if I try to use the xValue and yValue objects this does not work. I'm assuming that this is because I'm trying to call a function within the parameter of an other object, but I'm not sure how to get around this. In the exmaple Mike uses d[0] and d[1], but this won't work with JSON data (or I'm not sure how to make it work).
I've posted this JSFiddle so you can see the code. The problem lines are 125 to 131 which in turn is being called from line 165.
var main_line = d3.svg.line()
.interpolate("cardinal")
// Hard coding the elements works
//.x(function(d) { return main_x(d.date); })
//.y(function(d) { return main_y(d.buildFixTime); });
// Passing xValue and yValue does not work
.x(function(d) { return main_x(xValue); })
.y(function(d) { return main_y(yValue); });
http://jsfiddle.net/goodspeedj/fDyLY/
Thank you in advance.
You need to redefine your accessor method within .x() and .y(). The accessor method defines the way that a datum is pulled out of the data that is bound to the selection that you call the line generator on.
Suppose you have a relatively flat data structure such as the following.
data = [{x : 1, y : 2}, {x:1, y:3}, {x:4, y:5}];
You then bind the data to a selection with the following statement
d3.select("body").datum(data).append("path").attr("d",lineGenerator);
Quite a bit is going on underneath this statement. I'll give you a bit more of a walkthrough after showing you a commonly used example.
The important aspect to understand is that similarly to other calls in d3 such as
var exampleRectangles = d3.select("body")
.data(data).enter()
.append("rect")
.attr("width",2)
.attr("height", 3)
.attr("x",function(datum){return datum.x}) // pay attention to this line
.attr("y",0);
d3 is implicitly iterating over each element in your data. For each datum in your data array, in this case there is a total of three datum, you are going to add a rectangle to the dom.
In the line that I tell you to pay attention to you notice that you're defining an anonymous (unnamed) function. What is that datum parameter coming from? It's implicitly being passed to your anonymous function.
So each rectangle has it's own corresponding datum {x : 1, y : 2}, {x:1, y:3}, {x:4, y:5} respectively. Each rectangle's x coordinate is defined by the respective datum.x attribute. Under the sheets, d3 is implicitly looping over the data array that you've defined. A similar approach to the example d3 code could be written as above.
for (var i = 0; i < data.length; i++)
{
d3.select("body").append("rect")
.attr("width",2)
.attr("height", 3)
.attr("x",data[i].x)
.attr("y",0);
}
This follows from the notion of data driven documents (d3). For each item added (a rectangle in the above example a piece of data is tied to it. In the above example you see that there is something kind of similar to your .x() and .y() accessor functions :
.attr("x",function(datum){return datum.x})
This function is telling d3 how to filter over the total datum that's being passed to the .attr() accessor method.
So, you need to determine which data you need to get a hold of to make your .attr("d", lineGenerator)call make sense. The difference between your.datum(data)call and the typical.data(data)call is that instead of parceling the data that's being passed to.data(data)`, the whole array is given as a single piece of data to the line generator function (similar to main_line(data), wherein it will again implicitly loop over the points to construct your path.
So, what you need to do is determine what a single datum will be defined as for your function to operate on.
I'm not going to define that as I don't seem to know quite which information you are operating on, but I would hazard a guess at something like.
.x(xAccessor)
.y(yAccessor)
function xAccessor(datum)
{
return xScale(datum._id.month);
}
function yAccessor(datum)
{
return yScale(datum.buildFixTime);
}
The way you have it set up, xValue and yValue are functions; you have to actually execute them on something to get a value back.
.x(function(d) { return main_x( xValue(d) ); })
.y(function(d) { return main_y( yValue(d) ); });
If you weren't using a scale, you could use
.x(xValue)
.y(yValue);
but only because if you pass in a function d3 executes it for you with the data as a parameter. And that only works for d3 methods that expect functions as possible input -- the scale functions expect data values as input.
I wrote a long piece work for another user last week that you may find useful, explaining methods that accept functions as parameters.

How do i populate an Array in one class based on a textfield in another class?(Actionscript 3.0)

i have a class (TheList.as). in which i have an array "Data" and it has a couple of values. Then i have a loop through which i am creating a scrollable list which uses the values from "Data" array. [I am trying make a unit converter]
Then i have another class "Units.as". In that class i have created three instances of "TheList". A main list ("myList"), and to sublists "ListFrom" and "ListTo". They are using values from "Data" array. Now i have text field whose value changes to whatever item is clicked. When i click "Angle" in the main list, i want the sublists to get populated with ("Degree", "Radian" etc)..
Here is what i tried
if(myList._TextLabel.text == "Angle")
{
ListFrom.Data = ["Degree", "Radian"];
}
But nothing happens, i do not get any error either. When i do this in an "ENTER_FRAME" event and trace (ListFrom.Data), i can see that the values change, but they do not get assigned to the list items in the list. I would really appreciate the help. Thanks!
Here are complete Classes for understanding the situation better(the code is pretty messy, as i am a newbie to OOP)
TheList.as: http://pastebin.com/FLy5QV9i
Units.as : http://pastebin.com/z2CcHZzC
where you call ListFrom.Data = ["Degree","Radian"], make sure when the data changed, the renders in the ListFrom have been set new data. for example, you may use MyRender in ListFrom for show, you should debug in the set data method in MyRender.
you should call the code below after you call ListFrom.Data = ["Degree","Radian"];
for (var i:int = 0; i < Data.legnth;i++) {
var render:MyRender = ListFrom[i] as MyRender;
if (render) {
render.data = Data[i];
} else {
var render:MyRender = new MyRender();
render.data = Data[i];
ListFrom.addChild(render);
}
}
You can use event listeners, singleton classes or reference one class to another, depending on the style you want. All are equally valid and fast / efficient.

Creating a line graph with highcharts and data in an external csv

I've read through the Highcharts how-to, checked the demo galleries, searched google, read the X amount of exact similar threads here on stackoverflow yet I cannot get it to work.
I'm logging data in a csv file in the form of date,value.
Here's what the date looks like
1355417598678,22.25
1355417620144,22.25
1355417625616,22.312
1355417630851,22.375
1355417633906,22.437
1355417637134,22.437
1355417641239,22.5
1355417641775,22.562
1355417662373,22.125
1355417704368,21.625
And this is how far I've managed to get the code:
http://jsfiddle.net/whz7P/
This renders a chart, but with no series or data at all. I think I'm fudging things up while formatting the data so it can be interpreted in highcharts.
Anyone able to give a helping hand?
So, you have the following data structure, right ?
1355417598678,22.25
1355417620144,22.25
1355417625616,22.312
1355417630851,22.375
1355417633906,22.437
1355417637134,22.437
1355417641239,22.5
1355417641775,22.562
1355417662373,22.125
1355417704368,21.625
Then you split it into an array of lines, so each array item is a line.
Then for each line you do the following.
var items = line.split(';'); // wrong, use ','
But there ins't ; into the line, you should split using ,.
The result will be a multidimencional array which each item is an array with the following structure. It will be stored in a var named data.
"1355417598678","22.25" // date in utc, value
This is the expected data for each serie, so you can pass it directly to your serie.
var serie = {
data: data,
name: 'serie1' // chose a name
}
The result will be a working chart.
So everything can be resumed to the following.
var lines = data.split('\n');
lines = lines.map(function(line) {
var data = line.split(',');
data[1] = parseFloat(data[1]);
return data;
});
var series = {
data: lines,
name: 'serie1'
};
options.series.push(series);
Looking at your line.split part:
$.get('data.csv', function(data) {
// Split the lines
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(';');
It looks like you are trying to split on a semi-colon (;) instead of a comma (,) which is what is in your sample CSV data.
You need to put
$(document).ready(function() {
in the 1st line, and
});
in the last line of the javascript to make this work.
Could you upload your csv file? Is it identical to what you wrote in your original post? I ran into the same problem, and it turns out there are errors in the data file.