Gráficos HighCharts com DrillDown

Atendendo a pedidos vou colocar neste post a engine básica para usar o gráfico com Drill Down do HighCharts que você pode ver em funcionamento nesse link: http://www.highcharts.com/demo/column-drilldown

Não vou abordar aqui questões básicas sobre datasources, componentes ou layout. Parto da premissa de que, quem quer implementar um gráfico deste tipo em seu dashboard já tem conhecimento prévio de Pentaho e CDE.

De qualquer forma, seguem os links para tutoriais sobre esses assuntos:

O que é Pentaho

Como instalar o Pentaho – passo 1, passo 2 e passo 3

Instalando Plugins via Marketplace

Painéis CDE com Highcharts – MUITO IMPORTANTE PARA ENTENDER ESTE POST AQUI!!!

Vamos ao que interessa

Para que o gráfico com drill down funcione, o Highcharts utiliza o seguinte código javascript:

 

$(function () {
 // Create the chart
 $('#container').highcharts({
 chart: {
 type: 'column'
 },
 title: {
 text: 'Browser market shares. January, 2015 to May, 2015'
 },
 subtitle: {
 text: 'Click the columns to view versions. Source: <a href="http://netmarketshare.com">netmarketshare.com</a>.'
 },
 xAxis: {
 type: 'category'
 },
 yAxis: {
 title: {
 text: 'Total percent market share'
 }

},
 legend: {
 enabled: false
 },
 plotOptions: {
 series: {
 borderWidth: 0,
 dataLabels: {
 enabled: true,
 format: '{point.y:.1f}%'
 }
 }
 },

tooltip: {
 headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
 pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}%</b> of total<br/>'
 },

series: [{
 name: 'Brands',
 colorByPoint: true,
 data: [{
 name: 'Microsoft Internet Explorer',
 y: 56.33,
 drilldown: 'Microsoft Internet Explorer'
 }, {
 name: 'Chrome',
 y: 24.03,
 drilldown: 'Chrome'
 }, {
 name: 'Firefox',
 y: 10.38,
 drilldown: 'Firefox'
 }, {
 name: 'Safari',
 y: 4.77,
 drilldown: 'Safari'
 }, {
 name: 'Opera',
 y: 0.91,
 drilldown: 'Opera'
 }, {
 name: 'Proprietary or Undetectable',
 y: 0.2,
 drilldown: null
 }]
 }],
 drilldown: {
 series: [{
 name: 'Microsoft Internet Explorer',
 id: 'Microsoft Internet Explorer',
 data: [
 [
 'v11.0',
 24.13
 ],
 [
 'v8.0',
 17.2
 ],
 [
 'v9.0',
 8.11
 ],
 [
 'v10.0',
 5.33
 ],
 [
 'v6.0',
 1.06
 ],
 [
 'v7.0',
 0.5
 ]
 ]
 }, {
 name: 'Chrome',
 id: 'Chrome',
 data: [
 [
 'v40.0',
 5
 ],
 [
 'v41.0',
 4.32
 ],
 [
 'v42.0',
 3.68
 ],
 [
 'v39.0',
 2.96
 ],
 [
 'v36.0',
 2.53
 ],
 [
 'v43.0',
 1.45
 ],
 [
 'v31.0',
 1.24
 ],
 [
 'v35.0',
 0.85
 ],
 [
 'v38.0',
 0.6
 ],
 [
 'v32.0',
 0.55
 ],
 [
 'v37.0',
 0.38
 ],
 [
 'v33.0',
 0.19
 ],
 [
 'v34.0',
 0.14
 ],
 [
 'v30.0',
 0.14
 ]
 ]
 }, {
 name: 'Firefox',
 id: 'Firefox',
 data: [
 [
 'v35',
 2.76
 ],
 [
 'v36',
 2.32
 ],
 [
 'v37',
 2.31
 ],
 [
 'v34',
 1.27
 ],
 [
 'v38',
 1.02
 ],
 [
 'v31',
 0.33
 ],
 [
 'v33',
 0.22
 ],
 [
 'v32',
 0.15
 ]
 ]
 }, {
 name: 'Safari',
 id: 'Safari',
 data: [
 [
 'v8.0',
 2.56
 ],
 [
 'v7.1',
 0.77
 ],
 [
 'v5.1',
 0.42
 ],
 [
 'v5.0',
 0.3
 ],
 [
 'v6.1',
 0.29
 ],
 [
 'v7.0',
 0.26
 ],
 [
 'v6.2',
 0.17
 ]
 ]
 }, {
 name: 'Opera',
 id: 'Opera',
 data: [
 [
 'v12.x',
 0.34
 ],
 [
 'v28',
 0.24
 ],
 [
 'v27',
 0.17
 ],
 [
 'v29',
 0.16
 ]
 ]
 }]
 }
 });
});

