Making a nested/hierarchical set of tables using D3 - javascript

I have some data which I want to display in html tables using d3. My data is laid out like this:
var dataset = [
{
'name': 'foo',
'children': [
{
'var1': 'hello',
'var2': 87,
...
},
{...},
{...}
]
},
{
'name': 'bar',
'children': [
{
'var1': 'howdy',
...
},
{...},
]
},
{
// and so on...
}
]
Ultimately, I would like to have something similar in style/functionality to this example, where the user can click on the 'foo' row and see everything in the 'foo' group. But for now I'm struggling to display the data at all.
I've made a little jsfiddle to show where I am now. As you can see, I have so far been unsuccessful at showing any of the actual numbers from my data. Does anyone have any ideas on how I should go about this? Should I restructure dataset? Thank you
== EDIT ==
I must apologise for maybe being vague about what I'm trying to do. Here is a mock up of what I ultimately want to achieve, although I stress that this question is more about binding data than layout/transition stuff.

Here's what I would do: http://jsfiddle.net/j43Nb/
Looking at your data, it seems more appropriate to have one table per parent and one row per child, and not wrap the whole thing in one big table. If you really need one big table, just replace the div.section/h4 bits with another table/tr/td sequence.
The key to understanding how "child" objects become an array of cell data is in this bit at the end:
var cells = rows.selectAll('td')
.data(function(d) {
// return cell data as an array of prop values,
// ordered according to prop names in cols
return cols.map(function(prop) {
return d[prop];
})
});
where the field names in cols are used to build a corresponding array of cell values for each given row (child).

Related

How to make on the fly duplicate values validation more efficient using Javascript?

