JSON data format in NVD3 chart - javascript

I have a chart template for a multi bar chart in NVD3 here: http://jsfiddle.net/hohenheim/6R7mu/5/
I have the following JSON data I want to display:
[{"date": 1396828800, "impressions": 49145385},
{"date": 1396915200, "impressions": 46704447},
{"date": 1397001600, "impressions": 47181000},
{"date": 1397088000, "impressions": 47337965},
{"date": 1397174400, "impressions": 51129266},
{"date": 1397260800, "impressions": 60547397},
{"date": 1397347200, "impressions": 62217077},
{"date": 1397433600, "impressions": 49145385},
{"date": 1397520000, "impressions": 46704447},
{"date": 1397606400, "impressions": 47181000},
{"date": 1397692800, "impressions": 47337965},
{"date": 1397779200, "impressions": 51129266},
{"date": 1397865600, "impressions": 60547397},
{"date": 1397952000, "impressions": 62217077}]
I'm looking to use JSON data I have (shown above and also commented out in the fiddle) but don't have any idea how to get it in the format that this NVD3 chart will accept. The chart is currently using sample data that is meaningless to me.
Is there a way to convert my data into something NVD3 will accept? Any help appreciated.

data5 seems to have this format:
[
{key: x, values: VALUES, vAxis: 1},
{key: x, values: VALUES, vAxis: 1} // and maybe more for more colors
]
and VALUES seems to have this format:
[
{x: 0, y: N},
{x: 1, y: N},
{x: 2, y: N} // and more for more on the X axis
]
So you have to rewrite your data to that format. Only it seems you don't have more sources. You have only 1 color. What makes {"date": 1396828800, "impressions": 49145385} one or the other? Is date the X axis?
Assuming the order of your data is correct, and it's only 1 source:
data5 = [{key: 'X', values: [], vAxis: 1}]
yourData.forEach(function(el, i) {
data5[0].values.push({x: i, y: el.impressions});
// ^ only 1 source/color
// ^ incremental X, starting at 0
});
You might have to adjust the x and y range somehow. (Maybe vAxis is one?)

I just stumbled upon their github page, and seems the above answer is correct.
https://github.com/novus/nvd3/wiki/Sample-chart-(your-first-nvd3-chart!)
The data format for charts is supposed to be:
[
{
key: "<Series name>",
color: "<CSS color>",
values: [
{x: 0, y: 10},
{x: 1, y: 20},
{x: 2, y: 30}
....
]
},
{
key: "<Series name>"
...
}
]

Related

Plotly sunburst sub-section custom color JavaScript

I'm working with plotly in JS, trying to draw a sunburst chart. Everything works, but i would like to make it so that the child sections on the chart each have a different color. I cant seem to figure it out, any help is extremely appreciated.
Here is how my sunburst looks:
Notice that "Enos" and "Noam" have the same color, I would like them to have either different colors, or at least different opacities.
Like so:
Here is my code:
var data = [{
"type": "sunburst",
"labels": ["Eve", "Awan", "Seth", "Enos", "Noam", "Enoch"],
"parents": ["", "Eve", "Eve", "Seth", "Seth", "Awan"],
"values": [100, 20, 80, 60, 20, 20]
}];
var layout = {
sunburstcolorway: ["#636efa", "#ef553b"]
};
Plotly.newPlot('myChart', data, layout)
If you want to have custom colors for your traces, then you need to set the colors array of the marker object. There you can set the color for every single part of the sunburst diagram:
var data = [{
"type": "sunburst",
"labels": ["Eve", "Awan", "Seth", "Enos", "Noam","Enoch"],
"parents": ["", "Eve", "Eve", "Seth", "Seth", "Awan"],
"values": [100, 20, 80, 60, 20, 20],
"opacity" : 1,
"marker": {
colors: ["#ffffff","#fc6e08","#3e81ed","#3293e3","#c429ad","#d99543"]
}
}];
var layout = {
// sunburstcolorway: ["#636efa", "#ef553b"]
};
Plotly.newPlot('myChart', data, layout)
So the first value ("Eve") has the first color of the array, the second value ("Awan")the second color, and so on. In the example, I set the opacity to 1 to get the real colors from the colors array.

Multiple y-axis values against one single x-axis point

