Compare data element with partial mean in d3 - d3.js

I have the following data
[{"devcount" : 1 , "dayofweek" :0, "hour" : 1 },
{"devcount" : 2 , "dayofweek" :0, "hour" : 2 },
{"devcount" : 3 , "dayofweek" :1, "hour" : 2 },
{"devcount" : 4 , "dayofweek" :1, "hour" : 3 },
{"devcount" : 6 , "dayofweek" :1, "hour" : 4 },
{"devcount" : 5 , "dayofweek" :1, "hour" : 5 },
{"devcount" : 7 , "dayofweek" :2, "hour" : 5 },
{"devcount" : 8 , "dayofweek" :2, "hour" : 6 },
{"devcount" : 9 , "dayofweek" :2, "hour" : 7 },
{"devcount" : 10 , "dayofweek" :2, "hour" : 9 }]
It is required to compare the devcount with the group average of devcount for each dayofweek.
i.e. for the fist row, devcount=1 is to be compared with the the average device count for the dayofweek-0 (= 1.5) and "yes" to be returned if the devcount is lesser. Else "No" should be returned.
I have coded as below.
smry=d3.nest()
.key( function(d) { return d.dayofweek;})
.rollup(function(d) {return d3.mean(d, function(g) {return g.devcount; })})
.entries(result);
I am not sure how to compare the smry data and the original data.
The original data will be used in selectAll for creating rectangles and the output after comparison needs for determining the colour of the rectangle

You can do it as shown in the snippet below.
test = [{
"devcount": 1,
"dayofweek": 0,
"hour": 1
}, {
"devcount": 2,
"dayofweek": 0,
"hour": 2
},
{
"devcount": 3,
"dayofweek": 1,
"hour": 2
}, {
"devcount": 4,
"dayofweek": 1,
"hour": 3
}, {
"devcount": 6,
"dayofweek": 1,
"hour": 4
}, {
"devcount": 5,
"dayofweek": 1,
"hour": 5
},
{
"devcount": 7,
"dayofweek": 2,
"hour": 5
}, {
"devcount": 8,
"dayofweek": 2,
"hour": 6
}, {
"devcount": 9,
"dayofweek": 2,
"hour": 7
}, {
"devcount": 10,
"dayofweek": 2,
"hour": 9
}
];
//make the summary using nest
smry = d3.nest()
.key(function(d) {
return d.dayofweek;
})
.rollup(function(d) {
return d3.mean(d, function(g) {
return g.devcount;
})
})
.entries(test);
test.forEach(function(t) {
//find the value from summary for dayofweek
var k = smry.find(function(s) {
return (s.key == t.dayofweek)
});
//check the day of week with the mean, set the flag in the data
if(k.values<t.devcount){
t.flag = true;
} else {
t.flag = false;
}
});
console.log(test);//this now has the flag to determine the color
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Related

Trino count query for array

I have a JSON value for a column which is array of objects. Here, my requirement is to find the count of objects matching the filter
Row 1: Coumn 1
{
"createdBy": 2,
"teams": [
{
"companyId" : 1,
"teamId": 1
},
{
"companyId" : 1,
"teamId": 2
}
]
}
Row 2: Coumn 1
{
"createdBy": 2,
"teams": [
{
"companyId" : 1,
"teamId": 3
},
{
"companyId" : 1,
"teamId": 4
}
]
}
Here, companyId 1 presents in 4 places and i need the query to get the count.
Query tried,
select count(1) from a where any_match(
split(
trim(
'[]'
FROM
json_query(
a.teams,
'lax $.companyId' WITH ARRAY WRAPPER
)
),
',"'
),
x -> trim(
'"'
FROM
x
) = 2
)
Here it returns 1 because of any_match. Not sure how to get the size.

Laravel parent parameter in the relation

Good afternoon I ran into a problem
database structure
langs
id
title
1
ru
2
en
articles
id
alias
1
test_article_1
2
test_article_2
article_lang
article_id
lang_id
1
1
2
1
1
2
2
2
article_title_lang
article_id
lang_id
title
1
1
novost_1
2
1
novost_2
1
2
article_1
2
2
article_2
models:
Langs
public function articles()
{
return $this->belongsToMany(Articles::class, 'article_lang', 'lang_id', 'article_id');
}
Articles
public function articleTitleLang()
{
// return $this->hasOne(ArticlesTitleLang::class, 'article_id', 'id')->where('lang_id', '=', 1); // i can get titles lang 1
// return $this->hasOne(ArticlesTitleLang::class, 'article_id', 'id')->where('lang_id', '=', 2); // i can get titles lang 2
return $this->hasOne(ArticlesTitleLang::class, 'article_id', 'id'); // always lang id 1 (because the relation has one)
}
in controller:
$articles = Langs::with([
'articles',
'articles.articleTitleLang'
])->get();
return response($articles, 200)
return json:
[
{
"id": 1,
"title": "ru",
"articles": [
{
"id": 1,
"alias": "test_article_1",
"pivot": {
"lang_id": 1,
"article_id": 1
},
"article_title_lang": {
"title": "novost_1",
"article_id": 1,
"lang_id": 1,
}
},
{
"id": 2,
"alias": "test_article_2",
"pivot": {
"lang_id": 1,
"article_id": 2
},
"article_title_lang": {
"title": "novost_1",
"article_id": 2,
"lang_id": 1,
}
}
]
},
{
"id": 2,
"title": "en",
"articles": [
{
"id": 1,
"alias": "test_article_1",
"pivot": {
"lang_id": 2,
"article_id": 1
},
"article_title_lang": {
"title": "novost_1",
"article_id": 1,
"lang_id": 1,
}
},
{
"id": 2,
"alias": "test_article_2",
"pivot": {
"lang_id": 2,
"article_id": 2
},
"article_title_lang": {
"title": "novost_2",
"article_id": 2,
"lang_id": 1,
}
}
]
}
]
I need to change the dynamic value in the Articles model depending on the parent language value, so that when the language value is "en", the result is "title" = article_1, article_2
you can try this, in Articles Model
public function articleTitleLang()
{
return $this->hasMany(ArticlesTitleLang::class, 'article_id', 'id')
->where('lang_id', $this->lang_id)->first();
}

Show Label on Aggregate (Crossfilter + Reductio)

I have some (simplified) data as follows:
{ "PO": 1353901, "Qty": 1, "Levels": 3 },
{ "PO": 1353901, "Qty": 2, "Levels": 3 },
{ "PO": 50048309,"Qty": 1, "Levels": 1 },
{ "PO": 50048309,"Qty": 4, "Levels": 1 },
{ "PO": 50048309,"Qty": 1, "Levels": 1 }
You see here data for two purchase orders, each row representing a unique product and how much of it was used. You also see how many levels those products were spread out over.
A dimension to help understand cost is material density. That is, how many items were used per level. In the case of 1353901 there were three items used on three levels (Qty gets aggregated, Levels do not), resulting in one item per level.
For 50048309 there are six items used on one level, showing a much higher implant density. This tells me it was a lot of work focused in one place.
Filtering on flat data is easy, and not hard to group into ranges. Take Levels for example:
var levels = ndx.dimension(function (d) {
var level = d.Levels;
if (level == 1) {
return 'One';
} else if (level == 2) {
return 'Two';
} else if (level == 3) {
return 'Three';
} else {
return 'Four +';
}
});
I can easily create groups and ranges within a dimension.
What I cannot seem to do is the exact same thing for aggregates. I want to look at (filter) PO by number of materials used per level. It's not a hard figure to get per purchase order, but it seems hard to look at in groups. Example Below:
https://jsfiddle.net/efefdtcj/2/
Since I started with a Dimension based on aggregating at the PO, I'm getting a row back for each PO.
How do I get one row back per QtyPerLevel range?
I think you need to pre-calculate. That is, add a new property to each PO line with the value of the total quantity in the PO. While you're at it, you might as well calculate QtyPerLevel as well:
{ "PO": 1353901, "Qty": 1, "Levels": 3, "TotalQty": 3, "QtyPerLevel": 1 },
{ "PO": 1353901, "Qty": 2, "Levels": 3, "TotalQty": 3, "QtyPerLevel": 1 },
{ "PO": 50048309,"Qty": 1, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 },
{ "PO": 50048309,"Qty": 4, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 },
{ "PO": 50048309,"Qty": 1, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 }
Then create a Crossfilter dimension on QtyPerLevel and filter or group on that:
var ndx = crossfilter([
{ "PO": 1353901, "Qty": 1, "Levels": 3, "TotalQty": 3, "QtyPerLevel": 1 },
{ "PO": 1353901, "Qty": 2, "Levels": 3, "TotalQty": 3, "QtyPerLevel": 1 },
{ "PO": 50048309,"Qty": 1, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 },
{ "PO": 50048309,"Qty": 4, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 },
{ "PO": 50048309,"Qty": 1, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 }]);
var qtyPerLevelDim = ndx.dimension(function(d) { return d.QtyPerLevel; });
var qtyPerLevelGrp = qtyPerLevelDim.group();