I have a performance question for a React app.
I implementing a "table editing page", the users need to be able to add multiple rows and columns and then set names to them and also have indicators next to the inputs whether these names are empty or not unique.
The table structure when returned from backend is this
{
name: "table name",
columns: [
{
name: "column1",
token: "column1token"
}
],
rows: {
ROWNAME1: {
column1token: "value in ROWNAME1"
}
}
}
I have a preprocessing function which modifies the structure of the rows object in the table to be similar to columns to be kept in the state of the component:
{
name: "table name",
columns: [
{
name: "column1",
token: "column1token"
}
],
rows: [
{
name: "ROWNAME1",
token: "newtoken",
values: {
column1token: "value in ROWNAME1"
}
]
}
Every time user adds a new row/column, it gets inserted into the appropriate array with randomly generated token and an empty name. When changing the name I check in the arrays if it is duplicate or not.
For smaller tables this works fine, but for a table with 300+ rows it becomes slow.
Is there a better approach to solving this task? Can using Map be more efficient than iterating over arrays?
Using Map would definitely be faster than working with arrays. But something here doesn't fit... even with 1,000 items search, Javascript should do it very fast. I would think that you might have a BIG react redraw, instead of small update to the DOM.
Are you using the key property for each row in the table?

Can I rendered javascript object data into c3js chart?

I make a chart by using c3js library. Normally when I click legend, its only shows legend data.
Now, I want to add new Simple Moving Average data without remove existing data when I click a legend.
Here is the sample image of what I want,
If I click dept1 legend, I want to add new SMV value to chart.
Here is what I tried,
function show_svm(data) {
chart.load({
bindto: '#chart',
x: 'date',
xFormat: m_d_format,
json: data,
keys: {
x: 'date',
value: ['Dept1','Dept2','Dept3', 'Dept4','SMV']
}
});
}
In the function argument data is like this,
{
'date':["2015-11-23","2015-11-24","2015-11-25","2015-11-26","2015-11-27","2015-11-30","2015-12-01","2015-12-02","2015-12-03","2015-12-04","2015-12-08","2015-12-09","2015-12-11","2015-12-14","2015-12-15","2015-12-16","2015-12-17","2015-12-18","2015-12-19","2015-12-21","2015-12-22","2015-12-23","2015-12-24","2015-12-25","2015-12-28","2015-12-29","2015-12-30","2016-01-04","2016-01-05","2016-01-06","2016-01-07","2016-01-08","2016-01-09","2016-01-11","2016-01-12","2016-01-13","2016-01-14","2016-01-15","2016-01-18","2016-01-19","2016-01-20","2016-01-21","2016-01-22","2016-01-23","2016-01-24","2016-01-25","2016-01-26","2016-01-27","2016-01-28","2016-01-29","2016-02-01","2016-02-02","2016-02-03","2016-02-04","2016-02-05","2016-02-08"],
'Dept1':["100.00","50.00","57.14","71.43","100.00","42.86","85.71","85.71","71.43","66.67","33.33","100.00","50.00","57.14","66.67","71.43","100.00","57.14","0.00","28.57","57.14","66.67","57.14","57.14","71.43","57.14","57.14","71.43","71.43","71.43","85.71","83.33","100.00","42.86","57.14","57.14","66.67","100.00","71.43","100.00","71.43","14.29","28.57","100.00","50.00","28.57","57.14","57.14","57.14","100.00","42.86","57.14","71.43","71.43","42.86","71.43"],
'SMV':[null,null,null,null,null,null,null,70.407142857143,73.468571428571,74.83,69.387142857143,69.387142857143,70.407142857143,66.325714285714,63.605714285714,63.605714285714,68.367142857143,71.768571428571,57.482857142857,54.421428571429,54.421428571429,54.421428571429,52.38,46.257142857143,48.298571428571,56.461428571429,60.542857142857,62.584285714286,63.264285714286,65.305714285714,69.387142857143,71.087142857143,77.21,75.17,73.128571428571,71.087142857143,70.407142857143,72.448571428571,70.748571428571,70.748571428571,74.83,68.708571428571,64.627142857143,69.388571428571,62.245714285714,56.122857142857,50,47.958571428571,54.08,64.284285714286,56.121428571429,57.141428571429,63.264285714286,65.305714285714,63.265714285714,65.307142857143]
}
This data are came from ajax.
But, this SVM data cannot render on chart and I don't get any error. I don't know why.
The another thing I want to know is, can I use javascript object to json of c3js chart like this: json:data,. Is it correct way or not?. I'm very appreciate for any suggestion.
You have just a few mistakes in your code. First, you used the attribute json. For using that attribute, your data needs to be in the following form:
var data = [
{ 'date': '2015-01-01', 'Dept1': null, 'SMV': 3},
{ 'date': '2015-01-02', 'Dept1': 1, 'SMV': 4}
];
Your data however looks different. You separated all the date, the Dept1 and the SMV data into separate arrays. The way to go here is the following: The data should contain one array of several arrays. The first argument is defined as the key of the dataset. An example dataset looks then like this:
var data = [
['date', '2015-01-01', 2015-01-02'],
['Dept1', null, 1],
['SMV', 3, 4]
];
You then also do not need the keys attribute anymore.
Lastly, you forgot to add the c3 and d3 dependencies in your jsFiddle, what led to the error c3 is not defined. You can find a fixed example of your jsFiddle here: jsFiddle.

Grouping ng-grid by non-displayed column

Lets say I have an array of objects of the pattern
{
name: ...
age: ...
dept: ...
}
And I want to show them on an ng-grid, but I only want columns for name and age
columnDefs: [{field:'name'...},{field:'age'...}
But I want them to be grouped by dept, without showing a dept column.
I've tried to just add a groups: ['dept'] to my grid options, but that doesn't work - it just shows the grid without grouping.
I've also seen a lot of people use gridOptions.groupBy, but when I try
$scope.gridOptions = ...
$scope.gridOptions.groupBy('dept')
I get an (expected) undefined is not a function error. I don't understand how people how people's examples work when gridOptions is just a plain old object.
So my question is: is it possible to group my ng-grid with a non-displayed column?
I found a hack around my problem. I defined the 'group by' column as normal, but I set the width, minWidth, and maxWidth to 0. Additionally, I set resizeable to false.
you can use
$scope.gridOptions = {
columnDefs: [ {field:'name'...}, {field:'age'...}, {field:'dept', visible:false }],
groups: ['dept']
}

Array data appears as undefined?

I have an array declared as so:
$scope.test=['blah', 'blah2'];
And I wanted to use ng-grid as a test to merely display the data. I did the following:
$scope.sourceGridOptionsApprovers = {
plugins: [gridLayoutPlugin],
data : 'test',
columnDefs: [
{field: 'test', displayName: 'Approvers', width:'35%',
cellFilter: 'stringArrayFilter'}
]
};
I wanted to filter the array so I could display the contents of test into one of my columns in ng-grid. I appended the following to my angular controller:
.filter('stringArrayFilter', function(){
return function(myArray) {
//console.log(myArray);
return myArray.join(', ');
};
});
But when I try to display the contents of the array after I filter it, everything shows up as undefined, and I'm thinking it may be the way I passed in the array into the filter, but I'm not entirely sure. Any help would be appreciated.
Here is a plunkr of my example: http://plnkr.co/edit/Ba7hoGFhI7cWWaD3itZx?p=preview
First of all i think ngGrid strictly requires a json object with properties to work on. Without properties the cell cannot be matched to specific data so the data for the cell is 'undefined' => which results in 'undefined' error messages.
So your data need to be like:
$scope.test=[{name: 'blah'}, {name: 'blah2'}];
Secondly the cellfilter is applied per row/cell and not over your whole array. With your example data the single cell data contains no arrays so you will get 'no method join' error messages.
The data should be structured like that with the use of your filter:
$scope.test = [{name: ['blah', 'blah2']}, {name: ['blah3', 'blah4']}];
Here is a full working example:
http://plnkr.co/edit/6EsriMwBNILKzwk3JIR1?p=preview

loading csv into nvd3 to make discrete bar chart

I have the following CSV file:
Fun,Stupid,Yes,No
50,-20,100,70
I'd like to load it into nvd3 to make a discrete bar chart. I know it's easy but it's taking me way to long to manipulate the data.
I've tried the following:
d3.csv("/path/to/file", function(data){
console.log(data);
});
and I get the following object which isn't working with nvd3:
[{Fun:50, Stupid: -20, Yes: 100, No: 70}]
Thanks.
nvd3 is expecting a fairly specific data form so you need to get your data into that form. The form that it is expecting is:
[
{
key: "totals",
values: []
}
];
Where the empty array is filled with the objects from d3.csv and note that nv is expecting the name of the array of your objects to be called values.
So the first step is to create an empty object like this:
var exampleData = [
{
key: "totals",
values: []
}
];
Then fill it with your data:
data.forEach(function (d){
d.value = +d.value
exampleData[0].values.push(d)
})
This all needs to be inside your d3.csv call.
To use this format you need to have your csv file organised into columns with your names in one column and your values in another like:
label, value
Fun, 50
Stupid, -20
And here's a link to a working example

Categories

Resources