I have implemented AMCharts JS library in one of my web apps and am having an issue. Right now i need to add multiple y-axis values to one single x-axis point (which is actually a date). I have 5 values 5,1,5,4,1,3 which contain same x-axis point (same date) but when i observe the graph sometimes 4 is missing while sometimes 5 as shown in the image. Am i really doing something wrong? This is the form of data
{date: "2016-03-29", value: 5}
{date: "2016-03-29", value: 1}
{date: "2016-03-29", value: 5}
{date: "2016-03-29", value: 4}
{date: "2016-03-29", value: 1}
{date: "2016-03-29", value: 3}
{date: "2016-10-20", value: 0}
{date: "2016-10-20", value: 0}
{date: "2016-10-20", value: 0}
There are a couple of issues with your setup.
First, your data is structured incorrectly for a chart with parseDates enabled. You can't have multiple elements of the same date. AmCharts requires that you group your data points if they share the same date/category. This is by design and every single example on the website shows this, so all of your 2016-03-29 and 2016-10-20 points can be reduced into two objects. I'm presuming that those multiple values correspond to different graph objects, so you need unique value fields for each, i.e.
[{
date: "2016-03-29",
value1: 5,
value2: 1,
value3: 5,
value4: 4,
value5: 1,
value6: 3
}, {
date: "2016-10-20"
value1: 0,
value2: 0,
value3: 0
}]
And then you have 6 graph objects with valueFields set to value1 through value6 to accommodate for those points. Again, I'm assuming that you have multiple graphs given your dataset.
Edit
Your comment indicates that this is not the case and they all belong to one graph. You still need to restructure your data and give unique timestamps since you can't have multiple entries with the same timestamp for a parseDates-enabled chart. If those values came in at different times, then provide that information. For example, assuming your data is hourly:
{date: "2016-03-29 01:00", value: 5}
{date: "2016-03-29 02:00", value: 1}
{date: "2016-03-29 03:00", value: 5}
{date: "2016-03-29 04:00", value: 4}
{date: "2016-03-29 05:00", value: 1}
{date: "2016-03-29 06:00", value: 3}
{date: "2016-10-20 01:00", value: 0}
{date: "2016-10-20 02:00", value: 0}
{date: "2016-10-20 03:00", value: 0}
This will work but you have to set your dataDateFormat to match the timestamp (in this case "YYYY-MM-DD JJ:NN") and adjust your minPeriod to accommodate for the smallest interval in between your points (for this example: "hh").
If you don't parse dates, then you can keep your setup, but the chart will look weird with multiple 2016-03-29 entries. Those are your only options.
As for displaying multiple value axes, a value axis needs to be associated with a graph. If you need multiple value axes, then you need multiple graphs. Each graph's valueAxis property needs to be assigned to a valueAxis object or valueAxis id. You can't assign multiple value axes to one graph object. You can see how this works in this example.
If you only have one graph and need to display a second value axis, create a duplicate graph instance and disable visual aspects of it, like so:
valueAxes: [{
"position": "left",
"id": "v1"
}, {
"position": "right",
"id": "v2"
}],
graphs: [{
//initial graph
type: "line",
bullet: "round",
valueField: "value"
}, {
//invisible duplicate graph
//for second axis
lineAlpha: 0,
showBalloons: false,
visibleInLegend: false,
valueAxis: "v2",
valueField: "value"
}],
Demo

Reading CSV in D3 and converting it to array of arrays

I have the following small dataset hardcoded into a variable in my code:
var dataset = [['CENTRAL', 44, 552, 18565],
['NORTHERN', 42, 945, 20092],
['SOUTHERN', 96, 795, 30095],
['PARK', 1, 640, 9341],
['MISSION', 66, 1198, 18542],
['TENDERLOIN', 23, 113, 10735],
['RICHMOND', 9, 561, 9082],
['TARAVAL', 81, 789, 11966],
['INGLESIDE', 5, 1368, 13414],
['BAYVIEW', 7, 985, 14711]];
Now, this dataset is taken directly from a .csv file, that looks like this:
District,Prostitution,VehicleTheft,Totalcrimecount
CENTRAL,44,552,18565
NORTHERN,42,945,20092
SOUTHERN,96,795,30095
PARK,1,640,9341
MISSION,66,1198,18542
TENDERLOIN,23,113,10735
RICHMOND,9,561,9082
TARAVAL,81,789,11966
INGLESIDE,5,1368,13414
BAYVIEW,7,985,14711
However, I'd obviously like to be able to just read in the file, which I've attempted using this:
var dataset_csv = d3.csv("datafile.csv", function(d){
console.log(dataset_csv = d)
});
Which gives me an array of objects that look like this:
[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]
District: "CENTRAL"
Prostitution: "44"
Totalcrimecount: "18565"
VehicleTheft: "552"
My question is, and it might be trivial, how can I transform those objects into an array data structure like my initial dataset? I've been battling with it for some time now. Any hints greatly appreciated.
Use Array#map to iterate over each object and Object.keys to catch only the keys values.
var dataset_csv = [{District: "CENTRAL", Prostitution: "44", Totalcrimecount: "18565", VehicleTheft: "552"}, {District: "WEST", Prostitution: "22", Totalcrimecount: "4324", VehicleTheft: "53"}, {District: "EAST", Prostitution: "11", Totalcrimecount: "23434" , VehicleTheft: "76"}],
datasetArr = dataset_csv.map(v => Object.keys(v).map(c => Number(v[c]) ? Number(v[c]) : v[c]));
console.log(datasetArr);

SVG filter corruption

