Multi series not working in Bar Chart in Recharts - recharts

I need to create a bar graph with one of the format below. data1 or data2
const data1 = [ { day: 'ABC', data :[ {job_name: "Mon", value: 4}, {job_name: "Tue", value: 5}, {job_name: "Thu", value: 18}, {job_name: "Fri", value: 5} ] }, { day: 'DEF', data :[ {job_name: "Mon", value: 12}, {job_name: "Tue", value: 15}, {job_name: "Wed", value: 18}, {job_name: "Fri", value: 8} ] }, { day: 'XYZ', data :[ {job_name: "Mon", value: 12}, {job_name: "Tue", value: 15}, {job_name: "Wed", value: 18}, {job_name: "Thu", value: 8} ] } ];
const data2 = [ { day: 'Mon', data :[ {job_name: "ABC", value: 4}, {job_name: "DEF", value: 5}, {job_name: "XYZ", value: 8} ] }, { day: 'Tue', data :[ {job_name: "ABC", value: 12}, {job_name: "DEF", value: 15}, {job_name: "XYZ", value: 18} ] }, { day: 'Wed', data :[ {job_name: "DEF", value: 15}, {job_name: "XYZ", value: 18} ] }, { day: 'Thu', data :[ {job_name: "ABC", value: 12}, {job_name: "XYZ", value: 18} ] }, { day: 'Fri', data :[ {job_name: "ABC", value: 12}, {job_name: "DEF", value: 15} ] } ];

