Skip to main content
Announcements
Qlik Connect 2024! Seize endless possibilities! LEARN MORE
Yianni_Ververis
Employee
Employee

There were times in my Qlik Demo Team projects that the objects coming from the Capabilites Api were not enough and we wanted a custom chart in our website like the one we did for PGA Championship Data Visualizer

In this tutorial I will just add the D3 library (https://d3js.org/)‌ and create a simple bar chart having loaded Angularjs and the Capabilities API. At this point, I assume you have read the first article on setting the template up with Angularjs and the Capabilities API Creating a website with Angular and the Capabilities API

We will use the same template and the same qvf.

  • First, we will add d3 into bower.json
    "d3": "3.5.9"
  • from the command line, we need to run bower install
  • then, load it from js/lin/main.js L7
    'd3': scriptsUrl + 'js/vendor/d3/d3.min',
    and L83 add 'd3',
  • copy a controller and name it d3.js (controllers/d3.j)s
  • make you sure you name it as 'controller.d3 in L12'
  • add it to main.js
    'controller.d3': scriptsUrl + 'js/controllers/d3',
    and load it in L87 'controller.d3',
  • copy a view and name it as d3 (views/d3.html)
  • Add the html holder

<div class="row">

  <div class="col-md-12">

  <div id="chart"></div>

  </div>

</div>

  • in order to get the data from the qvf as a hypercube, we just add in d3.js the function, passing the dimension and measure as the default chart:

me.getData = function() {

  api.getHyperCube(['Case Owner Group'], ['Avg([Case Duration Time])'], function(data){

    me.createBarChart(data);

  });

}

  • Below is the code that will generate the Bar chart with the labels. I am borrowing the code from the barchart extension that I created and can be found on Branch Qlik Branch

me.createBarChart = function (data) {

  var vars = {

  id: 'chart',

  data: data,

  height: 300,

  width: 500,

  bar: {

  height: 35,

  padding: 3,

  border: 1,

  color: '#4477AA',

  colorHover: '#77b62a',

  borderColor: '#404040'

  },

  label: {

  visible: true,

  width: 200,

  padding: 15

  },

  footer: {

  visible: true,

  height: 20

  },

  canvasHeight: null,

  template: '',

  };

  var element = $('#'+vars.id);

  vars.data = vars.data.map(function(d) {

  return {

  "dimension":d[0].qText,

  "measure":d[1].qText,

  "measureNum":d[1].qNum,

  "qElemNumber":d[0].qElemNumber,

  }

  });

  var dMax = d3.max(vars.data, function(d) { return d.measureNum; });

  vars.canvasHeight = (vars.data.length * (vars.bar.height+(vars.bar.padding*2)+3));

  vars.template = '\

  <div class="barchart" id="barchart">\

  <div class="content"></div>\

  ';

  if (vars.footer.visible) {

  vars.template += '<div class="footer"></div>';

  };

  vars.template += '</div>';

  element.html($(vars.template).width(vars.width).height(vars.height));

  if (vars.footer.visible) {

  $('#' + vars.id + ' .content').height(vars.height-vars.footer.height);

  $('#' + vars.id + ' .footer').height(vars.footer.height);

  } else {

  $('#' + vars.id + ' .content').height(vars.height);

  }

  var x = d3.scale.linear()

  .domain([0,dMax])

  .range([0, (vars.label.visible)?vars.width-vars.label.width-(vars.label.padding*2):vars.width]);

  var y = d3.scale.linear()

  .domain([0,vars.data.length])

  .range([10,vars.canvasHeight]);

  var xAxis = d3.svg.axis()

  .scale(x)

  .orient('bottom');

  var yAxis = d3.svg.axis()

  .scale(y)

  .orient('left')

  .tickSize(1)

  .tickFormat(function(d,i){

  return vars.data.dimension;

  })

  .tickValues(d3.range(vars.data.length)); //1167

  var svg = d3.select('#barchart .content')

  .append('svg')

  .attr({'width':vars.width,'height':vars.canvasHeight});

  var svgFooter = d3.select('#barchart .footer')

  .append('svg')

  .attr({'width':vars.width,'height':vars.footer.height});

  // Y Axis labels

  var y_xis = svg.append('g')

  .attr("transform", "translate("+vars.label.width+",10)")

  .attr('id','yaxis')

  .call(yAxis)

  .selectAll("text")

  .style("text-anchor", "start")

  .attr("x", "-"+vars.label.width);

  // X Axis labels

  var x_xis = svgFooter.append('g')

  .attr("transform", "translate("+((vars.label.visible)?vars.label.width:0)+",0)")

  .attr('id','xaxis')

  .call(xAxis

  .tickSize(1)

      .ticks(vars.verticalGridLines)

     );

  // Draw bars

  svg.append('g')

  .attr("transform", "translate("+((vars.label.visible)?vars.label.width:0)+",-20)") //-20

  .attr('id','bars')

  .selectAll('#barchart rect')

  .data(vars.data)

  .enter()

  .append('rect')

  .attr('height', function(d,i){ return vars.bar.height; })

  .attr({'x':0,'y':function(d,i){ return y(i)+19; }})

  .attr('style', '\

  fill: ' + vars.bar.color + '; \

  stroke-width:' + vars.bar.border + '; \

  stroke: ' + vars.bar.borderColor + ';\

  cursor: pointer;\

  ')

  .attr('width',function(d){

  return x(d.measureNum);

  })

  .on('mouseover', function(d, i){

  d3.select(this).style("fill", vars.bar.colorHover);

  })

  .on('mouseout', function(d, i){

  d3.select(this).style("fill", vars.bar.color);

  })

  .on('click', function(d, i) {

  console.log(d);

  app.obj.app.field('Case Owner Group').select([d.qElemNumber], false, false)

  });

  // Draw text

  svg.append('g')

  .attr("transform", "translate("+((vars.label.visible)?vars.label.width:0)+",-20)") //-20

  .attr('id','text')

  .selectAll('#barchart text')

  .data(vars.data)

  .enter()

  .append('text')

  .attr({'x':function(d) {

  return x(d.measure)+10;

  },'y':function(d,i){

  return y(i)+40;

  }})

  .text(function(d){ return parseInt(d.measureNum); })

  .attr("class", function(d) {

  return 'barTextOut';

  });

  }

The template with the new addition can be found at branch and on git

Branch: Qlik Branch

2 Comments