Using D3, I am creating a dial with a nice lighting effect using SVG with a filter. When displayed at the top of the webpage, everything looks great. When displayed lower down in the page, it usually (9 times out of 10) gets corrupted somehow during page load. I guess this is something to do with the dial being rendered and then moved, with the filter not catching up somehow, but I'm not sure. I hope someone can tell me why. I don't think I can reproduce this in a Fiddle but if I can I'll add a link. Here are the essential parts.
Just the circle without the filter.
The circle with filter applied and looking good.
The circle with filter applied and corrupted. It looks like maybe the filter position is slightly down and right relative to the simple circle.
Filter code:
var defs = svg.append("defs");
defs.append("path").attr({ id: "curve", d: "M20,20 A43,40 0 0,0 66,20" });
var f1 = defs.append("filter").attr({ id: "f1", x: "-10%", y: "-10%", width: "120%", height: "120%" });
f1.append("feGaussianBlur").attr({ "in": "SourceAlpha", stdDeviation: "4", result: "blur" });
f1.append("feOffset").attr({ "in": "blur", dx: 4, dy: 4, result: "offsetBlur" });
f1.append("feSpecularLighting").attr({ "in": "blur", surfaceScale: "5", specularConstant: ".75", specularExponent: "20", "lighting-color": "#eeeeee", result: "specOut" })
.append("fePointLight").attr({ x: "-5000", y: "-10000", z: "20000" });
f1.append("feComposite").attr({ "in": "specOut", in2: "SourceAlpha", operator: "in", result: "specOut" });
f1.append("feComposite").attr({ "in": "SourceGraphic", in2: "specOut", operator: "arithmetic", k1: "0", k2: "1", k3: "1", k4: "0", result: "litPaint" });
var merge = f1.append("feMerge");
merge.append("feMergeNode").attr({ "in": "offsetBlur" });
merge.append("feMergeNode").attr({ "in": "litPaint" });
Filter application:
svg.append("circle").attr({ cx: mid, cy: mid, r: radius, "class": "edge", filter: "url(#f1)" });

Help with JSON structure

I have the following javascript which I need to make dynamic.
data.addRows(2);
data.setValue(0, 0, 'name goes here');
data.setValue(0, 1, value 1 goes here);
data.setValue(0, 2, value 2 goes here);
data.setValue(1, 0, 'name goes here');
data.setValue(1, 1, value 1 goes here);
data.setValue(1, 2, value 2 goes here);
I guess a loop is the best way to go forward:
I have come up with the following json structure:
[
{"User1":{"value1": 50.00,"value2": "100"}},
{"User2":{"value1": 10.00,"value2": "20"}},
{"User3":{"value1": 10.00,"value2": "20"}},
{"User4":{"value1": 10.00,"value2": "20"}},
{"User5":{"value1": 20.00,"value2": "40"}}
]
I think this structure needs improving. Can someone please suggest a better structure to make it very easy for me to extract the data I want to extract from this?
var dataset = [
{uid: 'user1', value1: 50.00, value2: 100},
{uid: 'user2', value1: 10.00, value2: 20},
];
That way you can do data.length to figure out how many values you have and you can loop a bit easier. For example:
for(i = 0; i < dataset.length; i++) {
console.log(data[i].uid);
}
Using your example:
data.addRows(2);
var l = dataset.length, i, x = 0, y = 0;
for(i = 0; i < l; i++) {
data.setValue(y, x, dataset[i].uid); x++;
data.setValue(y, x, dataset[i].value1); x++;
data.setValue(y, x, dataset[i].value2); x=0;
y++;
}
I don't see that you could make it anymore simple, unless there's something special about the data that would allow repeated parts to be separated out in some fashion.
Try something like:
{"users": [
{"value1": 50, "value2": 100},
{"value1": 10, "value2": 20},
{"value1": 10, "value2": 20},
{"value1": 10, "value2": 20},
{"value1": 20, "value2": 40}
]}
Or, if you want to have your users have IDs:
{"users": {
"userId1": {"value1": 50, "value2": 100},
"userId2": {"value1": 10, "value2": 20},
"userId3": {"value1": 10, "value2": 20},
"userId4": {"value1": 10, "value2": 20},
"userId5": {"value1": 20, "value2": 40}
}}
Remember, all numbers in JavaScript are floating-point numbers.
I think you can try something like this, the idea is from ColdFusion SerializeJson()
I assume your data is like a table
user value1 value2
------------------------------------
user1 50 100
user2 10 20
...
the json structure is
{"COLUMNS":["USER","VALUE1","VALUE2"],"DATA":[["user1",50.0,100.0],["user2",10.0,20.0]]}
more clear reading
{
"COLUMNS":
[
"USER",
"VALUE1",
"VALUE2"
],
"DATA":
[
[
"user1",
50.0,
100.0
],
[
"user2",
10.0,
20.0
]
]
}
with this structure, we know that every varname.DATA[index][0] is refers to USER
Check this link for json encoding
And for now your json value should be encoded like this
{"id":8,"heading":"heading goes here","content":"<p>content goes here<\/p>"}
Sorry not for you....

Categories