Short answer, you can't. The shape of the data in your samples aren't suitable for Rechart.
Please look up the documentation of Rechart - BarChart -> data and reshape your data accordingly.
Here's an example of the required data format from the same page:
const data = [
{
"name": "Page A",
"uv": 4000,
"pv": 2400,
"amt": 2400
},
{
"name": "Page B",
"uv": 3000,
"pv": 1398,
"amt": 2210
}
Where name is the x-axis data label, and uv, pv and amt are the values of the data series.
So a more hands on example:
const data = [
{
"name": "2019-11-01",
"morning_temp": 8,
"midday_temp": 14,
"evening_temp": 10
},
{
"name": "2019-11-02",
"morning_temp": 5,
"midday_temp": 18,
"evening_temp": 7
},
...
Though from my own experience changing the shape you have can be challenging and possibly will end up a high complexity function. If you can't change the data shape you may have a look at react-vis -> sample as react-vis' data-shape looks more similar to your samples.
Either case the data has to be in the right shape.

Related

RadDataForm Multiple select in nativescript-vue

I have this TKEntityProperty:
<TKEntityProperty v-tkDataFormProperty name="groups" displayName="Groups" index="2" :valuesProvider="retrieveGroups">
and this gets values from below object:
retrieveGroups:[
{key: "1", "label": "Group 1"},
{key: "2", "label": "Group 2"},
{key: "3", "label": "Group 3"}
]
but it does not multi select. I want to select multiple elements.
Is there another type of editor available ?
As #Manoj suggested, you should use AutoCompleteInline
Here is an example, it is available at Nativescript github page
data() {
return {
title: description,
booking: new Booking(),
bookingMetadata: {
'isReadOnly': false,
'commitMode': DataFormCommitMode.Immediate,
'validationMode': DataFormValidationMode.Immediate,
'propertyAnnotations': [{
'name': 'from',
'displayName': 'From:',
'index': 0,
'editor': DataFormEditorType.AutoCompleteInline,
'editorParams': {
'autoCompleteDisplayMode': AutoCompleteDisplayMode.Tokens
},
'valuesProvider': fromProviders,
},
{
'name': 'to',
'displayName': 'To:',
'index': 1,
'editor': DataFormEditorType.AutoCompleteInline,
'editorParams': {
'autoCompleteDisplayMode': AutoCompleteDisplayMode.Plain
},
'valuesProvider': ['New York', 'Washington', 'Los Angeles'],
},
]
}
};
},

dc.js Flatten Data vs Array of Objects and filtering

I would like to understand if the following is possible. If have two jsFiddle examples with the same dataset. One contains an array of objects while the other is flatten. I have also added some records that are not fully scoped.
Can the filter on the scatter plot work correctly for the Array of Objects dataset?
Data - Flatten : jsFiddle Example
var data = [
{"_uid": 1, "business": 'Resort', "state": {name: 'Virginia', startups: 15}},
{"_uid": 1, "business": 'Resort', "state": {name: 'Maryland', startups: 6}},
{"_uid": 3, "business": 'Training', "state": {name: 'Virginia', startups: 4}},
{"_uid": 3, "business": 'Training', "state": {name: 'Maryland', startups: 2}},
{"_uid": 3, "business": 'Training', "state": {name: 'D.C.', startups: 3}},
{"_uid": 4, "business": 'Sitting'},
{"_uid": 5, "business": 'Vet', "state": {name: 'Virginia', startups: 4}},
{"_uid": 6, "business": 'Parties', "state": {}},
{"_uid": 7, "business": 'Grooming', "state": {name: 'Virginia', startups: 4}},
{"_uid": 7, "business": 'Grooming', "state": {name: 'D.C.', startups: 3}},
];
Data - Array of Objects : jsFiddle Example
var data = [
{"_uid": 1, "business": 'Resort', "states": [{state: 'Virginia', startups: 15}, {state: 'Maryland', startups: 6}]},
{"_uid": 3, "business": 'Training', "states": [{state: 'Virginia', startups: 4}, {state: 'Maryland', startups: 2}, {state: 'D.C.', startups: 3}]},
{"_uid": 4, "business": 'Sitting'},
{"_uid": 5, "business": 'Vet', "states": [{state: 'Virginia', startups: 4}]},
{"_uid": 6, "business": 'Parties', "state": {}},
{"_uid": 7, "business": 'Grooming', "states": [{state: 'Virginia', startups: 4}, {state: 'D.C.', startups: 3}]}
];
The data is displayed correctly for both datasets.
If I select the Pet Business Type - "Grooming" and brush the scatter plot vertically on 3 the filtered data is correct for the Flatten dataset, but not correct for the Array of Objects dataset.
Flatten dataset - Filtered
CORRECT - It is showing that "Training" also has a startup value of "3"
Array of Objects - Filtered
INCORRECT - All of the business types are showing up along with the other state "Virginia" for "Grooming".
I know we are asking a lot out of Crossfilter and dc.js by not flattening the data, but is this possible?

How to make such a schedule?

It is necessary that all lines had different colors
The lines can be a maximum of 10 pieces
help me please
http://demos.telerik.com/kendo-ui/bar-charts/stacked-bar (It was not possible to make different color lines in each category :( )
You can use the colorField property (API: http://docs.telerik.com/kendo-ui/api/javascript/dataviz/ui/chart#configuration-series.colorField)
var data = [
{x: "Name 1", y: 16, valueColor: "#556270"},
{x: "Name 2", y: 13, valueColor: "#4ECDC4"},
{x: "Name 3", y: 15, valueColor: "#C7F464"},
{x: "Name 4", y: 14, valueColor: "#FF6B6B"},
{x: "Name 5", y: 16, valueColor: "#C44D58"},
];
$("#chart").kendoChart({
dataSource: data,
series: [{
type: "bar",
field: "y",
categoryField: "x",
colorField: "valueColor"
}],
});
DEMO

c3js: Uncaught TypeError: c.forEach is not a function

I'm trying to create a simple line-graph of points using a timeseries axis, but the chart doesn't render and my browser console shows the error:
c3.min.js Uncaught TypeError: c.forEach is not a function
Here's my javascript:
var chart = c3.generate({
bindto: '#chart',
data: {
json: [
{date: "2016-01-01", pageviews: 1},
{date: "2016-01-02", pageviews: 2},
{date: "2016-01-03", pageviews: 3},
{date: "2016-01-04", pageviews: 4},
{date: "2016-01-05", pageviews: 5}],
keys: {
x: 'date',
value: 'pageviews'
}
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y-%m-%d'
}
}
}
});
And here's a jsfiddle which uses the un-minified sources for D3 and C3 and gives the following browser console error: Uncaught TypeError: targetKeys.forEach is not a function
The data.keys.value is expecting an array, so simply wrap 'pageviews' in square brackets like so:
var chart = c3.generate({
bindto: '#chart',
data: {
json: [
{date: "2016-01-01", pageviews: 1},
{date: "2016-01-02", pageviews: 2},
{date: "2016-01-03", pageviews: 3},
{date: "2016-01-04", pageviews: 4},
{date: "2016-01-05", pageviews: 5}],
keys: {
x: 'date',
value: ['pageviews'] // needs to be an array
}
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y-%m-%d'
}
}
}
});
Working jsfiddle for completeness

How to manipulate the reduce function in crossfilter in a way to create a certain array/object structure?

