Plotly.js define shape of data - javascript

I'm pulling data from an API that comes back in the following format:
[{
"metadata": {"colName": "nameOfCol"},
"value": valueForCol // string or number or whatever
},
...]
But according to Plotly's website, they want two simple arrays of labels and columns:
var data = [{
values: [19, 26, 55],
labels: ['Residential', 'Non-Residential', 'Utility'],
type: 'pie'
}];
or:
var data = [{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
type: 'bar'
}];
Now there's quite a big dataset coming back, so I'd prefer to not have to loop through the whole set and extract the labels and values from everything. Is there a nice way to tell Plotly to loop through my data and find the labels and values?
I don't know what this would look like, maybe something like:
var data = [{
source: myData,
labels: "metadata.colName",
values: "value",
type: "pie"
}]

Short answer: no, there is no feature in Plotly.js for this, you'll unfortunately have to loop through and extract.

Related

Chartjs: Multiple data values for the same label

I'm trying to build a chart that looks like this ...
Chart bar example
However I am not able to use multiple data values for the same label. Does anyone have any ideas? I'm using chart.js
I would like the code to look something like this...
labels: ['category 1, 'category 2'],
datasets: [
{
// values for category one
type: 'bar',
backgroundColor: '#8e5ea2',
data: [111, 222, 333]
}, {
// values for category two
type: 'bar',
backgroundColor: '#3e95cd',
data: [111, 222, 333]
}
]
However, chart.js takes each data item for each label created. I would like to have multiple date items for just one label
Not sure if it will work but you can try to specify the data as an object and then in the first dataset put all the x values to the first label and in the second dataset put all the x values to the second label.
https://www.chartjs.org/docs/master/general/data-structures

Chart.js: passing objects instead of int values as data

Is it possible to pass an array of objects instead of an array of integers? The following code works but results in a flat zero line:
var ctx = document.getElementById("a").getContext("2d");
var data = {
labels: ["Fri", "Sat", "Sun"],
datasets: [{
label: "Chart B",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(150,150,150,1)",
pointColor: "rgba(150,150,150,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [{
y: 48,
name: "Value one",
date: "2015-04-30"
}, {
y: 40,
name: "Value two",
date: "2016-05-30"
}, {
y: 19,
name: "Value three",
date: "2016-06-30"
} ]
}]
};
var Chart = new Chart(ctx).Line(data);
In short, I think your example should work. The key is to use y for the y value in the chart, and to add your arbitrary property to the object, as well.
It looks like this is what you're doing, but you've reported it's not working... It works for me, though! ?
Longer answer
According to the docs for Line, data can be a Number[]:
data: [20, 10]
...but it can also be a Point[]:
data: [{
x: 10,
y: 20
}, {
x: 15,
y: 10
}]
This was intended to be used for sparsely-populated data sets. Through experimentation, I've found you can omit the x property and simply specify the y property. The x value will be inferred, as usual.
You can also add in any other arbitrary properties that can be accessed from your label callback. So, you might end up with something like this:
data: [{
y: 20,
myProperty: "Something"
}, {
y: 10,
myProperty: "Something Else"
}]
I can confirm that answer #rinogo gave works on latests version. You can add custom properties to dataset and use 'em in tooltip or elsewhere afterwards.
First add data to dataset. On my case I only have one set, so I'm just pushing points.
chartData.datasets[0].data.push({
y: groupedBooking.distinctCount,
distinctUsers: distinctUsers
});
... and finally override callback with chartOptions:
options: {
tooltips: {
callbacks: {
label(tooltipItem, data) {
console.log(data);
return data.datasets[0].data[tooltipItem.index].distinctUsers;
}
}
}
}
If you would happen to have multiple datasets you get datasetIndex from tooltipItem as well... so to confirm, X can be omitted from datapoint and customer properties are preserved within object.
In the data structure doc (version 3.5.1 at the time of writing this), it is documented objects can be used as data and parsing option is also available to pick the keys.
Example from the doc:
data: {
datasets: [{
data: [{id: 'Sales', nested: {value: 1500}}, {id: 'Purchases', nested: {value: 500}}]
}]
},
options: {
parsing: {
xAxisKey: 'id',
yAxisKey: 'nested.value'
}
}

Creating A MultiSeries Bar Chart With Different Number of Series For Each Item