RethinkDB Compound Index Weirdness Using Between

I've noticed something strange with compound indexes in the between function in RethinkDB. It seems to retrieve results that don't match the query. It's all detailed below.
r.dbCreate('test')
r.db('test').tableCreate('numbers')
r.db('test').table('numbers').insert([
{ first: 1, second: 1 },
{ first: 1, second: 2 },
{ first: 1, second: 3 },
{ first: 1, second: 4 },
{ first: 1, second: 5 },
{ first: 2, second: 1 },
{ first: 2, second: 2 },
{ first: 2, second: 3 },
{ first: 2, second: 4 },
{ first: 2, second: 5 },
{ first: 3, second: 1 },
{ first: 3, second: 2 },
{ first: 3, second: 3 },
{ first: 3, second: 4 },
{ first: 3, second: 5 },
{ first: 4, second: 1 },
{ first: 4, second: 2 },
{ first: 4, second: 3 },
{ first: 4, second: 4 },
{ first: 4, second: 5 },
{ first: 5, second: 1 },
{ first: 5, second: 2 },
{ first: 5, second: 3 },
{ first: 5, second: 4 },
{ first: 5, second: 5 }
])
r.db('test').table('numbers').indexCreate(
"both", [r.row("first"), r.row("second")])
r.db('test').table('numbers').orderBy({index :'both'}).between(
[2, 3], [3, 5], {index: 'both', rightBound: 'closed'}).without('id')
// output
{ "first": 3 ,
"second": 3
} // ok
{ "first": 3 ,
"second": 4
} // ok
{ "first": 2 ,
"second": 5
} // ok
{ "first": 3 ,
"second": 1
} // not ok
{ "first": 3 ,
"second": 5
} // ok
{ "first": 3 ,
"second": 2
} // not ok
{ "first": 2 ,
"second": 3
} // ok
{ "first": 2 ,
"second": 4
} // ok
The array in the query doesn't appear to act like an AND or an OR. Am I missing something or is this a bug?
Ok so thanks to some help from originalexe over on the Slack channel I've figured this out. It's behaving as normal and essentially the array is treated as a single value and the query returns all values that are between the two in an ordered list.

D3 cross tabulation HTML table

I'm trying to create a D3 cross tabulation HTML table (there will be more interactive features, this is just the first step) based on JSON data. I can populate the horizontal table header, but am having trouble with the vertical headers and data fields.
The table should look something like the following:
My code so far (JSFiddle here) is:
var nested = d3.nest()
.key(function(d) { return d._id.env; })
.entries(data.result);
console.log(nested);
var table = d3.select("#table")
.append("table")
.style("border-collapse", "collapse")
.style("border", "2px black solid");
var thead = table.append("thead");
thead.append("tr")
.selectAll("th")
.data(nested)
.enter().append("th")
.text(function(d) { return d.key; });
var tbody = table.append("tbody");
var tr = tbody.selectAll("tr")
.data(nested.values) // not sure how to get this
.enter().append("tr");
tr.selectAll("td")
.data(function(d) { console.log(d); return d; })
.enter().append("td")
.text(function(d, i) { console.log(d[i]); return d; });
The raw data is in the following format:
{
"result" : [
{
"_id" : {
"month" : 5,
"day" : 6,
"year" : 2014,
"env" : "A"
},
"ruleScore" : 83.25,
"jsPerPage" : 12,
"cssPerPage" : 4,
"imagesPerPage" : 7.75
},
{
"_id" : {
"month" : 5,
"day" : 6,
"year" : 2014,
"env" : "B"
},
"ruleScore" : 83,
"jsPerPage" : 12,
"cssPerPage" : 4,
"imagesPerPage" : 10
},
{
"_id" : {
"month" : 5,
"day" : 6,
"year" : 2014,
"env" : "C"
},
"ruleScore" : 83,
"jsPerPage" : 12,
"cssPerPage" : 5,
"imagesPerPage" : 10,
},
{
"_id" : {
"month" : 5,
"day" : 6,
"year" : 2014,
"env" : "D"
},
"ruleScore" : 83.08333333333333,
"jsPerPage" : 12,
"cssPerPage" : 6,
"imagesPerPage" : 9.25
}
],
"ok" : 1
}
I'm guessing this is pretty simple, just can't get my head around it - thanks!

Resources