I'm using crossfilter and am looking for a certain output after the reduce function:
var ndx = crossfilter(data);
var alDim = ndx.dimension(function(d) { return d.al_code_unique; });
var seatsPaxAirline = alDim.group().reduce(
function(a, d) {
a.seats += d.seats;
a.pax += d.pax;
return a;
},
function(a, d) {
a.seats -= d.seats;
a.pax -= d.pax;
return a;
},
function() {
return {seats:0, pax:0 }; }
).top(100);
seatsPaxAirline is now an array of objects like this:
[
{key: "5Y", value: {pax: 60, seats: 100}},
{key: "4Y", value: {pax: 50, seats: 90}},
{key: "3Y", value: {pax: 40, seats: 80}}
]
But I do need the following output from the crossfilter reduce function:
[
{key: "5Y", value: [ {name: "pax", value: 60}, {name: "seats", value: 100}},
{key: "4Y", value: [ {name: "pax", value: 50}, {name: "seats", value: 90}},
{key: "3Y", value: [ {name: "pax", value: 40}, {name: "seats", value: 80}},
]
I feel it's just a question of changing the reduce function in a certain manner but unfortunately I have no clue. Could someone help me on this? Thanks in advance!
As far as I understand the question, you need to change your reduce function like so:
var seatsPaxAirline = alDim.group().reduce(
function(a, d) {
a[0].value += d.seats;
a[1].value += d.pax;
return a;
},
function(a, d) {
a[0].value -= d.seats;
a[1].value -= d.pax;
return a;
},
function() {
return [{name: 'seats', value: 0}, {name: 'pax', value: 0}]; }
).top(100);
The key is in how you set up the reduceInitial function, as that will determine the data structure of your 'a' object that gets passed through the reduce.
From what I understand, your input format is similar to:
var seatsPaxAirline =
[{key: "5Y", value: {pax: 60, seats: 100}},
{key: "5Y", value: {pax: 40, seats: 100}},
{key: "3Y", value: {pax: 30, seats: 100}},
{key: "2Y", value: {pax: 70, seats: 100}},
{key: "4Y", value: {pax: 50, seats: 100}},
{key: "1Y", value: {pax: 45, seats: 100}},
{key: "2Y", value: {pax: 50, seats: 100}},
{key: "5Y", value: {pax: 60, seats: 100}},
{key: "5Y", value: {pax: 65, seats: 100}},
{key: "5Y", value: {pax: 55, seats: 100}}
];
And, you wish to group elements based on their key values like:
{
"5Y": [{"key": "5Y", "value": {"pax": 60, "seats": 100}},
{"key": "5Y", "value": {"pax": 40, "seats": 100}},
{"key": "5Y", "value": {"pax": 60, "seats": 100}},
{"key": "5Y", "value": {"pax": 65, "seats": 100}},
{"key": "5Y", "value": {"pax": 55, "seats": 100}}],
"3Y": [{"key": "3Y", "value": {"pax": 30, "seats": 100}}],
"2Y": [{"key": "2Y", "value": {"pax": 70, "seats": 100}},
{"key": "2Y", "value": {"pax": 50, "seats": 100}}],
"4Y": [{"key": "4Y", "value": {"pax": 50, "seats": 100}}],
"1Y": [{"key": "1Y", "value": {"pax": 45, "seats": 100}}]
}
If this is what you are looking to achieve using D3 then this is the way to do it:
d3.nest().key(function(d){return d.key}).map(seatsPaxAirline);
And, here's the working demo.
EDIT:
I believe the sample object you've provided is malformed. But, if you modify the code I provided as shown below:
var output = d3.nest().key(function(d){return d.key}).map(seatsPaxAirline);
d3.entries(d3.entries(output).forEach(function(d,i){
d.value.forEach(function(o,j){
delete o["key"];
d.value[j] = d3.entries(o.value);
});
}));
output = d3.entries(output);
The output you'll get is:
[{
"key": "5Y",
"value": [
[{"key": "pax","value": 60}, {"key": "seats","value": 100}],
[{"key": "pax","value": 40}, {"key": "seats","value": 100}],
[{"key": "pax","value": 60}, {"key": "seats","value": 100}],
[{"key": "pax","value": 65}, {"key": "seats","value": 100}],
[{"key": "pax","value": 55}, {"key": "seats","value": 100}]
]
}, {
"key": "3Y",
"value": [
[{"key": "pax","value": 30}, {"key": "seats","value": 100}]
]
}, {
"key": "2Y",
"value": [
[{"key": "pax","value": 70}, {"key": "seats","value": 100}],
[{"key": "pax","value": 50}, {"key": "seats","value": 100}]
]
}, {
"key": "4Y",
"value": [
[{"key": "pax","value": 50}, {"key": "seats","value": 100}]
]
}, {
"key": "1Y",
"value": [
[{"key": "pax","value": 45}, {"key": "seats","value": 100}]
]
}]
This is as close as I can get it to the desired data structure. See if this is usable for you.
Updated Demo
PS: I realize that this isn't the most efficient of solutions but this is as good as it gets with me & D3. If you wish to fool around with the data structure, consider using underscoreJS.

Resources