I'm currently using highcharts on a project and having a hard time creating a chart I need. I've researched this quite a bit and I don't think highcharts will be able to render the data the way I'm trying and I might need to split this into multiple charts which would be a 'hacky' way of accomplishing what I would like to do.
var mockData = [
{
name: 'Southwest',
partners: ['A1', 'B2', 'C3', 'D4', 'E5'],
data: [23, 42, 67, 53]
},{
name: 'Delta',
partners: ['F6', 'G7'],
data: [55, 32]
},{
name: 'American Airlines',
partners: ['H8', 'I9', 'J10', 'K11', 'L12', 'M13'],
data: [7, 25, 14, 78, 31, 55]
},{
name: 'China Air',
partners: ['N14', 'O15', 'P16', 'Q17', 'R18'],
data: [1, 65, 35, 46, 74]
},{
name: 'Air Mexico',
partners: ['S19', 'T20', 'U21', 'V22', 'W23', 'X24', 'Y25', 'Z26', 'AA27', 'AB28', 'AC29', 'AD30'],
data: [87, 24, 76, 5, 57, 67, 43, 47, 56, 19, 20, 32]
}];
I would like to see the name of each item (Southwest, Delta, AA..) displayed as the label on the y-axis and the name of each 'partner' (A1, B2, C3...), displayed in each bar with the corresponding data determining the length of the bar. So in this case Southwest would have 5 bars, Delta would have 2, AA 6, China Air 5 and Air Mexico 12. With each bar labeled by the partner name.
I believe the problem is that highcharts doesnt support having a different number of series for each particular item. I don't want to put zeros to make all charts have an equal amount of series (bars).
So far the only alternative I see is to create a separate highchart bar chart for each item in mockData and try to make it look like 1 continuous graph.
Additionally I'm a bit worried about rendering 1 large bar chart for this since some of the items can have as many as 250 partners...so this chart will be quite large.
I hope this question is easy enough to understand, but I can clarify any confusion.
Thank you in advance.
I am not sure how this chart suppose to look, so I suggest to use grouped categories plugin, to display data: http://jsfiddle.net/TFhd7/754/
However, as you said, it's not a problem to render 1000 of bars, but readability of the chart will be very bad (just multiplicated data, see: http://jsfiddle.net/TFhd7/755/ )
Sample code for Highcharts:
var categories = [],
seriesData = [];
$.each(mockData, function(i, item) {
categories.push({
name: item.name,
categories: item.partners
});
seriesData = seriesData.concat(item.data);
});
var chart = new Highcharts.Chart({
chart: {
renderTo: "container",
type: "bar"
},
legend: {
enabled: false
},
series: [{
data: seriesData
}],
xAxis: {
categories: categories,
labels: {
x: -4
}
}
});

add custom links to series / data sections in pie chart (highcharts.js)

I am simply trying to allow each data section or series of a pie chart via highcharts to be clickable, eg. Shop section should link to #shop_section I've found demos where a global link was set to every data section in a chart. But I simply would like a unique #link to be accessible via clicking one of my three data sections / series.
series: [{
innerSize: '30%',
data: [
['Shop', 10],
['Buy', 10],
['Own', 10],
]
}]
});
This didn't work: (attempt)
data: [
{name: 'Shop', 10, url: 'http://my_site1.com'},
{name: 'Buy', 10, url: 'http://my_site2.com'},
{name: 'Own', 10, url: 'http://my_site3.com'}
]
Your series is incorrect, it should be:
data: [
{name: 'Shop', y: 10, url: 'http://my_site1.com'},
{name: 'Buy', y: 10, url: 'http://my_site2.com'},
{name: 'Own', y: 10, url: 'http://my_site3.com'}
]
Using plotOptions would do the work:
plotOptions: {
series:{
point:{
events:{
click: function(){
window.location.href = this.url;
}
}
}
},
},
By simply using a series->point->events we can speficy which events to delegate to our series points (in the case of a pie chart a point is a "slice").
On the event handler function itself, this refers to the clicked point, therefore I can directly use the custom property url you've set.

Is there a way to enter Highchart series data without eval?

I have been working on getting data into a highchart graph with much difficulty.
Eventually I had to go with using eval(data).
Is there a better way to do this?
JSFiddle Example
$(function () {
var test = "[[Date.UTC(2013, 4, 08), 45.95],[Date.UTC(2013, 5, 28), 19.95]]";
$('#container').highcharts({
chart: {
},
xAxis: {
type: 'datetime'
},
series: [{
data: eval(test)
}]
});
});
UPDATE 1
My actual objective is to pass a JSON object into a function (as shown below) then get the required strings and pass them to the series input.
The following is still not working.
function showPriceChart(priceData) {
var json = jQuery.parseJSON(priceData);
var pricePrices = [ json.pricePrices ];
// This works if I use eval below
// var pricePrices = '['+json.pricePrices+']';
/// Other chart config goes here
series: [{
name: 'Retailer Price',
data: pricePrices
}, {
name: 'RRP',
data: rrpPrices
}]
});
}
Here is the JSON object from php using print_r():
{"pricePrices":"[Date.UTC(2013, 4, 8), 67],[Date.UTC(2013, 5, 28), 29]","salePrices":"[Date.UTC(2013, 4, 8), ],[Date.UTC(2013, 5, 28), ]","rrpPrices":"[Date.UTC(2013, 4, 8), 67],[Date.UTC(2013, 5, 28), 67]"}
you were really close from your goal.
The following is working :
(http://jsfiddle.net/G6jrU/3/)
$(function () {
var test =[ [ Date.UTC(2013, 4, 08), 45.95 ],
[ Date.UTC(2013, 5, 28), 19.95 ] ];
$('#container').highcharts({
chart: {
},
xAxis: {
type: 'datetime'
},
series: [{ data : test }]
});
});
Rq : You might use JSON to serialize/unserialize data if you need to.
The problem is that you are using Date.UTC() function, so you need to use eval. How about passing numbers(timestamps in milliseconds) instead of that functions? So, your JSON should look this way:
{
"pricePrices":[1367971200000, 67],[1372377600000, 29],
"salePrices":[1367971200000, ],[1372377600000, ], //where are values ?!
"rrpPrices":[1367971200000, 67],[1372377600000, 67] //without extra '"'!!
}
Also, there is some missing values for second series, where are they?

Categories