Rose18 Rose18 - 4 months ago 29
AngularJS Question

Kendo UI - column chart from JSON array

In my AngularJS application I am using Kendo UI to create charts. I have a JSON Array as below.

[
{
"date": "2016-06-24",
"competitor": []
},
{
"date": "2016-06-23",
"competitor": []
},
{
"date": "2016-06-22",
"competitor": []
},
{
"date": "2016-06-21",
"competitor": []
},
{
"date": "2016-06-20",
"competitor": [
{
"price": 1223,
"competitorName": "competitorA"
},
{
"price": 1222,
"competitorName": "competitorB"
}
]
},
{
"date": "2016-06-19",
"competitor": []
},
{
"date": "2016-06-18",
"competitor": []
},
{
"date": "2016-06-17",
"competitor": []
},
{
"date": "2016-06-16",
"competitor": []
},
{
"date": "2016-06-15",
"competitor": []
},
{
"date": "2016-06-14",
"competitor": []
},
{
"date": "2016-06-13",
"competitor": []
},
{
"date": "2016-06-12",
"competitor": []
},
{
"date": "2016-06-11",
"competitor": []
},
{
"date": "2016-06-10",
"competitor": []
},
{
"date": "2016-06-09",
"competitor": [
{
"price": 1345,
"competitorName": "competitorA"
},
{
"price": 1604,
"competitorName": "competitorC"
}
]
},
{
"date": "2016-06-08",
"competitor": []
},
{
"date": "2016-06-07",
"competitor": []
},
{
"date": "2016-06-06",
"competitor": []
},
{
"date": "2016-06-05",
"competitor": []
},
{
"date": "2016-06-04",
"competitor": [
{
"price": 1343,
"competitorName": "competitorB"
},
{
"price": 1604,
"competitorName": "competitorC"
}
]
},
{
"date": "2016-06-03",
"competitor": []
},
{
"date": "2016-06-02",
"competitor": []
},
{
"date": "2016-06-01",
"competitor": []
},
{
"date": "2016-05-31",
"competitor": []
},
{
"date": "2016-05-30",
"competitor": []
},
{
"date": "2016-05-29",
"competitor": [
{
"price": 1370,
"competitorName": "competitorD"
}
]
},
{
"date": "2016-05-28",
"competitor": []
},
{
"date": "2016-05-27",
"competitor": []
},
{
"date": "2016-05-26",
"competitor": []
}
]


I want to create a column chart for these data. The chart should be categorized by date. The thing is, competitors are varying for date by date. As an example, for the date 2016-06-20, competitors are competitorA & competitorB. Also some dates don't have competitors. Some has two or one. That means, in the column chart, column series count is varying date by date.

UPDATED

I just want to set colors for the series of the chart as below.

CompetitorC - Green (every time CompetitorC should be green)
Every Other competitors - blue with different shades

And I want to set chart theme to "back". I tried following.

var transData = [];
for (var i=0; i<data.length; i++){
var date = data[i].date;
if (data[i].competitor.length > 0){
for (var j=0; j<data[i].competitor.length; j++){
var obj = {}
obj.date = date;
obj.competitorName = data[i].competitor[j].competitorName;
obj.price = data[i].competitor[j].price;
if(obj.competitorName==='CompetitorC') {
obj.color = 'green';
}
transData.push(obj);
}
} else {
var obj = {}
obj.date = date;
obj.competitorName = "";
obj.price = "";
transData.push(obj);
}
}


Then in the chart:

series: [{
field: 'price',
categoryField: "date",
name: "#= group.value #",
colorField: 'color'
}]


Then my chart set color green to competitorC but legend is not changing to green. How do I fix it & how can I set blue with different shades to other competitors?

Any suggestions would be highly appreciated.

Thank You

Answer

I would transform you JSON so and then use grouping on competitorName. You end up with a simpler array:

[
  { date: "", competitorName: "", "price: ""},
  ...
]

Dates will be repeated where more than one competitor exists at that date.

  var transData = [];
  for (var i=0; i<data.length; i++){        
    var date =  data[i].date;
    if (data[i].competitor.length > 0){
      for (var j=0; j<data[i].competitor.length; j++){
        var obj = {}
        obj.date = date;
        obj.competitorName = data[i].competitor[j].competitorName;
        obj.price =  data[i].competitor[j].price;
        transData.push(obj);            
      }          
    } else {
      var obj = {}
      obj.date = date;
      obj.competitorName = "";
      obj.price = "";
      transData.push(obj);
    }        
  }

With the date transformed, you use the grouping functionality of the kendo datasource:

$("#chart").kendoChart({
 theme: "material",
 dataSource: {
      data: transData,
      group:{field: 'competitorName'}, 
      sort: {field: "date", dir: "asc"},
      schema: {
          model: {
              fields: {
                  date: {
                      type: "date"
                  }
              }
          }
      }
  },
  legend: { visible: true, position: "bottom" },
  seriesDefaults: {type: 'column',},
  series: [{
      field: 'price',
      categoryField: "date",
      name: "#= group.value #"
  }],
  tooltip: {
    visible: true,
    template: "#= series.name #<br />#= kendo.toString(category, 'yyyy-MM-dd') # = #= value #"
  },
});

Here is a dojo demo:

DEMO

Comments