Precisaremos substituir alguns blocos desse código para fazer nosso próprio gráfico funcionar e o que é melhor, com informações vindas do seu banco de dados. Mas isso fica para o final.

Para começar vamos chamar a biblioteca do HC no nosso dash. Para isso siga os seguintes passos:

  1. Na perspectiva layout adicione uma Row, dentro dela uma Column e dentro dela um HTML.
  2. Dê um nome para o HTML alterando sua propriedade “name”. Usei “htm”
  3. Edite sua propriedade “HTML” e insira o seguinte conteúdo:

Agora vá para a perspectiva Datasource e crie duas fontes. Para este exemplo utilizaremos “sql over sqljndi”.

chamaremos respectivamente de sql1 e sql2. Em ambas selecione a conexão JNDI que aponte para sua base de dados.

No meu caso eu criei um SQL que me retornava algumas linhas do meu banco de dados, mas para que possa funcionar de forma didática, vou reproduzir as mesmas linhas através deste SQL abaixo:

select ‘Manutencao’ as name, 500 as y, ‘Manutencao’ as drilldown union all
select ‘Pintura’ as name, 600 as y, ‘Pintura’ as drilldown union all
select ‘Lanternagem’ as name, 200 as y, ‘Lanternagem’ as drilldown union all
select ‘Borracharia’ as name, 300 as y, ‘Borracharia’ as drilldown union all
select ‘Eletrica’ as name, 550 as y, ‘Eletrica’ as drilldown union all
select ‘Estofamento’ as name, 100 as y, ‘Estofamento’ as drilldown

Esta é a instrução da do dado mais agregado, ou seja, o primeiro gráfico antes de fazermos drill para uma granularidade mais baixa. Portanto este é o comando para o “sql1”.

Para o dado mais detalhado, utilizarei a instrução a seguir e chamarei de “sql2”.

select ‘Manutencao’ as servico, ‘PAULO CESAR’ AS usuario, 100 as quantidade union all
select ‘Manutencao’ as servico, ‘ELIAS BRITO’ AS usuario, 400 as quantidade union all
select ‘Pintura’ as servico, ‘PAULO CESAR’ AS usuario, 300 as quantidade union all
select ‘Pintura’ as servico, ‘WALTER FERRAZ’ AS usuario, 300 as quantidade union all
select ‘Lanternagem’ as servico, ‘PAULO CESAR’ AS usuario, 200 as quantidade union all
select ‘Borracharia’ as servico, ‘PAULO CESAR’ AS usuario, 100 as quantidade union all
select ‘Borracharia’ as servico, ‘ELIAS BRITO’ AS usuario, 100 as quantidade union all
select ‘Borracharia’ as servico, ‘JOSE DAS COVES’ AS usuario, 100 as quantidade union all
select ‘Eletrica’ as servico, ‘PAULO CESAR’ AS usuario, 250 as quantidade union all
select ‘Eletrica’ as servico, ‘ELIAS BRITO’ AS usuario, 300 as quantidade union all
select ‘Estofamento’ as servico, ‘PAULO CESAR’ AS usuario, 100 as quantidade

Agora vá para a perspectiva Components e insira 2 componentes do tipo “Query Component”.

 

Altere as propriedades respectivamente conforma abaixo:

  • Name: q1
  • Result Var: v1
  • Datasource: sql1
  • HtmlObject: htm – AQUI DEVE SER O NOME QUE VOCÊ DEU AO HTML NA PERSPECTIVA LAYOUT
  • Name: q2
  • Result Var: v2
  • Datasource: sql2
  • HtmlObject: htm – AQUI DEVE SER O NOME QUE VOCÊ DEU AO HTML NA PERSPECTIVA LAYOUT

Ainda no componente “q2”, clique em “Advanced Properties”.

Altere a propriedade “Post Execution” para que fique da seguinte forma:

function(){

var vetDrill = [];
var vetData = [];
var vetagrupado = []
var valAnterior = ”;
//Pegando o vetor do banco e colocando na estrutura aceita pelo HC
// este vetor se refere a primeira query, onde os dados encontram-se mais agrupados
for(i=0;i<v1.length;i++){
vetagrupado = vetagrupado.concat({name: v1[i][0], y: v1[i][1], drilldown: v1[i][2]});
}

//Pegando o vetor do banco e colocando na estrutura aceita pelo HC
//Note que o objeto “data” é um subvetor e por isso vamos montá-lo em um segundo momento
//Este vetor se refere a segunda query, onde os dados são mais detalhados (drill)
for(i=0;i<v2.length;i++){
if(valAnterior != v2[i][0]){
vetDrill = vetDrill.concat({name: v2[i][0], id: v2[i][0], data: []});
valAnterior = v2[i][0];
}
}

//Montando o subvetor “data”
for(j=0;j<vetDrill.length;j++){
for(i=0;i<v2.length;i++){ //Para cada linha do vetor vetDrill, percorre o v2 (vetor do banco)
if(v2[i][0] === vetDrill[j].name){//compara se a linha atual do vetDrill corresponde ao serviço do v2 (vetor do banco)
vetData.push([v2[i][1],v2[i][2]]); //Acrescenta dados ao subvetor “data” obedecendo a estrutura [texto,valor]
if(i===v2.length-1){ //Verifica se é a última linha do vetor para não deixar o último registro de fora
vetDrill[j].data = vetData;
}
}else{//Caso a linha atual de vetDrill não seja correspondente a linha atual de v2, ou seja, acabou de ler um grupo de linhas de um serviço
if(vetData.length > 0){// e Vetor data não estiver vazio
vetDrill[j].data = vetData; //acrescenta dados
}
vetData = []; //Limpa vetor
}
}
}
var vetDrill1 = [[2011,’sss’]];

 

// a partir daqui o código é o mesmo do HC, apenas trocando os vetores fixos pelo resultado de suas queries!!
$(function () {
// Create the chart
$(‘#container’).highcharts({
chart: {
type: ‘column’
},
title: {
text: ‘Quantidade de Servicos por Especialidade e Profissional’
},
subtitle: {
text: ‘Clique nas colunas ver quantidade por profissional.’
},
xAxis: {
type: ‘category’
},
yAxis: {
title: {
text: ‘Total’
}

},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: ‘{point.y:.1f}’
}
}
},

tooltip: {
headerFormat: ‘<span style=”font-size:11px”>{series.name}</span><br>’,
pointFormat: ‘<span style=”color:{point.color}”>{point.name}</span>: <b>{point.y:.2f}</b> ‘
},

series: [{
name: ‘Especialidades’,
colorByPoint: true,
data: vetagrupado //substitui o vetor fixo do HC pelo seu
}],
drilldown: {
series: vetDrill //substitui o vetor fixo do HC pelo seu
}
});
});

}

 

Explicando o Código

Note que para montar as barras com os dados mais agrupados, o vetor que o HC usa tem a seguinte estrutura:

[{name,y,drilldown},{name,y,drilldown},…]

Como abaixo:

[{name: ‘Microsoft Internet Explorer’,y: 56.33,drilldown: ‘Microsoft Internet Explorer’},

{name: ‘Chrome’,y: 24.03,drilldown: ‘Chrome’},…]

 

Então precisamos montar um vetor com os dados que vem do banco seguindo a mesma estrutura. O código javascript para isso está destacado na cor laranja.

Já para fazermos o drill para o dado mais detalhado precisamos de um vetor mais complexo com a estrutura multidimensional como mostrada abaixo:

[{name,id,data: [[‘rotulo’,valor],[‘rotulo’,valor],…]},{name,id,data: [[‘rotulo’,valor],[‘rotulo’,valor],…]},…}]

Vetor original:

[{name: ‘Microsoft Internet Explorer’,id: ‘Microsoft Internet Explorer’,data: [[‘v11.0’,24.13],[‘v8.0’,17.2],[‘v9.0’,8.11],[‘v10.0’,5.33],[‘v6.0’,1.06],[‘v7.0’,0.5]]},

{name: ‘Chrome’,id: ‘Chrome’,data: [[‘v40.0’,5],[‘v41.0’,4.32],[‘v42.0’,3.68],[‘v39.0’,2.96],[‘v36.0’,2.53],[‘v43.0’,1.45],[‘v31.0’,1.24],[‘v35.0’,0.85],[‘v38.0’,0.6],[‘v32.0’,0.55],[‘v37.0’,0.38],[‘v33.0’,0.19],[‘v34.0’,0.14],[‘v30.0’,0.14]]},…]

Então precisamos montar um vetor com os dados que vem do banco seguindo a mesma estrutura. O código javascript para isso está destacado na cor verde.

Basta substituir os vetores que estão no javascritp do próprio exemplo do site do HC pelos nossos vetores conforme mostramos no código acima.

Para trocar os textos do gráfico, basta verificar como foi feito no texto destacado em lilás.

e… pronto!!!

 

passo4

 

passo5

Espero ter ajudado.

 

3 comentários em “Gráficos HighCharts com DrillDown”

    1. Eric, aqui você deve estar atento ao vetor que seu javascript gera. Tem que obedecer a estrutura do HC. Por favor coloque-o em um alert e me mande um print desse alert para eu dar uma olhada. Quem sabe consigamos identificar o problema juntos.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *