Hidash documentation

Hidash is a library for web application built on Django to create graphs and charts within minutes. Currently, the supported JS libraries to build charts are Google Charts and Highcharts. The Project can be explained as follows:

  1. Provide the chart details in an xml file.
  2. Provide the path to your xml in your settings.py.
  3. Make API calls to get the chart data as desired for Google Charts, generated directly from your database (works even if you have multiple databses).
  4. Or, you can just inject our angular dependency hidash in your angular module to get the chart directly using angular directives <hi-dash-gc> for Google charts, <hi-dash-hc> for highcharts and <hi-dash-reports> to get all the charts using a single directive without making any API calls manually.
  5. Use our APIs to generate reports of the charts in excel or pdf format.
  6. UI Ready Dashboard - Group reports in the xml file and see all the charts in a single page by just hitting a single url and writting zero lines of code.

Installation And Initial Setup

  1. Inside your Django project activate virtual environment
  2. Run the following command:
pip install hidash
  1. Inside your app go to urls.py and add the following to urlpatterns
from django.conf.urls import include
from hidash import router

urlpatterns = [url(r'^api/', include(router.urls))]
  1. create your charts.xml file.(see XML instructions below)
  2. Inside your app go to settings.py and add the following code to specify your charts:
HIDASH_SETTINGS = {
       'xml_file_path': "<absolute path to your xml file>"
       }

Note: You can also use the following function to extract the absolute path if the xml file is in the same package as settings.py

from os.path import join, abspath, split
charts_dir = split(abspath(__file__))[0]
charts_xml = join(charts_dir, "<filename>.xml")
 #now use charts_xml as the absolute path
  1. Add hidash in INSTALLED_APPS in settings.py
INSTALLED_APPS = [
      <rest_of_the_apps>,
      'hidash',
]

You are all set. Just make sure your database in set up in settings.py.


The XML

<charts>

This tag should be the very first tag in your xml which will contain all the chart tags

<chart>

This tag defines a single chart data and must contain the attribute “id” and “lib”. The id identifies every chart element uniquely and the attribute lib tells hidash to convert the data into a structure desired by the charting library specified in lib attribute.

<charts>
     <chart id="timesheet" lib="googlechart/highcharts">
     .....
     </chart>
</charts>

Other than the attribute, there are two optional attributes that a chart tag can contian.

Optional attributes:

database: This attributes must be used in case your aplication is having multiple databses. Just specify you database name as the value of this attribute like this:

<chart id="timesheet" lib="googlechart/highcharts" database="<enter your databse name here>">
     .....
</chart>

group: This attribute is used when you desire to see a set of charts by hitting a single url click here to get details on api calls for grouped charts.

<chart id="timesheet" lib="googlechart/highcharts" group="<enter group name here>">
        ....
</chart>

<dimension>

This tag must be provided by the label of x-axis. For example if your graph is Hours vs project, the dimension tag must be like this:

<dimension>Projects</dimension>

Now the x-axis label becomes Project

<metric>

This tag contains the unit on the basis of which we are comparing values on the x-axis. Continuing with the same example, the y-axis must show Hours. Hence, the metric tag must be like this:

<metric>Hours</Hours>

<type>

This tag defines the type of chart you wish to generate. The supported types for google chart are:

  1. LineChart
  2. BarChart
  3. AreaChart
  4. PieChart
  5. ScatterChart
  6. SteppedAreaChart
  7. ComboChart
  8. ColumnChart

The supported types for highcharts:

  1. line
  2. bar
  3. pie
  4. area
  5. scatter
  6. spline

<query>

This tag encapsulates the sql query to be executed.

This completes the description of all the tags (except for the handler tag) you need to put in your xml. Now let’s have a look at the complete xml that should be written in order to generate a column chart for the same result set.

For an sql query which gives a result set similar to this:

project_code hrs
Project1 2
Project2 5
Project3 6
Project4 12
Project5 5
<charts>
 <chart id="timesheet" lib="googlechart/highcharts">
     <dimension>Projects</dimension>
     <metric>Hours</metric>
     <type>ColumnChart</type>
     <query>
       <![CDATA[
             select project_code, sum(hrs) from demotable  group by project_code order by sum(hrs) desc limit 5
       ]]>
     </query>
 </chart>
</charts>

Adding parameters to queries

Django comes with a feature to use parameters in queries. These parameters act like variables which can take any values. When using hidash, you can use this feature by two was. First is to pass these variables in the url when making an API call, second way is to use the augment parameters feature.

Here is an example on using parameters in the sql query and passing them in the url:

  1. Add the query with parameters to the xml. A query with a parameter looks like this:

    select abc, xyz from some_table where some_attribute = %(param)s
    
  2. Pass the parameters in the url like this:

    api/chartid.json/?param=somevalue
    

Multiple series

Till now whatever we have done will work perfectly for a result set with single series but to handle multiple series, we will have to understand few more concept. But before that let’s have a quick look the type of result sets which can create multiple series data.

Series names as column names in the result set

For a query which gives the result set like this:

project_name series1 series2
Project1 5 1
Project2 6 5
Project3 8 8
Project4 6 7

The x-axis labels are: Project1, Project2, Project3, Project4 and Project5.

The y-axis labes are: The numerical values in the tuples.

The series are: series1, series2.

The xml for such kind of result set should be like this:

<charts>
  <chart id="politica" lib="googlechart/highcharts">
    <dimension>Projects</dimension>
    <metric>series1</metric>
    <metric>series2</metric>
    <type>ColumnChart</type>
          <query><![CDATA[
      select project_type, series1, series2 from demotable
        ]]></query>
  </chart>
</charts>

Series names in tuples

For a query which gives result set like this:

month project_code hrs
December project1 344.25
January project1 426.45
November project2 2
December project2 1.5
January project2 5
December project3 11
December project4 6
January project4 90.5
December project5 66
January project5 27.5

The Series: project1, project2, project3, project4, project5

The x-axis labels: January, December, November

The y-axis labels: sum of hours represented as integer

NOTE: In this case the series names are in the rows and not the column names itself

The xml for such kind of result set should be like this:

<charts>
  <chart id="timesheet3" lib="googlechart/highcharts">
       <dimention>Month</dimenstion>
    <separator>Project</separator>
    <metric>Hours</metric>
    <type>ColumnChart</type>
      <query><![CDATA[
              select monthname(STR_TO_DATE(extract(month from day),'%%m')) as month, project_code , sum(hrs) as hrs from demotable where extract(month from day) between %(start)s and %(end)s group by project_code , month  limit 10;
       ]]></query>
  </chart>
</charts>

Series names in tuples and x-axis values as column names

The xml for such kind of result set should be like this:

<charts>
  <chart id="timesheet3" lib="googlechart/highcharts">
    <dimention>extract</dimenstion>
    <type>ColumnChart</type>
    <query><![CDATA[
      select monthname(STR_TO_DATE(extract(month from day),'%%m')) as month, project_code , sum(hrs) as hrs from demotable where extract(month from day) between %(start)s and %(end)s group by project_code , month  limit 10;
     ]]></query>
  </chart>
</charts>

Reports

To generate tabular reports from the queries you can use the handler report in the xml. No need to specify any thing other than the query.

Example:

<chart id="politica4" lib="googlechart">
  <query id="q1"><![CDATA[
                select project_code, sum(hrs) from demotable
  ]]></query>
</chart>

API Calls

Get the Chart Data

/api/charts/<chart-id>.json/?<...optional-query-parameters...>

Description

Use this api call to get json data according to the format accepted by google charts library. This api would run the query and generate the chart data according to the specifications specified in your charts xml file. <chart-id> is used to specify the chart tag inside the xml file. <optional-query-parameters> can be passed if the query has some parameters within it.

Example

For sql query of type:

SELECT Column FROM TableName WHERE Column BETWEEN %(param1)s AND %(param2)s

Use

/api/charts/chart001.json/?param1=somevalue&param2=somevalue

Sample Usage Code

There are two possible ways to implement the charts in your ui:

  1. Making api calls from the frontend to get the chart data.
  2. Using the hidash.js library. (Recommended) API.

How to make API calls

Below is a sample code to make an API call and render the chart inside a <div>. We are using Angular JS to make API calls. You are free to use plain JavaScript or Ajax calls to generate charts. For more details on generating Google Charts using JavaScript refer this

<html>
     <head>
     </head>
     <body ng-app="...insert AppName here..." ng-controller="...insert controller Name here...">
     <div google-chart chart="chart" style="{{chart.cssStyle}}">
         <!-- This is where the chart will be rendered -->
     </div>
     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-google-chart/0.1.0/ng-google-chart.min.js" type="text/javascript"></script>
     <script>...Include your angular app here...</script>
     <script>...Include your controller...</script>
     </body>
 </html>

Controller.js

$scope.chart={}
$http.get("/api/charts/chart1.json/?param1=somevalue&param2=somevalue").success(function(data) {
     $scope.chart.data = data;
     $scope.chart.type = data.chart_type;
});

How to use hidash.js

You can include the hidash.js script and include the chart very easily using the directives. Steps to follow:

Include the charting libary script:

//For Google charts
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-google-chart/0.1.0/ng-google-chart.min.js" type="text/javascript"></script>

//For Highcharts
<script src="http://code.highcharts.com/highcharts.js"></script>

Include the hidash.js inside your html code.

npm install Hidash
//Or you can add this link in your template

<script src="https://googledrive.com/host/0B46o2bSeT47MdWRyVEE2THhhcG8/"></script>

Include the ['hidash'] dependency in your angular app.

for example inside your app :

angular.module('AppName', ['hidash']);

If you want an api base to be appended before every url, the in your configuration file, write the following code:

hidashApiBase: "apibase.com/api"

<hi-dash-gc>

Use this directive to get the chart using google charts charting library.

<hi-dash-gc chart="chart_id" params="optional_parameters_seperated_by_commas"></hi-dash-gc>

Optional attributes for hi-dash-gc

1. type: The value of this attribute specifies which type of chart you want to display.

2. options: These are the customiztion options for the google charts click here to read about google charts options object

3. typeselect: This atribute must be used if you want to change the chart type on the front end. Using this attribute you get a dropdown menu to select chart types from. The supported values are:

  • am : To get a dropdown menu if you are using Angular Material framework on the frontend.
  • bs : To get a dropdown menu if you are using Bootsrtap framework on the frontend.
  • default: To get a custom HTML dropdown menu.

4. update: To update the chart without refreshing the page use this attribute. This attribute expects an integer value. Suppose that update=x then the chart gets refreshed in every x miliseconds.

<hi-dash-gc
     chart="chart_id"
     type="bar"
     params="optional_parameters_seperated_by_commas"
     options="<options to customize the chart>"
     update="2000"
     typeselect="am">
</hi-dash-gc>

Customizing the typeselect dropdown menu

The typeselect dropdown menu comes with a class name chart-select. Hence this class can be extended in the css file to customize the dropdown menu.

<hi-dash-hc>

Use this directive to get the chart using highcharts charting library.

<hi-dash-hc chart="chart_id" params="optional_parameters_seperated_by_commas"></hi-dash-hc>

Optional attributes for hi-dash-hc

1. type: The value of this attribute specifies which type of chart you want to display.

2. options: These are the customiztion options for the google charts click here to read about google charts options object

3. update: To update the chart without refreshing the page use this attribute. This attribute expects an integer value. Suppose that update=x then the chart gets refreshed in every x miliseconds.

<hi-dash-hc
     chart="chart_id"
     type="bar"
     params="optional_parameters_seperated_by_commas"
     options="<options to customize the chart>"
     update="2000">
</hi-dash-hc>

<hi-dash-reports>

Check ou group reports section to learn how to group reports through the xml. To see the reports of a group through the hidhash directive with two datepickers write the code like this:

<hi-dash-reports group="group name" params="optional_parameters_seperated_by_commas">

If the group attribute is not used then all the charts with no group are shown. |

Group Reports

This is a special API where you can get a view of multiple charts defined in your xml in one place.

Just add an attribute group in the <chart> tag with a group id that can be used to gather all charts having same group id.

Syntax:

<chart id="..chart_id here.." group="<..group id here..">

Example:

<chart id="chart01" group="group01">....</chart>
<chart id="chart02" group="group01">....</chart>
.
.

Api call:

/api/show_reports/?group=<groupid>

And you will see a page with all you reports and charts of the group beautifully designed on one single place.

To get groupped chart data as json (data structure as desired by google charts):

/api/group_reports.json/?group=<groupid>

You can use this to get group of charts in one single API call.

To see a UI ready dashboard page, hit this url:

/api/group_reports/?group=<groupid>

If you are using the Hidash angular module the you can use the <hi-dash-reports> directive to see all the reports

Get Excel Reports

Excel

/api/charts/<chart-id>.xls/?<...optional-query-parameters...>

Description

Use the above API calls to export the result dataset of your sql query directly to xls format made available for download.

Sample Code

Below is the code to make an API call and download the report in xls format. For Pdf, just replace api url as mentioned above. We are using Angular JS to show the API call. You are free to use plain JavaScript or Ajax.

HTML Code

<html>
     <head>
     </head>
     <body ng-app="...insert AppName here..." ng-controller="...insert controller Name here...">
     <!-- Just click this button to download the xls report -->
     <button ng-click="download_xls()">Download Report</button>

     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-google-chart/0.1.0/ng-google-chart.min.js" type="text/javascript"></script>
     <script>...Include your angular app here...</script>
     <script>...Include your controller...</script>
     </body>
 </html>

Controller.js

$scope.download_xls= function(){
             $window.location.href="/api/charts/<chart-id>.xls/?<...optional-query-parameters...>";
             };

NOTE: Don’t forget to add $window in your controller dependencies


Augmenting Parameters

Apart from the query parameters that are passed in the url, you can add additional parameters to be used in the sql query generated at runtime. Here is how you do it: - Define a function in some script in your app to update the parameters

some_script.py:

def add_params(request):
     '''
     Some logic to get parameters to be passed
     '''
     params = {"key": "value"}
     return params
  • Register your function in the HIDASH_SETTINGS variable

settings.py:

HIDASH_SETTINGS = {
     'parameter_processors': [ <appname>.some_script.add_params,],
     'xml_file_path': "<path-to-xml-file>"
 }

Once you have done this much, you can use the parameters you are adding to params in a function (as shown above) in your query inside the xml file.


Authentication

By default authentication is not handled on api calls but the user can define custom Authenticator function to allow only some specific class of users to have access to the API.

Steps to define a Custom Authentication function :

  • Define a function with the following format in some_script.py in your app.

Example authenticator syntax:

some_script.py :

'''
The function MUST take a single argument user only and return boolean
True/False only.
'''
def myauthenticator(user):

    #some checks on the user object for example
    if user.is_authenticated():
        if user.email == "devashish.sharma@gmail.com":
           return True
    return False
  • Add the function to the HIDASH_SETTINGS inside your settings.py
 HIDASH_SETTINGS = {
  'parameter_processors': [appname.somescript.add_params,],
  'xml_file_path': "path to charts.xml",
   #ADD THIS LINE
  'api_authenticator': <appname>.somes_script.myauthenticator
}

Authentication rules defined in the autheticator function would be applied to all the hidash api urls.

Authorization

Authorization is supported in two ways:

1. Authorization through permission check

To make sure that a chart is only visible to people with a certain set of permissions, add a permissions tag in the xml file like this:

<charts>
        <chart id="chart01" group="group01">
                <permissions>auth.can_see_timesheet, auth.can_edit_timesheet</permissions>
                .
                .
                .
        </chart>
</charts>

2. Authorization through group check

To make sure that a chart is visible only to the people in a certain group only, use the <auth_groups> tag like this:

<charts>
        <chart id="chart01" group="group01">
                <auth_groups>group1, group2,...</auth_groups>
                .
                .
                .
        </chart>
</charts>