How to plot a week interval in X axis using c3js? - d3.js

I want to plot a graph with c3.js library that displays a week interval in x axis as the picture below:
I have a JSON file that has several dates in it that I would like to use:
{
"foo": 1,
"date": "2016-09-20"
},
{
"foo": 2,
"date": "2016-09-21"
},
{
...
}
How do I do that?

I would have made this is a comment, however I cannot, so my recommendation would be to create this line graph using d3.js not c3.js. Here is a really good tutorial Setting up axes in d3.js that will generate the above chart and you can customise the x axis to what ever you want. weekly x axis

I discovered the answer for this question.
My JSON data has a field called "weekDetails", that contains a string with the week interval, like "Sep 22-28" for each register. With this information in mind, i have to call a function like below to load the json and specify the key value for X axis, that is "weekDetails"
chart.load({
json: myJson,
keys: {
x: 'weekDetails',
value: ['value1', 'value2', 'value3']
}
});
After that, you have to change the property x: to 'category' in c3.generate() function, like below:
axis: {
x: {
type: 'category'
}
}
And my json file would be like:
{
"foo": "foo",
"weekDetails": "Sep 1-7"
},
{
"foo": "foo",
"weekDetails": "Sep 8-15"
},
{
"foo": "foo",
"weekDetails": "Sep 16-23"
}...

Related

Value based on percentage doughnut char.js

I want to show a number if doughnut charts in my application. Lets say for example it's based on a number of flights at a airfield.
There are 800 flights in the next 4 hours. I want to have 4 doughnut charts displaying data.
Number of flights getting ready in the next 30 minutes
Number of flights getting ready in the next 5 minutes
Number of flights ready now
Number of flights that are delayed
I'm using chart.js to create the donuts but as far as I can see I can only use static numbers:
this.data = {
datasets: [
{
data: [
300,
],
backgroundColor: [
'#FF6384',
],
hoverBackgroundColor: [
'#FF6384',
]
}]
};
This fills the whole chart. I'm thinking there's 2 ways to solve this problem:
Chart.js supports some kind of max value (800) and based on the actual number (300) fills the chart based on that ratio.
I could use 2 values in the data array. One is the actual number of flights (300) and the other is the difference to the max value (500) = 800.
But I can't use variable values in an array:
this.data = {
datasets: [
{
data: [
this.number1,
this.number2
],
backgroundColor: [
'#FF6384',
'#36A2EB'
],
}]
};
Are undefined.
By pulling the this.data object out of the constructor and building it in a function I can calculate the correct values.
constructor() {
this.calcArray(500);
}
calcArray(value: number) {
const difference = Math.abs(this.max - value);
this.data = {
datasets: [
{
data: [
difference, value
],
backgroundColor: [
'#FF6384',
'#36A2EB'
],
hoverBackgroundColor: [
'#FF6384',
'#36A2EB'
]
}]
};
}
So might need to make this a class so I can use it for multiple values.

Different size for the same view on CouchDB

I have two databases with similar data (organized differently) and I've created a view for each one returning the same response. I have notice that the time response of the query is different even returning the same response, one being 3182ms, other being 217ms approximately, having queried 5 times.
I query both using:
curl -x GET ...db1/_design/query1/view/q1?group=true and
curl -x GET ...db2/_design/query1/view/q1?group=true.
I have checked the data sizes of the design documents using curl -x GET ...db1/_design/query1/_info. The design data size of the first is 146073878 bites and the second is 3739596 bites.
I thought both should have the same size, because they return the same view, and i havent used any filters, both views beeing equal.
Somebody can explain me why the same view created by different databases have different sizes?
My data is organized using two differents roots, but the same data, changing only the root:
Customer data in the root:
{
"c_customer_sk": 65836,
"c_first_name": "Frank",
"c_last_name": "White",
"store_sales": [
{
"ss_sales_price": 20.24,
"ss_ext_sales_price": 1012,
"ss_coupon_amt": 0,
"date": [
{
"d_month_seq": 1187,
"d_year": 1998
}
],
"item": [
{
"i_item_sk": 10454,
"i_item_id": "AAAAAAAAGNICAAAA",
"i_item_desc": "Results highlight as patterns; so right years show. Sometimes suitable lips move with the critics. English, old mothers ought to lift now perhaps future managers. Active, single ch",
"i_current_price": 2.88,
"i_class": "romance",
"i_category_id": 9,
"i_category": "Books"
}
]
},
{
"ss_sales_price": 225,
"ss_ext_sales_price": 1023,
"ss_coupon_amt": 0,...
View function for customer in the root:
function(doc)
{
for each (store_sales in doc.store_sales) {
var s=store_sales.ss_ext_sales_price;
if(s==null){s=0}
for each (item in store_sales.item){
var item_id=item.i_item_id;
var item_desc=item.i_item_desc;
var category=item.i_category;
var class=item.i_class;
var price=item.i_current_price;}
if(category=="Music" || category=="Home" || category=="Sports"){
for each (date in store_sales.date){
var g=date.d_month_seq;}
if (g>=1200 && g<=1211){
emit({item_id:item_id,item_desc:item_desc, category:category, class:class, current_price:price},s);
}
}}}
reduce:_sum
Example of answer:
key:
{"item_id": "AAAAAAAAAAAEAAAA", "item_desc": "Rates expect probably necessary events. Circumstan", "category": "Sports", "class": "optics", "current_price": 3.99}
Value:
106079.49999999999
Item data in the root:
{
"i_item_sk": 10454,
"i_item_id": "AAAAAAAAGNICAAAA",
"i_item_desc": "Results highlight as patterns; so right years show. Sometimes suitable lips move with the critics. English, old mothers ought to lift now perhaps future managers. Active, single ch",
"i_current_price": 2.88,
"i_class": "romance",
"i_category_id": 9,
"i_category": "Books",
"store_sales": [
{
"ss_sales_price": 20.24,
"ss_ext_sales_price": 1012,
"ss_coupon_amt": 0,
"date": [
{
"d_month_seq": 1187,
"d_year": 1998
}
],
"customer": [
{
"c_customer_sk": 65836,
"c_first_name": "Frank",
"c_last_name": "White",
}
]
},
{
"ss_sales_price": 225,
"ss_ext_sales_price": 1023,
"ss_coupon_amt": 0,...
View for item on root:
function(doc)
{
var item_id=doc.i_item_id;
var item_desc=doc.i_item_desc;
var category=doc.i_category;
var class=doc.i_class;
var price=doc.i_current_price;
if(category=="Music" || category=="Home" || category=="Sports"){
for each (store_sales in doc.store_sales) {
var s=store_sales.ss_ext_sales_price;
if(s==null){s=0}
for each (date in store_sales.date){
var g=date.d_month_seq;}
if (g>=1200 && g<=1211){
emit({item_id:item_id,item_desc:item_desc, category:category, class:class, current_price:price},s);
}
}}}
reduce:_sum
Returning the same answer.
I have made the cleanup and compaction of the designs and the time response of the database which the itens data are in the root is much faster, and the sizes of the data size is smaller too, but I dont know why.
Can someone explain me?
could it be a difference of database compaction? When you replicate an existing databases to an empty one, only the last revision of each documents are sent to the new one, making it potentially way lighter. The same applies to views

KendoUI Grid: Array as a field

I have a data source, which gets built from a JSON data string, containing a field called Fruit:
[{
... /other entries
fruit: [{
name: 1
}, {
name: 2
}, {
name: 3
}]
}]
I'm using this field in a KGrid, and would like to do a comma seperated list of links, from the names:
1, 2, 3
Currently, I'm hooking into the dataBound function, and build this up individually for the fruit field, is there an easier way to do this with, let's say, a template? I tried to look up information about something similar in the docs, but couldn't find anything pertaining to splitting arrays?
I wouldn't transform the data at the data source. That job is the responsibility of the UI component. Instead move your logic to the column template function of your grid. [ API reference ]
$('#grid').kendoGrid({
columns: [ {
field: 'fruit',
template: function(dataItem) {
var html = [];
for (var i = 0; i < dataItem.length; i++) {
html.push('' + dataItem[i].name + '');
}
return html.join(', ');
}
}],
dataSource: data
});

Kendoui chart - stacked columns and dates

It seems that I just cannot get beyond this issue.This is an example of dataset:
[
{ type: "FOO", date: 1396952060722, count: 3 },
{ type: "BAR", date: 1396952060722, count: 2 },
{ type: "FOO", date: 1396952060722, count: 4 },
{ type: "BAZ", date: 1396952060722, count: 1 },
{ type: "FOO", date: 1396952060722, count: 3 },
{ type: "FOO", date: 1396952060722, count: 3 }
]
How can I make stacked column chart where X axis holds dates and columns are stacked by type with count fields summed (Y axis) if they fall under the same date.
I also need a way to regulate date granularity (year/month/day) and the data should distribute accordingly.
Is there a buildin way to do this or I'll have to make complex data transform?
I've found this googling a bit:
KendoUI - DataViz - Grouping and Aggregating a JSON datasource within the chart
I believe this solves your problem.

Translating JSON into custom dijit objects

I am looking for an example where JSON constructed from the server side is used to represent objects that are then translated into customized widgets in dojo. The JSON would have to be very specific in its structure, so it would not be a very general solution. Could someone point me to an example of this. It would essentially be the reverse of this
http://docs.dojocampus.org/dojo/formToJson
First of all let me point out that JSON produced by dojo.formToJson() is not enough to recreate the original widgets:
{"field1": "value1", "field2": "value2"}
field1 can be literally anything: a checkbox, a radio button, a select, a text area, a text box, or anything else. You have to be more specific what widgets to use to represent fields. And I am not even touching the whole UI presentation layer: placement, styling, and so on.
But it is possible to a certain degree.
If we want to use Dojo widgets (Dijits), we can leverage the fact that they all are created uniformly:
var myDijit = new dijit.form.DijitName(props, node);
In this line:
dijit.form.DijitName is a dijit's class.
props is a dijit-specific properties.
node is an anchor node where to place this dijit. It is optional, and you don't need to specify it, but at some point you have to insert your dijit manually.
So let's encode this information as a JSON string taking this dijit snippet as an example:
var myDijit = new dijit.form.DropDownSelect({
options: [
{ label: 'foo', value: 'foo', selected: true },
{ label: 'bar', value: 'bar' }
]
}, "myNode");
The corresponding JSON can be something like that:
{
type: "DropDownSelect",
props: {
options: [
{ label: 'foo', value: 'foo', selected: true },
{ label: 'bar', value: 'bar' }
]
},
node: "myNode"
}
And the code to parse it:
function createDijit(json){
if(!json.type){
throw new Error("type is missing!");
}
var cls = dojo.getObject(json.type, false, dijit.form);
if(!cls){
// we couldn't find the type in dijit.form
// dojox widget? custom widget? let's try the global scope
cls = dojo.getObject(json.type, false);
}
if(!cls){
throw new Error("cannot find your widget type!");
}
var myDijit = new cls(json.props, json.node);
return myDijit;
}
That's it. This snippet correctly handles the dot notation in types, and it is smart enough to check the global scope too, so you can use JSON like that for your custom dijits:
{
type: "my.form.Box",
props: {
label: "The answer is:",
value: 42
},
node: "answer"
}
You can treat DOM elements the same way by wrapping dojo.create() function, which unifies the creation of DOM elements:
var myWidget = dojo.create("input", {
type: "text",
value: "42"
}, "myNode", "replace");
Obviously you can specify any placement option, or no placement at all.
Now let's repeat the familiar procedure and create our JSON sample:
{
tag: "input",
props: {
type: "text",
value: 42
},
node: "myNode",
pos: "replace"
}
And the code to parse it is straightforward:
function createNode(json){
if(!json.tag){
throw new Error("tag is missing!");
}
var myNode = dojo.create(json.tag, json.props, json.node, json.pos);
return myNode;
}
You can even categorize JSON items dynamically:
function create(json){
if("tag" in json){
// this is a node definition
return createNode(json);
}
// otherwise it is a dijit definition
return createDijit(json);
}
You can represent your form as an array of JSON snippets we defined earlier and go over it creating your widgets:
function createForm(array){
dojo.forEach(array, create);
}
All functions are trivial and essentially one-liners — just how I like it ;-)
I hope it'll give you something to build on your own custom solution.

Resources