60 new data analytics life hacks for Operations, Agencies & beyond

Brand new BellaDati release includes tons of hidden gems for Operations & Agency warriors. Actually there is over 60 new life hacks for business data analysts and business users of various industry focus. Let’s start with stuff for operations professionals

Maps

 

1. Ubiquity of project management data

Project management data are omnipresent trough different industries. It makes no difference if we discuss with maritime shipping customer in Singapore, hospitality services in Turkey or Boston producer of project management tool. You may notice, that Gantt charts have been in BellaDati for a while. This edition makes operational and project management data treatment a breeze. It includes milestones (zero length tasks in your project) displayable as triangles

gantt

 

  • geo maps with detail control over state borders, jurisdictions (very handy for logistics industry)
  • drill-down color changes available directly from map legend
  • precise control over Scatter chart bubble size
  • each shared dashboard can be set as default for your CxO

With build-in connector to ProjectorPSA.com (major producer of project management cloud service from Boston) you may be at risk to finalize all reporting tasks before your afternoon coffee or tea. Whatever are your preferences.

 

2. Ever changing live info-graphics 

There is a whole business process, that should be adopted by market research or digital agencies. One of the key factors, how to make KPIs easy to comprehend is trough pixel perfect control and some embedded info graphics and media. It does not have to be limited only to agencies. For instance retail chain reports with build-in graphics can say more to executives.

Retail chain Marketing Dollars

  • rotation of images directly in report UI
  • you can upload any image into the report
  • any image can be insert as chart background to create interactive info-graphics
  • pixel perfect control over size of tables

These tools can be handy, when you create market research report for your customer, who simply insist on specific look and feel of report. Sounds familiar?

 

3. For those who love to code 

To satisfy your thirst for a bit of coding you may be interested, that BellaDati platform has been enhanced with features like 2 segments. First good hack is for data tranformation and import settings script. You know, that one based on Groovy. Henceforth you can call two new methods, that allows you upload data files directly from script code

  • getFileName()
  • getPath()

New methods

You may be familiar, that you can call most of the BellaDati features available for users also via REST API. You can now control as well mechanism to display default dashboard to user trough REST.

font

All that is wrapped in nice new cool application font, that works for Chinese, English, Korean, Spanish and for other regions, where BellaDati is used. You can find complete list of new features and enhancements at support.belladati.com in Release notes section. Enjoy!

 

Embedding BellaDati Tutorial – Part 6 – Setting Filters

After customizing our charts with date intervals in the last step, today we will look at how to apply filters to chart contents.

Goal: Display chart attribute values and let the user select which values to filter.

We will go through these steps:

  1. Pick an attribute and fetch all its values.
  2. Let the user select attribute values to filter.
  3. Remember and apply the predefined filters for each view so we won’t overwrite them.

 

First, we need to decide which filter attributes to offer to the user. We could determine this dynamically based on the report and its attributes using getAttributes(). To keep it simple, we will just pick and hardcode the attribute L_PRODUCT for this tutorial.

Attribute code in data set

Whenever a report is shown, we load the available attribute values:

 

List values = manager.getService().getAttributeValues(DATA_SET_ID, ATTRIBUTE_CODE).loadFirstTime()                        
 .toList();

 

 

Note how we are calling loadFirstTime() on the CachedList of attributes. This way, we load attribute values only in the first call while the CachedList keeps them for later. The loadFirstTime() method won’t reload the list contents from the server if it has been loaded already! We pass the attribute values to our frontend for display. In this tutorial we’ll assume that attribute values are valid HTML ID attribute values and insert them directly into the element IDs. More generally, we would use a mapping function to match up the checkboxes with their underlying attribute values.

 

<div class="filter-select">
<p class="filter-item">                                                        <input id="${value.value}" class="filter-value" name="${value.value}" type="checkbox" />                                                         <label for="${value.value}">${value.label}</label></p>

</div>

<div class="filter-select">
<p class="filter-item">                                                        
<input id="${value.value}" class="filter-value" name="${value.value}" type="checkbox" />         <label for="${value.value}">${value.label}</label></p>
</div>

 

We adjust our frontend script to send the selected attribute values to the server when fetching chart contents:

    $filterContainer.find(".filter-value").each(function() {
                        // get all selected filter values
                        if($(this).is(":checked")) {
                                filterValues.push(this.id);
                        }
                });

 

On the server side, we can now read those values and create a filter object with the given values. To create a filter, the SDK offers 4 different operators: IN, NOT_IN, NULL and NOT_NULL. Since we want to filter only the selected attributes, we use IN.
Each FilterOperation has a method createFilter() that creates a filter for a given attribute, in our case identified by a data set ID and an attribute code. For IN, this method returns a MultiValueFilter.
Finally, we can use the MultiValueFilter’s addValue() method to add our attribute values. Since we only know the attribute String values, we wrap the raw values in FilterValue objects.

Let’s put it all together:

  if (filterString != null) {
                        try {
                                ArrayNode interval = (ArrayNode) new ObjectMapper().readTree(filterString);
                                if (interval.size() > 0) {
                                        MultiValueFilter filter = FilterOperation.IN.createFilter(manager.getService(), DATA_SET_ID, ATTRIBUTE_CODE);
                                        for (JsonNode value : interval) {
                                                filter.addValue(new FilterValue(value.asText()));
                                        }

                                        // if all is successful,
                                        // use the filter when loading the chart
                                        loader.addFilters(filter);
                                }
                        } catch (IOException e) {}
                }

 

Not that complicated, was it?
With this, we’re already able to set user-defined filters on our charts. Let’s give it a try:

Charts without predefined filters

What happened? Suddenly, all our charts show the same content!
In our original report, each view uses a predefined filter to show data for a specific city. The user-defined filter we set in our SDK request replaces the predefined filter, so our views are no longer filtered by city.

To fix this, we need to apply the predefined filter in addition to the user-defined attribute selection when loading views.
First, let’s store all predefined filters in a map when loading a report:

    // store the views' predefined filters for later use
                for (View view : report.getViews()) {
                        predefinedFilters.put(view.getId(), view.getPredefinedFilters());
                }

 

Now, we can include the predefined filter whenever loading a view’s content:

                // and always include the predefined filter, if we have one
                if (predefinedFilters.containsKey(chartId)) {
                        loader.addFilters(predefinedFilters.get(chartId));
                }

                // load the chart
                return (JsonNode) loader.loadContent();

 

While we’re at it, let’s apply one more filter that removes those unsightly “(blank)” items we used to see in our report:

   // always exclude items with a blank product name
                loader.addFilters(FilterOperation.NOT_NULL.createFilter(manager.getService(), DATA_SET_ID, ATTRIBUTE_CODE));

 

Note that the order matters here: Both the non-empty filter and the user-defined value filter refer to the same attribute. By setting the non-empty filter first, we ensure that it won’t overwrite the user-selected attribute values.

And just like that, we can filter!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?
We’re looking forward to your call or email!

America: (+1) 866 668-0180
Asia Pacific: (+65) 6274-1260
Europe: (+420) 255-725-405
sales@belladati.com

Embedding BellaDati Tutorial – Part 5 – Date and Time Intervals

Over the course of the previous four tutorials, our demo application has made a lot of progress: From a single static chart through authentication to showing a whole report and even a list of all reports and dashboards available to a user.
However, we still haven’t actually interacted with our charts. That is what we will start doing today.

Goal: Display predefined date intervals and allow users to adjust them.

We will go through these two steps:

  1. Detect the current date interval and display it.

  2. Reload chart contents when the user changes the interval.

To skip right to the end, get the source code from GitHub or see the live result.

Since our reports contain several charts showing data from the same date range, it would be nice if the user could adjust all of them at the same time.
In this demo, we will allow the user to set the start and end of all monthly intervals using a global setting at the top of the report. Charts using a quarterly or other interval won’t be affected. We won’t offer the interval control if there are different monthly intervals on the page.

Of course, these decisions are fairly arbitrary. Using the same mechanism, we could just as easily provide individual controls for each chart or let the user choose which charts to update when setting a new interval.

First off, we need to find out the current intervals used in our charts by calling getPredefinedDateInterval() on the views in our report. We do this for all views and compare their intervals to ensure they’re all the same.

      

  /**
         * Looks for a common month-based interval in the report's views. Views
         * without an interval or with an interval that's not month-based are
         * ignored.
         * 
         * @param report the report to examine
         * @return the interval if all month-based views share the same interval,
         *         <tt>null</tt> if there are different intervals or no views have
         *         month-based intervals
         */
        private Interval<DateUnit> getCommonMonthInterval(Report report) {
                Interval<DateUnit> commonInterval = null;
                for (View view : report.getViews()) {
                        // check each view's interval
                        Interval<DateUnit> dateInterval = view.getPredefinedDateInterval();
                        if (dateInterval != null && dateInterval.getIntervalUnit() == DateUnit.MONTH) {
                                // if the view has an interval that's month-based
                                if (commonInterval == null) {
                                        // if we haven't seen a month-based interval yet, note it
                                        commonInterval = dateInterval;
                                } else if (!commonInterval.equals(dateInterval)) {
                                        // if we've seen a different month interval before, return
                                        return null;
                                }
                        }
                }
                return commonInterval;
        }

Now that we found the common date interval, we can pass it into the view for rendering:

        

/**
         * Loads report contents from BellaDati and injects them into the frontend
         * view for rendering.
         * 
         * @param reportId ID of the report to load
         */
        @RequestMapping("/report/{id}")
        public ModelAndView showReport(@PathVariable("id") String reportId) {
                if (!manager.isLoggedIn()) {
                        return new ModelAndView("redirect:/?redirectUrl=/report/" + reportId);
                }
                Report report = manager.getService().loadReport(reportId);

                ModelAndView modelAndView = new ModelAndView("report");
                modelAndView.addObject("report", report);
                modelAndView.addObject("commonInterval", getCommonMonthInterval(report));

                return modelAndView;
        }

In the view, we check whether an interval exists and display it:

            

    <c:if test="${commonInterval != null}">
                        <div class="date-select">
                                <div class="date-from">
                                        <span>Show data from</span>
                                        <select name="month">
                                                <option value="1">Jan</option>
                                                <option value="2">Feb</option>
                                                <option value="3">Mar</option>

        <option>2014</option>
                                                <option>2015</option>
                                        </select>
                                </div>
                                <button class="date-update">Update</button>
                                <button class="date-reset">Reset</button>
                        </div>
                        <script>
                                initInterval($(".date-select"), ${commonInterval}, '${pageContext.request.contextPath}');
                        </script>
                </c:if>

We use a few lines of JavaScript to set the initial values of the select boxes:

function initInterval($selectContainer, initialInterval, basePath) {
        // helper function to set month and year values
        var setValues = function($innerContainer, date) {
                $innerContainer.find("[name=month]").val(date.month);
                $innerContainer.find("[name=year]").val(date.year);
        };
        
        var resetValues = function() {
                // set from and to dates in the respective select boxes
                setValues($selectContainer.find(".date-from"), initialInterval.dateInterval.interval.from);
                setValues($selectContainer.find(".date-to"), initialInterval.dateInterval.interval.to);
        };
        
        resetValues();

Now what do we do once the user sets an interval and clicks Update? This:

        var updateContents = function() {
                // build an interval object containing the selected from and to date
                var interval = { from: {}, to: {} };
                interval.from.year = $selectContainer.find(".date-from [name=year]").val();
                interval.from.month = $selectContainer.find(".date-from [name=month]").val();
                interval.to.year = $selectContainer.find(".date-to [name=year]").val();
                interval.to.month = $selectContainer.find(".date-to [name=month]").val();
                
                $(".wrapper[data-use-date-interval=true]").each(function() {
                        // reload all views that use the interval
                        loadViewContent($(this), basePath, interval);
                });
        };
        
        $selectContainer.find(".date-update").click(updateContents);
        $selectContainer.find(".date-reset").click(function() {
                resetValues();
                updateContents();
        });

We create a JSON object containing the dates the user has selected and pass them into our loadViewContent() function from before, slightly modified to take the interval as a third parameter:

function loadViewContent(wrapper, basePath, interval) {
        var id = wrapper.data("view-id"); // ID of the chart
        var url = basePath + "/chart/" + id;
        var $container = wrapper.find(".chart");
        
        // clear any existing content from the chart container
        $container.empty();
        
        // get the chart contents from our server
        $.get(url, { interval: JSON.stringify(interval) }, function(response) {
                
                // create the chart and display it
                var chart = Charts.create("chart-" + id, response.content);
                chart.resize($container.width(), $container.height());
        });
}

Likewise, we need to make a few modifications to the server method fetching the chart:

        /**
         * Loads and returns the content of a chart from BellaDati.
         * 
         * @param chartId ID of the chart to load
         * @param intervalString an optional JSON string representing the interval
         *            to set, containing "from" and "to" elements with "year" and
         *            "month" each
         * @return the JSON content of the chart
         */
        @RequestMapping("/chart/{id}")
        @ResponseBody
        public JsonNode viewContent(@PathVariable("id") String chartId,
                @RequestParam(value = "interval", required = false) String intervalString) throws IOException {
                if (intervalString != null) {
                        try {
                                JsonNode interval = new ObjectMapper().readTree(intervalString);
                                Calendar from = new GregorianCalendar(interval.get("from").get("year").asInt(), interval.get("from").get("month")
                                        .asInt() - 1, 1);
                                Calendar to = new GregorianCalendar(interval.get("to").get("year").asInt(), interval.get("to").get("month")
                                        .asInt() - 1, 1);
                                AbsoluteInterval<DateUnit> dateInterval = new AbsoluteInterval<DateUnit>(DateUnit.MONTH, from, to);

                                // if all is successful, use the interval to load the chart
                                return (JsonNode) manager.getService().createViewLoader(chartId, ViewType.CHART).setDateInterval(dateInterval)
                                        .loadContent();
                        } catch (IOException e) {} catch (InvalidIntervalException e) {}
                }

                // otherwise, load the chart without a specified interval
                return (JsonNode) manager.getService().loadViewContent(chartId, ViewType.CHART);
        }

We check if the interval parameter is set and attempt to parse the JSON. If anything goes wrong here, we ignore the error and act as if no interval was set.

To load the chart content with a custom interval, we use a ViewLoader obtained fromcreateViewLoader(). The ViewLoader offers a number of methods to customize view loading, among them setDateInterval().
We create an AbsoluteInterval using the values received from the frontend, pass it into theViewLoader and call loadContent() to get and return the view content.

Try it out!

Setting Date Intervals

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?
We’re looking forward to your call or email!

America: (+1) 866 668-0180
Asia Pacific: (+65) 6274-1260
Europe: (+420) 255-725-405
sales@belladati.com

National University of Singapore Library chooses BellaDati against Tableau and QlikView

BellaDati is now proudly providing fast insights on 46 000 users from 7 libraries to National University of Singapore. We succeeded against Tableau and Qlikview (Qlik). The main winning factors were that BellaDati is fully web based solution that allows users to create and access reports anywhere and anytime, instant and fully automatic sharing of reports, fully fledged ETL functions that make combining various different data sources easier than ever, and our powerful BellaDati mobile apps that provide great mobility to empower management to monitor KPIs at the fingertip. Last but not least, our new customer also appreciated powerful API&SDK capabilities of our platform that allow him to develop its own specific BI apps.

 

BellaDati Deployment Type: BellaDati On-Premise
Data Sources: MySQL, MS Access, Facebook, Twitter, Excel
Winning Factors:

  • Fully web based solution with instant sharing of reports;
  • Fully GUI featured ETL functions to enable combining multiple different data sources;
  • Mature mobile BI solution;
  • Platform abilities of BellaDati that allows to develop customers’ own BI apps.

Embedding BellaDati Tutorial – Part 4 – Multiple Reports

So far, we have only been concerned with showing a single, hardcoded chart or report. Today, let’s see how we can give a list of reports and dashboards to the user and have them select which one they want to view!

Goal: Display a list of all reports and dashboards, allowing the user to view each of them.

We will make the following additions:

  1. Add an overview page that lists all available dashboards and reports.
  2. Fetch thumbnail images to display in the list.
  3. Show dashboard or report details when clicking on one of them.

 

To skip right to the end, get the source code from GitHub or see the live result.

 

Instead of displaying the content of a hardcoded report, we now need to fetch a list of all dashboards and reports available to the user. This is done using the methods getDashboardInfo()and getReportInfo(). For optimal performance, we want to fetch both of those lists in parallel using an ExecutorService.

        /**
         * Loads the list of reports and dashboards from BellaDati and injects them
         * into the frontend view to display.
         */
        public ModelAndView showReportDashboardList() throws InterruptedException, ExecutionException {
                ModelAndView modelAndView = new ModelAndView("list");

                // start a service for parallel execution of requests
                ExecutorService service = Executors.newCachedThreadPool();

                // provide thread-independent access
                final BellaDatiService bdService = manager.getService();

                // submit requests for reports and dashboards
                Future<List<ReportInfo>> reportFuture = service.submit(new Callable<List<ReportInfo>>() {
                        @Override
                        public List<ReportInfo> call() throws Exception {
                                return bdService.getReportInfo().load().toList();
                        }
                });
                Future<List<DashboardInfo>> dashboardFuture = service.submit(new Callable<List<DashboardInfo>>() {
                        @Override
                        public List<DashboardInfo> call() throws Exception {
                                return bdService.getDashboardInfo().load().toList();
                        }
                });

                // stop the service once the requests are done
                service.shutdown();

                // then inject the responses into the view
                modelAndView.addObject("reports", reportFuture.get());
                modelAndView.addObject("dashboards", dashboardFuture.get());

                return modelAndView;
        }

 

We create a new frontend page that takes the two lists and displays them to the user.

 

    <section>
                        <h1>Your Dashboards</h1>
                        <c:forEach var="dashboard" items="${dashboards}">
                                <c:if test="${dashboard.name != 'Hidden'}">
                                        <a class="wrapper dashboard"
                                                href="${pageContext.request.contextPath}/dashboard/${dashboard.id}">
                                                <span class="title">${dashboard.name}</span> <img
                                                src="${pageContext.request.contextPath}/dashboard/${dashboard.id}/thumbnail" />
                                        </a>
                                </c:if>
                        </c:forEach>
                        <h1>Your Reports</h1>
                        <c:forEach var="report" items="${reports}">
                                <a class="wrapper report"
                                        href="${pageContext.request.contextPath}/report/${report.id}">
                                        <span class="title">${report.name}</span> <img
                                        src="${pageContext.request.contextPath}/report/${report.id}/thumbnail" />
                                </a>
                        </c:forEach>
                 </section>

 

Note the image tags: the user’s browser will query our server for the dashboard and report thumbnail images. To fetch those thumbnails, we call loadDashboardThumbnail() orloadReportThumbnail() and return the byte content of the image BellaDati gives us.

 

 /**
         * Loads the thumbnail image for the dashboard with the given ID.
         * 
         * @param id ID of the dashboard
         * @return the dashboard's thumbnail, or an empty array if no thumbnail is
         *         found
         */
        @RequestMapping(value = "/dashboard/{id}/thumbnail", produces = "image/png")
        @ResponseBody
        public byte[] getDashboardThumbnail(@PathVariable String id) {
                return doGetThumbnail(true, id);
        }

        /**
         * Loads the thumbnail image for the report with the given ID.
         * 
         * @param id ID of the report
         * @return the report's thumbnail, or an empty array if no thumbnail is
         *         found
         */
        @RequestMapping(value = "/report/{id}/thumbnail", produces = "image/png")
        @ResponseBody
        public byte[] getReportThumbnail(@PathVariable String id) {
                return doGetThumbnail(false, id);
        }

        /**
         * Performs loading a thumbnail image for the given ID.
         * 
         * @param isDashboard <tt>true</tt> to load a dashboard image,
         *            <tt>false</tt> for a report
         * @param id ID of the dashboard or report
         * @return the thumbnail, or an empty array if no thumbnail is found
         */
        private byte[] doGetThumbnail(boolean isDashboard, String id) {
                try {
                        final BufferedImage thumbnail;
                        if (isDashboard) {
                                thumbnail = (BufferedImage) manager.getService().loadDashboardThumbnail(id);
                        } else {
                                thumbnail = (BufferedImage) manager.getService().loadReportThumbnail(id);
                        }
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        ImageIO.write(thumbnail, "png", baos);
                        baos.flush();
                        byte[] bytes = baos.toByteArray();
                        baos.close();
                        return bytes;
                } catch (IOException e) {
                        return new byte[0];
                }
        }

 

The last bit is simple as well: We set up URLs to display dashboards and reports with a given ID taken from the URL:

 

        /**
         * Loads report contents from BellaDati and injects them into the frontend
         * view for rendering.
         * 
         * @param reportId ID of the report to load
         */
        @RequestMapping("/report/{id}")
        public ModelAndView showReport(@PathVariable("id") String reportId) {
                if (!manager.isLoggedIn()) {
                        return new ModelAndView("redirect:/");
                }
                ModelAndView modelAndView = new ModelAndView("report");
                modelAndView.addObject("report", manager.getService().loadReport(reportId));

                return modelAndView;
        }

        /**
         * Loads dashboard contents from BellaDati and injects them into the
         * frontend view for rendering.
         * 
         * @param dashboardId ID of the dashboard to load
         */
        @RequestMapping("/dashboard/{id}")
        public ModelAndView showDashboard(@PathVariable("id") String dashboardId) {
                if (!manager.isLoggedIn()) {
                        return new ModelAndView("redirect:/");
                }
                ModelAndView modelAndView = new ModelAndView("dashboard");
                modelAndView.addObject("dashboard", manager.getService().loadDashboard(dashboardId));

                return modelAndView;
        }

 

And that’s all!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?
We’re looking forward to your call or email!

America: (+1) 866 668-0180
Asia Pacific: (+65) 6274-1260
Europe: (+420) 255-725-405
sales@belladati.com

Embedding BellaDati Tutorial – Part 3 – Whole Reports

Now that we can authenticate to our system, wouldn’t it be nice if we could show not just one chart but all the charts in a given report?

Goal: Load and display all charts from a report on one page.

To skip right to the end, get the source code from GitHub or see the live result.

To make our code easier to understand, we will change our workflow to dynamically load the charts via JavaScript rather than all at once initially. This means our users will get to see the report page immediately, even while we’re still fetching the chart contents in the background.
For a similar example that loads chart contents as part of the page, check our demo application.

We will need to make three changes to our implementation:

  1. Load the report with its list of charts instead of just one chart.
  2. Get individual chart contents from BellaDati and serve them to the frontend.
  3. Use JavaScript to fetch charts from our server and display them in the browser.

 

Loading the report content is easy:

 

/**
	 * Loads report contents from BellaDati and injects them into the frontend
	 * view for rendering.
	 */
	public ModelAndView showReport() {
		ModelAndView modelAndView = new ModelAndView("report");
		modelAndView.addObject("report", manager.getService().loadReport(REPORT_ID));

		return modelAndView;
	}

 

All we had to do was replace the loadViewContent() method call with a call to loadReport(). Our frontend page receives the whole Report object and uses it to set up the page:

<script>
function loadViews() {
	// iterate over all wrappers and load their chart contents
	$(".wrapper").each(function() {
		loadViewContent($(this));
	});
}
function loadViewContent(wrapper) {
	var id = wrapper.data("view-id"); // ID of the chart
	var url = "${pageContext.request.contextPath}/chart/" + id;
	
	// get the chart contents from our server
	$.get(url, function(response) { 
		var $container = wrapper.find(".chart");
	
		// clear any existing content from the chart container
		$container.empty();
		
		// create the chart and display it
		var chart = Charts.create("chart-" + id, response.content);
		chart.resize($container.width(), $container.height());
	});
};
</script>
</head>
<body onLoad="loadViews()">
	<header>
		<img src="${pageContext.request.contextPath}/images/logo.png" />
		<a class="logout button" href="${pageContext.request.contextPath}/logout">Logout</a>
	</header>
	<section>
		<%-- Since we injected the whole report, we can conveniently access its fields --%>
		<h1>${report.name}</h1>
		<div>
			<%-- iterate over all views that are charts --%>
			<c:forEach var="view" items="${report.views}">
				<c:if test="${view.type == 'CHART'}">
					<%-- build a wrapper element in which to display the chart --%>
					<div class="wrapper" data-view-id="${view.id}">
						<span class="title">${view.name}</span>
						<div class="content chart" id="chart-${view.id}"></div>
					</div>
				</c:if>
			</c:forEach>
		</div>
	</section>
</body>

 

We use JSTL to show the report’s name as a heading, then iterate over the views in the report and create a HTML structure for each of them. Later, we will fill in the content using JavaScript – note the loadViews() function we’re calling in the body tag.

Next, we need a server-side endpoint that can fetch and serve charts from BellaDati:

package com.belladati.tutorial;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.belladati.sdk.BellaDatiService;
import com.belladati.sdk.auth.OAuthRequest;
import com.belladati.sdk.exception.auth.AuthorizationException;
import com.belladati.sdk.view.ViewType;
import com.fasterxml.jackson.databind.JsonNode;

/**
 * Handles incoming page requests from the end user's browser. Connects to
 * BellaDati to fetch data and passes it on to the frontend for rendering.
 * 
 * @author Chris Hennigfeld
 */
@Controller
public class TutorialController {

	/** Hard-coded ID of the report we want to load. */
	private static final String REPORT_ID = "30751";

	/**
	 * Provides access to a {@link BellaDatiService} instance, automatically
	 * injected via Spring.
	 */
	@Autowired
	private ServiceManager manager;

	/**
	 * Handles the root URL. Redirects to the login page or the report page
	 * depending on whether the user is logged in.
	 */
	@RequestMapping("/")
	public ModelAndView initialUrl() {
		if (manager.isLoggedIn()) {
			return showReport();
		} else {
			return new ModelAndView("login");
		}
	}

	/**
	 * Loads report contents from BellaDati and injects them into the frontend
	 * view for rendering.
	 */
	public ModelAndView showReport() {
		ModelAndView modelAndView = new ModelAndView("report");
		modelAndView.addObject("report", manager.getService().loadReport(REPORT_ID));

		return modelAndView;
	}

	/**
	 * Loads and returns the content of a chart from BellaDati.
	 * 
	 * @param chartId ID of the chart to load
	 * @return the JSON content of the chart
	 */
	@RequestMapping("/chart/{id}")
	@ResponseBody
	public JsonNode viewContent(@PathVariable("id") String chartId) {
		return (JsonNode) manager.getService().loadViewContent(chartId, ViewType.CHART);
	}

	/**
	 * Redirects the user to BellaDati for OAuth authorization.
	 */
	@RequestMapping("/login")
	public ModelAndView redirectToAuth(HttpServletRequest request) {
		OAuthRequest oAuthRequest = manager.initiateOAuth(getDeploymentUrl(request) + "/authorize");
		return new ModelAndView("redirect:" + oAuthRequest.getAuthorizationUrl());
	}

	/**
	 * Landing page after OAuth authorization, reached by redirect from the
	 * BellaDati server. Completes OAuth.
	 */
	@RequestMapping("/authorize")
	public ModelAndView requestAccessToken(RedirectAttributes redirectAttributes) {
		try {
			manager.completeOAuth();
		} catch (AuthorizationException e) {
			/*
			 * show an error informing the user - use e.getReason() to show
			 * custom error messages depending on what happened
			 */
			redirectAttributes.addFlashAttribute("error", "Authentication failed: " + e.getMessage());
		}
		return new ModelAndView("redirect:/");
	}

	/**
	 * Logs out.
	 */
	@RequestMapping("/logout")
	public ModelAndView doLogout() {
		manager.logout();
		return new ModelAndView("redirect:/");
	}

	/**
	 * Finds the root URL of the current deployment based on the user's request.
	 * 
	 * @param request request from the user
	 * @return the deployment root, including scheme, server, port, and path
	 */
	private String getDeploymentUrl(HttpServletRequest request) {
		String requestUrl = request.getRequestURL().toString();
		String servletPath = request.getServletPath();
		return requestUrl.substring(0, requestUrl.length() - servletPath.length());
	}
}

 

Looks just like what we did when we loaded the chart in our first tutorial step, doesn’t it? And it is – the only difference is that this time we’re getting the ID dynamically from the URL.

Finally, we need a bit of JavaScript to load the chart content from the endpoint we just set up and render it in the browser.

<script type="text/javascript" src="${pageContext.request.contextPath}/js/raphael.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/charts.js"></script>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- We're using jQuery for convenience - BellaDati charts rendering doesn't require it -->

 

Nothing magic here: We’re iterating over all the HTML elements we created based on the report and fetch the chart content for each one from the server. Then, we simply render the chart content the way we did before.

And there we go!

Tutorial Result

Check out the source for more details!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?
We’re looking forward to your call or email!

America: (+1) 866 668-0180
Asia Pacific: (+65) 6274-1260
Europe: (+420) 255-725-405
sales@belladati.com

Embedding BellaDati Tutorial – Part 2 – Authentication

Last week, we have seen how to use the BellaDati SDK to embed a chart into a simple web application. One of the simplifications we made was to set the BellaDati connection and authentication credentials directly in the code. Today, we will look at how to configure the server connection and use BellaDati authentication for our application.
If you want to skip ahead, get the source code from GitHub or see the live result.

Goal: Use dynamic authentication to ensure only registered users can access our content.

BellaDati offers two authentication options: OAuth and xAuth. Using either, the client will hold an access token rather than the user’s credentials, ensuring that an attacker cannot obtain sensitive information from an insecure application.

So what’s the difference between the two?

In a nutshell, OAuth offers maximum security by making the user sign in directly at the BellaDati server using their browser. User credentials don’t even pass through the client application, making it impossible to intercept them along the way.
We recommend using OAuth for any web application for the security it provides.

xAuth is a modified OAuth where the client sends credentials on the user’s behalf instead of making them authenticate directly with BellaDati. While they’re not stored, credentials still need to pass through the client application, increasing the security risk.
xAuth should only be used when OAuth is impractical, e.g. in a mobile app where browser-based authentication isn’t feasible.

Last week, we have seen xAuth authentication with hardcoded credentials.

              // connect to BellaDati and authenticate with fixed credentials
                                service = BellaDati.connect().xAuth("techKey", "techSecret", "api-demo@belladati.com", "apiDemo1");

If we wanted, we could simply reuse this and ask the user to enter their login information into our client. However, in a web application, we can achieve much better security by using OAuth.

We’ll need to make three additions:

  1. Create a landing page welcoming users that are not logged in.

  2. Redirect users to BellaDati to authenticate, then back to our application.

  3. Store the user’s authentication token and reuse it until the user logs out.

First, let’s look at our landing page:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" />
<title>Please Log In</title>
</head>
<body>
        <form method="POST" action="${pageContext.request.contextPath}/login" class="login">
                <img src="${pageContext.request.contextPath}/images/logo.png" /> <input type="submit"
                        value="Please Log In" />
                <div class="login-hint">Try logging in as <strong>api-demo@belladati.com</strong> with password <strong>apiDemo1</strong>.</div>
                <div class="error-message">${error}</div>
        </form>
</body>
</html>

There isn’t much going on here – it’s a plain HTML page with a button to tell the server we want to log in. At the bottom is a field for the server to inject error messages if anything went wrong during login.

Next, we need to implement the OAuth workflow so we can allow our users to sign in.

package com.belladati.tutorial;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.belladati.sdk.BellaDati;
import com.belladati.sdk.BellaDatiConnection;
import com.belladati.sdk.BellaDatiService;
import com.belladati.sdk.auth.OAuthRequest;
import com.belladati.sdk.exception.auth.AuthorizationException;

/**
 * Provides access to the BellaDati service. This is a singleton component
 * retrieving the service object from the current session. Spring ensures that
 * the right session is injected thread-safely.
 * 
 * @author Chris Hennigfeld
 */
@Component
public class ServiceManager {

        /** Session attribute to store the BellaDati service. */
        private static final String SESSION_SERVICE_ATTRIBUTE = "BellaDatiService";

        /** Session attribute to store pending OAuth requests. */
        private static final String SESSION_OAUTH_ATTRIBUTE = "pendingOAuth";

        /** Current session to store the service object. */
        @Autowired
        private HttpSession session;

        /**
         * Connection used to contact BellaDati cloud. Since this component is a
         * singleton, there will be only one connection shared by all users.
         */
        private final BellaDatiConnection connection = BellaDati.connect();

        /**
         * Returns the service object used to access BellaDati.
         * 
         * @return the service object used to access BellaDati, or <tt>null</tt> if
         *         the user is not logged in
         */
        public BellaDatiService getService() {
                return (BellaDatiService) session.getAttribute(SESSION_SERVICE_ATTRIBUTE);
        }

        /**
         * Returns <tt>true</tt> if the user is logged in.
         * 
         * @return <tt>true</tt> if the user is logged in
         */
        public boolean isLoggedIn() {
                return getService() != null;
        }

        /**
         * Initiates OAuth authentication to the BellaDati cloud server. Call
         * {@link OAuthRequest#getAuthorizationUrl()} to point the user to the URL
         * to authorize the request, then complete authorization by calling
         * {@link #completeOAuth()}.
         * 
         * @param redirectUrl URL to redirect to after authorization
         * @return the pending OAuth request
         */
        public OAuthRequest initiateOAuth(String redirectUrl) {
                OAuthRequest request = connection.oAuth("techKey", "techSecret", redirectUrl);
                session.setAttribute(SESSION_OAUTH_ATTRIBUTE, request);
                return request;
        }

        /**
         * Completes authorization of a pending OAuth request and returns the
         * service object to access BellaDati. Does nothing if no OAuth request is
         * pending for the current session.
         * 
         * @return the service object to access BellaDati, or <tt>null</tt> if no
         *         OAuth request was pending
         * @throws AuthorizationException if an error occurred during authorization
         */
        public BellaDatiService completeOAuth() throws AuthorizationException {
                OAuthRequest request = (OAuthRequest) session.getAttribute(SESSION_OAUTH_ATTRIBUTE);
                if (request != null) {
                        BellaDatiService service = request.requestAccess();
                        storeService(service);
                        return service;
                }
                return null;
        }

        /**
         * Logs out.
         */
        public void logout() {
                // since there's no session on the BD server,
                // we just need to discard the service object
                storeService(null);
        }

        /**
         * Stores the given service object in the session. Call with <tt>null</tt>
         * to clear the service.
         * 
         * @param service service object to store, <tt>null</tt> to clear
         */
        private void storeService(BellaDatiService service) {
                session.setAttribute(SESSION_SERVICE_ATTRIBUTE, service);
        }
}

The initiateOAuth(String) method starts the OAuth process, resulting in an OAuthRequest object. At this point, we’re already telling the server to redirect back to our application once the user has successfully entered their credentials.
After the user has authorized the request, we call requestAccess() in the completeOAuth() method. We now have a BellaDatiService object that we can store in the user’s session* for later use through the getService() method.

*Note that both OAuthRequest and BellaDatiService are Serializable and can be stored in sessions or even written to a file.

Finally, we need to put it all together in our controller.

package com.belladati.tutorial;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.belladati.sdk.BellaDatiService;
import com.belladati.sdk.auth.OAuthRequest;
import com.belladati.sdk.exception.auth.AuthorizationException;
import com.belladati.sdk.view.ViewType;

/**
 * Handles incoming page requests from the end user's browser. Connects to
 * BellaDati to fetch data and passes it on to the frontend for rendering.
 * 
 * @author Chris Hennigfeld
 */
@Controller
public class TutorialController {

        /** Hard-coded ID of the chart we want to load. */
        private static final String CHART_ID = "30751-PqMvlM9gdC";

        /**
         * Provides access to a {@link BellaDatiService} instance, automatically
         * injected via Spring.
         */
        @Autowired
        private ServiceManager manager;

        /**
         * Handles the root URL. Redirects to the login page or the view page
         * depending on whether the user is logged in.
         */
        @RequestMapping("/")
        public ModelAndView initialUrl() {
                if (manager.isLoggedIn()) {
                        return showView();
                } else {
                        return new ModelAndView("login");
                }
        }

        /**
         * Loads chart contents from BellaDati and injects them into the frontend
         * view for rendering.
         */
        public ModelAndView showView() {
                ModelAndView modelAndView = new ModelAndView("view");
                modelAndView.addObject("chart", manager.getService().loadViewContent(CHART_ID, ViewType.CHART));

                return modelAndView;
        }

        /**
         * Redirects the user to BellaDati for OAuth authorization.
         */
        @RequestMapping("/login")
        public ModelAndView redirectToAuth(HttpServletRequest request) {
                OAuthRequest oAuthRequest = manager.initiateOAuth(getDeploymentUrl(request) + "/authorize");
                return new ModelAndView("redirect:" + oAuthRequest.getAuthorizationUrl());
        }

        /**
         * Landing page after OAuth authorization, reached by redirect from the
         * BellaDati server. Completes OAuth.
         */
        @RequestMapping("/authorize")
        public ModelAndView requestAccessToken(RedirectAttributes redirectAttributes) {
                try {
                        manager.completeOAuth();
                } catch (AuthorizationException e) {
                        /*
                         * show an error informing the user - use e.getReason() to show
                         * custom error messages depending on what happened
                         */
                        redirectAttributes.addFlashAttribute("error", "Authentication failed: " + e.getMessage());
                }
                return new ModelAndView("redirect:/");
        }

        /**
         * Logs out.
         */
        @RequestMapping("/logout")
        public ModelAndView doLogout() {
                manager.logout();
                return new ModelAndView("redirect:/");
        }

        /**
         * Finds the root URL of the current deployment based on the user's request.
         * 
         * @param request request from the user
         * @return the deployment root, including scheme, server, port, and path
         */
        private String getDeploymentUrl(HttpServletRequest request) {
                String requestUrl = request.getRequestURL().toString();
                String servletPath = request.getServletPath();
                return requestUrl.substring(0, requestUrl.length() - servletPath.length());
        }
}

When the user clicks the login button, the redirectToAuth() method initiates OAuth and redirects the user to BellaDati for authorization. The user enters their credentials and BellaDati sends them back to us, calling requestAccessToken(). We can now complete authentication, fetch the chart contents for the user and render the chart as we did last week.

Eventually, the user may want to end their session with our application and log out. Since there is no active session at the BellaDati server, we don’t need to do any remote communication here. All we need to do is discard the access token by removing the stored BellaDatiService object from the user’s session.

Try it out or get the full code with all the details!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180
Asia Pacific: (+65) 6274-1260
Europe: (+420) 255-725-405
sales@belladati.com

Embedding BellaDati Tutorial – Part 1 – Introduction

Today’s post is the first in a series of tutorials demonstrating how to use the BellaDati SDK in practice. In this series, we’ll begin each step with a simple goal that we’ll work towards and reach by the post’s end.

 

Our first goal is setting up the essentials: A web application that connects to BellaDati using a preconfigured login and displays a single chart. If you want to skip ahead, get the source code from GitHub or see the live result.

 

Let’s start by setting up the project in Eclipse:

Setting up the Project

For convenience, our project will use Spring MVC. We add the BellaDati SDK and Spring as dependencies to our Maven configuration (download):

Maven Dependencies

Finally, to configure Spring, we’ll need to set up our web.xml and Spring descriptor in our application’s WEB-INF folder.

 

Our application will essentially consist of 3 parts: A component handling the access to BellaDati, a controller reacting to page requests, and a frontend displaying the content.

Let’s begin with the BellaDati access:

 

package com.belladati.tutorial;

import org.springframework.stereotype.Component;

import com.belladati.sdk.BellaDati;
import com.belladati.sdk.BellaDatiService;

/**
 * Provides access to the BellaDati service. This is a singleton component
 * holding one lazily initialized service instance.
 * 
 * @author Chris Hennigfeld
 */
@Component
public class ServiceManager {

        /** Service object used to connect to BellaDati. */
        private BellaDatiService service;

        /**
         * Returns the service object used to access BellaDati. Lazily initializes
         * the service by connecting to BellaDati the first time this method is
         * called.
         * 
         * @return the service object used to access BellaDati
         */
        public BellaDatiService getService() {
                // first do a non-thread-safe check for better performance
                if (service != null) {
                        // if we already have a service, use it
                        return service;
                }
                // otherwise initialize, synchronized to be thread-safe
                synchronized (this) {
                        // check again since the first check wasn't thread-safe
                        if (service == null) {
                                // connect to BellaDati and authenticate with fixed credentials
                                service = BellaDati.connect().xAuth("techKey", "techSecret", "api-demo@belladati.com", "apiDemo1");
                        }
                        return service;
                }
        }
}

That was easy. All we did was create a Spring component that provides a singleton BellaDatiService, lazily initialized on the first call. We’re using xAuth authentication, at this point hardcoded into the application. Of course it would be easy to pull out the login data into a configuration file as we did in the SDK demo.

 

Next up is our controller. We have two choices:

  • Include the content of our chart in the page when it is served
  • Let the browser fetch the content using JavaScript at runtime

 

Direct inclusion is simpler and faster if the end user’s latency is high, since the user’s browser makes just one call to our server. Dynamic fetching through JavaScript on the other hand allows us to react to user input and easily update parts of the page later on.
Since today we just want to display a single chart, we’ll go with direct inclusion. We will revisit dynamic fetching in a later post when we start working with filters.

package com.belladati.tutorial;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.belladati.sdk.BellaDatiService;
import com.belladati.sdk.view.ViewType;

/**
 * Handles incoming page requests from the end user's browser. Connects to
 * BellaDati to fetch data and passes it on to the frontend for rendering.
 * 
 * @author Chris Hennigfeld
 */
@Controller
public class TutorialController {

        /** Hard-coded ID of the chart we want to load. */
        private static final String CHART_ID = "30751-PqMvlM9gdC";

        /**
         * Provides access to a {@link BellaDatiService} instance, automatically
         * injected via Spring.
         */
        @Autowired
        private ServiceManager manager;

        /**
         * Handles the root URL. Loads chart contents from BellaDati and injects
         * them into the frontend view for rendering.
         * 
         * @return the frontend view and view options to send to the end user
         */
        @RequestMapping("/")
        public ModelAndView initialUrl() {
                ModelAndView modelAndView = new ModelAndView("view");
                modelAndView.addObject("chart", manager.getService().loadViewContent(CHART_ID, ViewType.CHART));

                return modelAndView;
        }
}

 

Easy again: All our controller method needs to do is fetch the chart JSON from BellaDati and send it to the view. How do we know the chart ID, you ask? In this case, from BellaDati directly – we looked at the chart in the browser’s developer tools to find its ID.

Chart ID in Chrome Debugger

Finally, the frontend. Here, we need to include the BellaDati chart renderer, consisting of BellaDati’scharts.js and its dependency raphael.js. In a later post we will look at how to fine-tune the charts and add tooltips, but for now, let’s keep it simple.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Step 1 - BellaDati SDK Tutorial</title>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/raphael.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/charts.js"></script>
</head>
<body>
        <!-- chart contents will be displayed in the div below -->
        <div id="chart"></div>
        <script>
                // inject the chart JSON (server-side)
                var json = ${chart};
                
                // create the chart object using the charts library
                // first parameter "chart" is the ID of the element where charts are inserted
                // second parameter is the chart data itself
                var chart = Charts.create("chart", json.content);
                
                // set the chart size, triggering the chart render
                chart.resize(800, 600);
        </script>
</body>
</html>

 

As you can see, all we do is call Charts.create(), passing the ID of the container element and the JSON content. Then we define the desired size, which will automatically render the chart.

Tutorial Result

And with that, we’re done! We have successfully created a web application showing a BellaDati chart in just a handful lines of code!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email! 

America: (+1) 866 668-0180
Asia Pacific: (+65) 6274-1260
Europe: (+420) 255-725-405
sales@belladati.com

Embedding BellaDati – A Use Case Overview

Version 0.9.3 of the BellaDati SDK is now available! With this version, you can start working with data sets: read metadata, insert data, and trigger or schedule imports from your data sources.

Since the SDK introduction post we have made many new additions to the SDK. Over the next few weeks, on this blog we will showcase technical examples and tutorials, showing you just how easy it is to embed your analytics using the BellaDati SDK!

Before we jump into that, let’s do a quick recap of the use cases we looked at:

summary.png

Business Processes

These are scenarios where BellaDati is used to more efficiently run a business. Such analytics could run as a separate tool, but offer maximum efficiency when embedded into other systems.

Controllers in any business work with data from many different sources in vastly different formats. With BellaDati, it becomes easy to integrate all this data into coherent reports for senior managers and C-level executives in an easy-to-use embedded app.

In HR, an important use case is staff performance evaluation and tracking. By embedding performance charts right into the HR application, performance data becomes visible at a glance for each employee.

In the hospitality app ClickRest, hotel and restaurant managers can analyze their sales data in a pre-built app that offers key insights on products, outlets and staff over time. Like many embedded apps, ClickRest aims at maximal usability, requiring no technical or analytical knowledge from its users at all!

Specialized Applications

Perhaps the most common use of embedded analytics is for use in an interactive application. Such applications can make automated recommendations or predictions based on user input and analytical data.

Many businesses depend on materials delivered by their supply chains. With BellaDati, we can easily track current stock levels and supplier offers, view usage over time and predict future need. The embedded app can give buying recommendations and even place orders right away.

Success in a marketing campaign depends on finding the right media to reach the target audience. Embedding BellaDati, it’s easy to see the market reach of different channels by demographics and interactively predict the total campaign reach based on channel choice.

In Food & Beverage and other industries, many businesses see a strongly fluctuating number of customers each day. With embedded BellaDati analytics, accurately predicting customer business becomes possible, helping to assign staff more efficiently and avoid waste of supplies.

When interacting with a customer, understanding their needs and offering to cross-sell the right products can be an important factor in driving revenue. This interaction may take place directly in a shop, or indirectly through a support line or in an online environment.

Some applications may even be available to the end user, such as a downloadable app. As an example, energy providers or governments can provide simple, easy-to-use analytics to the general public, allowing users to review their personal energy consumption and explore saving possibilities.

Public Access

In some cases, embedded apps don’t even need to offer data to one particular user. Analytical insights can be made available to the general public, whether to increase transparency or highlight the value of a service offer.

Where staff is interacting with end users, too often customers need to wait for an available agent. With BellaDati, businesses can embed analytics in their website or app, showing customers when they can expect the fastest service.

For social web services, a key challenge is encouraging users to interact, making them use the service as much as possible. Analytical insights can help users to find interesting content, encounter other users and increase their overall use experience.

Over the next weeks, we will see how to turn those use cases, and countless more, into reality using the BellaDati SDK!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

sales@belladati.com

Increased Efficiency for Transport & Logistics

Today’s transportation and logistics industry is characterized by cut-throat competition and razor-thin margins. In this environment, unexpected delays or surcharges can quickly mean losing important customers that may never come back. In addition, hard-to-predict variables like maintenance, repairs and fuel cost can drastically affect profitability, quickly turning an already small profit margin into a net loss.

These conditions make it extremely important for transportation businesses to reduce their operating costs, improve efficiency and ensure maximum reliability for their customers.

With BellaDati, it is easy to set up reports showing key operational factors in order to reduce costs, improve efficiency, and achieve greater customer satisfaction.

Do you want to optimize transportation of non-time-critical freight to best utilize all resources?

BellaDati analytics can help you identify slow days, allowing you to accept or negotiate orders to use the free capacity available on such days and generate increased business!

Daily Routes over Time

Perhaps you want to evaluate your routes to identify problems such as frequent delays that you need to consider in your offers? You can create a chart showing the time you take for each tour and how this timing develops over time. If there’s a sudden change, you’ll know immediately and can react:

Delays per Route over Time

Or do you want to evaluate your haulers to make sure you let each of them run the routes they can do best? Easy: You can build charts for at-a-glance information and drill down to view the full data in tabular form.

Hauler Performance

You can even evaluate the maintenance cost of each of our vehicles compared to the distance run and freight carried. This allows you to quickly identify and phase out vehicles with a poor maintenance record to prevent maintenance costs from taking a large cut out of your revenue.

Maintenance by Vehicle

All of this you can set up using out-of-the-box functionality, without any coding required. In addition to the web interface, BellaDati provides mobile apps for fast and easy access from anywhere.

You can even embed your analytics directly into your company intranet portal or transport management solution, making the reports available right in the context where they’re needed!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

 

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

sales@belladati.com

Classroom Progress Tracking with BellaDati

In this week’s post, we take a look at how BellaDati analytics can be used in education to increase teaching efficiency and easily monitor learning progress.

Schools today are getting increasingly computerized. For private schools in particular, it isn’t uncommon for students to do class exercises or homework on a portable computer such as a tablet, using a system that automatically grades their results or submits them to the teacher for review.

Tablet-using Student

In practice, this is often where it ends. Towards the end of the term, the teacher might go through their data to set a final grade and write a report. Otherwise, much of the data’s potential remains unused.

With BellaDati, it’s easy to set up a report that shows a graphical overview of key indicators. Connect to more than a hundred data sources using scheduled automatic imports and ensure your reports stay up to date, regardless of where and how your data is stored!

You can track a student’s progress, view the overall level of a class, and even get recommendations on what to focus on in the lessons!

Sample Classroom Progress Report

Do we want to see at a glance which students are at risk of not meeting the class goals? Easy: We define our threshold and let BellaDati display each student’s individual skill levels!

Performance by Student

Maybe we want to see which areas are generally problematic for our class, in order to plan more focused lessons?

Classroom Average Scores

What about a more complex use case: We want our class to do group assignments and need to put students of similar skill level together. No longer do we need to manually group students – BellaDati can automatically cluster students into groups of similar skill level!

Automatic Learning Group Generation

In this example, we decided to distinguish three levels: high (green), medium (yellow) and low (red), the strength of the color showing distinctions within each group. As the teacher, we can simply look at each row and assign students into groups of the desired size, without worrying that their skill levels might not match each other!

Get in Touch

Do you have questions about using BellaDati in your school? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

sales@belladati.com

Improving Energy Efficiency with BellaDati

Do you feel you’re spending too much money on utility bills each month? You’re turning off heating, lights or air-con whenever you’re not using them, but still your costs are too high?

Today, many governments, utility providers and third parties have started to realize the need to save resources. Through more efficient consumption, you can reduce your costs and save the environment!

Whether you’re a utility provider looking for a competitive advantage, an advisory service, or a resource-conscious government agency: With BellaDati you can easily analyze and visualize your end users’ energy consumption and give advice how they can save!

Energy Analytics

In the screenshot above you can see several example metrics: Compare a user with neighbors living in similar environments, or visualize their consumption levels throughout the year and by time of day to find peaks. By joining your data with weather information you can even differentiate by climate, helping users to see how much their heaters or air-con contribute to their spending!

Of course, many of your customers probably don’t know much about Business Intelligence and might be overwhelmed by the possibilities. At the same time, perhaps you already have an online customer portal and would like to aggregate all your services there, without having to introduce a separate BI solution to your users.

The answer to both of these concerns is easy:

Embed BellaDati reports into your own portal!

By embedding, your can choose easy to understand reports that highlight key insights for your users and make them available in your context.

Energy Usage Portal

You can even help your users optimize their consumption by finding out how much energy each of their appliances use and how they can best save. Just ask them what devices they’re using and let BellaDati deal with the calculations and visualization!

Energy Consumption Calculator

Reduce resource consumption, increase efficiency and save the environment with BellaDati embedded analytics!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

sales@belladati.com

Travel Data Analytics with BellaDati

Today’s travel agencies and booking sites, whether online or offline, possess a wealth of data about their customers’ travel behavior. Much of this data is simply archived and forgotten, without recognizing its immense value to partners like hoteliers or tour operators.

With BellaDati, you can make this information available for the benefit of your partners! Give yourself an edge by offering a service none of your competitors provide and open up a new revenue stream at the same time!

Let’s look at the example of BellaStay, a medium-sized, regional hotel booking site. BellaStay processes 2,000 bookings per day, working with several hundred hotels in the region, either directly or through wholesalers.

BellaStay front page

For each booking, we know a number of data points:

  • Location
  • Type of hotel (business, resort, budget, …)
  • Number of guests
  • Type of room
  • Amenities available
  • Additional services booked (e.g. airport pickup)
  • Price
  • Date/time of booking
  • Date/duration of stay

 

We can use this data to set up reports providing insights into our customers’ booking behavior:

Travel Data Report

Finally, we want to make these insights available to our hotel partners! With our extensive booking information, our partners no longer need to rely on guesswork based on incomplete data and subjective impressions. Quickly and objectively, hotels can:

  • Compare services and pricing with competitors nearby
  • Find out which services matter most to customers, adjust pricing and availability accordingly
  • Stop wasting money or effort on services or amenities that are relevant only to a tiny fraction of customers
  • Optimize marketing to tap into new customer segments

 

With BellaDati, this is easy: We set up a white-labeled portal in the BellaStay design, where hotel managers can log in and work with our data!

This service is conveniently available in the cloud, with all data imported automatically – no added maintenance effort for our BellaStay staff! All we need to do is tell our partners, ask them to sign up, and watch the revenue pour in!

Travel Data Portal

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

sales@belladati.com

New Chart Visualizations and Design Options with BellaDati 2.7.9.1

Treemap Chart

BellaDati can now display data using Treemap visualization, reflexing members’ values by size of the rectangular area in the map. Furthermore, diversity indicator can be selected to distinguish items with color intensity.
Screen Shot 2014-05-12 at 11.12.11 AM.png

Horizontal Stacked Bar Chart

In addition to vertical stacked bar chart, you can now visualize values broke down with two attributes also on horizontal bars.

 

Screen Shot 2014-05-12 at 11.16.42 AM.png

oAuth Support in URL Connector

BellaDati now allows you to use simple, oAuth1 and oAuth2 authorization protocols when connecting to remote locations via URL Connector.

Screen Shot 2014-05-13 at 9.38.51 AM.png

Data Level Permission based on Lookup Dataset

Thanks to this feature, data visible to logged-in user can be filtered not only by his/her profile information, but by complex rules stored in lookup datasets. You can access Data level permission control via filter icon next to list of attributes. Lookup datasets settings are available in advancedsection.

Screen Shot 2014-05-12 at 12.56.02 PM.png

Other

  • Display total value in the center of Donught chart
  • ChangeGear connector
  • Bulk Deletion of all Data Sets
  • Option to export BellaApp without data

Do you want to try BellaDati 2.7.9.1 now?

Give us a call or an email for exclusive one to one demo.

US: (+1) 866 668-0180
Asia: (+65) 6274-1260
EU: +420 255-725-405

sales@belladati.com

Easy Hospitality Analytics with BellaDati

In a hospitality businesses of any size, from a small outlet to a large chain, there’s a lot you can gain from data analytics!

Do you want to know how your revenue fluctuates throughout the day or over the course of a year?

Would you like to have an at-a-glance comparison of your outlets, easily identifying their respective strengths and difficulties?

Perhaps you want to know more about the performance of your staff or the popularity of the items on your menu?

Using BellaDati, answers to all of these questions and more are available at your fingertips! Forget about large time investments, technical background, or complex mathematics: At BellaDati, we take care of all this and provide you an easy-to-use solution that gives you just the answers you’re looking for!

For our partner Protel, BellaDati has developed the ClickRest solution to fulfill your hospitality needs:

ClickRest

As a Protel customer in hospitality, you get access to a managed deployment of BellaDati where you can easily import sales data from your point-of-sales system.

The BellaDati system contains preconfigured reports that allow you to immediately start gaining insights from your data, without lengthy training or configuration!

Hospitality Report in BellaDati

But that’s not all! To make analytics as easily available as possible, we built an app that summarizes reports for different use cases and allows you to drill down and view more details.

As managers, we can view our recent revenue, both as an overview and in chart form, for different time intervals:

Recent Revenue

 

We can get an overview of our staff members’ performance and view details at a click:

Employee Performance

And for those of us running multiple outlets, we can compare outlet performance and view most popular items by store:

Outlet Performance

Are you interested in a similar solution for your business or your customers?

By embedding BellaDati, it is easy to gain access to your reports through an app! Even better, you can include your analytics in the existing apps you’re already using!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

sales@belladati.com

How to Become Data Driven Company Presented by BellaDati at Chicago BigDataWeek

We hear it from everywhere: “To make business decisions effectively, you have to become a data driven company”.

Do you want to learn how? You have the unique opportunity to join BellaDati presentation atBigDataWeek in Chicago and consider major changes that have dramatically impacted the way we communicate, share, discover and collaborate with data.

On May 6th, Martin Trgina, BellaDati CEO will take the stage to present 8 most disruptive trends in business analytics.

What is the scientifically proven approach that can fully utilize the power of analytics?

How to make all business users in the company really addicted to reports, dashboards and other great features of BI in everyday life?

healthy-1.png

How to help them turn data into profits faster?

Join us to see how have successful retail companies leverages industry analytics apps to increate their sales performance. How hospitality managers around the world manage their business from mobile devices via embedded analytics.
clickrest-blog-image-620.jpg

Are you ready to take the first step? Join the session at Chicago BigDataWeek on May 6th at 12:30 pm.

Cannot make it? Watch the live streaming here.

 

BigDataWeek is taking place between May 5th and 11th in Chicago and other 30 cities worldwide.

Are you keen to learn more? Give us a call or an email for exclusive one to one demo.
US: (+1) 866 668-0180
Asia: (+65) 6274-1260
EU: +420 255-725-405

sales@belladati.com

Contact

Aislinn Chen

Customer Success Manager

Office Phone: +1 312 619 9353

E-mail: aislinn.chenya@belladati.com

Martin Trgiňa

CEO

Office Phone: (+1) 866 668 0180

Email: martin.trgina@belladati.com

LinkedInwww.linkedin.com/company/belladati

Facebookhttp://www.facebook.com/belladati

Twitterhttps://twitter.com/BellaDati

Social Analytics and Revenue with BellaDati

In today’s post, we’ll take a look at how your social platform, online game, or even dating site can benefit from data analytics with BellaDati.

Your site has a wealth of information about your users from their profiles. You know their interests, who they interact with, when they use your service, often even their approximate location. You want to use this data to present them with interesting information that keeps them using our site. At the same time, you might want to make this information, anonymized, available to customers like advertisers.

How can BellaDati analytics help improve your user experience and increase revenue? Let’s look at an example!

KnittingMatch front page

KnittingMatch is a dating site for knitting enthusiasts. They can upload their personal profile and favorite knitting designs to find compatible users. Users can interact with each other directly via chat or through a messaging system when offline.

As a social service, our most valuable asset is our user base. We need to engage them, provide interesting information and make it easy for them to get in touch with one another. So where does BellaDati come in?

Look at the front page above. See the trending interests and times to meet at the bottom? Right there, before even signing up, we can give our potential users a taste of what they can get by joining KnittingMatch!

Similar are the designs on the left side: with BellaDati, our website can dynamically determine the most relevant pictures to show to the visitor based on time, location and other data!

When a user is logged in, we can show them even more information. Like any dating site, we can find compatible users based on their profile, but it doesn’t end there!

Here is what our user page looks like:

KnittingMatch user page

By embedding BellaDati analytics, it’s easy to find matches with other users, topics of interest, or event recommendations!

For advertisers, we can offer a similar page:

KnittingMatch for advertisers

Our customers immediately get to see the most important data at a glance. To find out more details, they can filter by gender or age range, focus on a specific state or region, drill down into trending topics and more!

You can even make your reports available to 3rd-party-developers, all without writing any code yourself!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

sales@belladati.com

Effective Sales Recommendations with BellaDati

Effective Sales Recommendations with BellaDati

Are you running a retail shop facing increasing competition from large online stores? Are you trying to increase your sales without losing the personal feel that’s so important to your customers? Perhaps you read our cross- and up-selling tips and are wondering how to apply them in your setting?

Today, we will take a look at how BellaDati can help you get there!

Let’s look at an example to illustrate. We’re running a medium-sized bookstore with 10 employees in a local mall, selling a thousand or so books per day. Our customers value our staff’s knowledge and personalized recommendations, but we’re having difficulties competing with the prices offered by large retail chains. And even though our staff is knowledgeable about lots of books, it isn’t easy to compete with an automatic recommendation engine like Amazon’s.

Amazon recommendations

What if we could supplement our staff’s knowledge using the sales data from our store? Our point-of-sales system already knows which books customers like to buy together, what the best sellers of the past week are, or even what type of book sells well at this time of the year!

Let BellaDati help you bridge the gap between your sales data and your sales floor!

In the first step, we set up BellaDati to automatically import our sales data. With a few clicks, we can set up reports telling us which other books might be interesting to a customer who liked “The Alchemist”.

Books bought with 'The Alchemist'

How can we make this information available to our staff talking to the customer?

That’s easy: we embed BellaDati into a mobile app!

We equip every member of our staff with a tablet. When the customer asks about a book, all they need to do is scan the book’s ISBN number and our app automatically shows recommendations and summaries based on our data!

Recommendations app

Our staff will recognize some of these book suggestions and can make a personal recommendation to the customer. And for those books they don’t know yet, the app can immediately show the back cover summary and other information!

We can even make the app available to our customers directly, allowing them to browse on their own if no staff member is nearby!

 

Beyond Books

Of course this solution is in no way limited to books. We can easily apply the same concept to music, electronics, even clothes in a designer store.

Increase your customer satisfaction and your sales by embedding BellaDati!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

sales@belladati.com

Easier Controlling with BellaDati

n any business, small or large, effective controlling is essential to ensure your operations are on the right track. The controller needs to merge data streams from all over the organization, whether it’s HR, finance, sales, or R&D, in order to draw their conclusions.

Even in 2014, in many businesses this data is gathered by hand, perhaps with the help of a spreadsheet to crunch the numbers. As more and more data becomes available, controllers need to spend increasingly more time tracking and managing that data before being able to analyze it for the benefit of the business.

Too much data...

Using BellaDati, we can automate the whole data-gathering process. Whenever there’s a change in one of the many data streams, BellaDati can fetch the latest data and automatically update your reports.

Don’t waste your time gathering and managing data – with BellaDati, you can fully focus on gaining insights and making improvements to your business operations!
Let BellaDati gather your data!

And that’s not all! Often, you want to share your reports with others – perhaps other managers, your employees, or even your shareholders. By embedding BellaDati, this becomes easier than ever before!

Do you have an intranet portal accessible to your organization’s management? Embed your reports and pass around the link; your analytics update automatically and require nothing more than a web browser to view!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

 

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

support@belladati.com

Efficient Part-Time Staff Deployment with BellaDati

Are you managing a restaurant, cafe or other outlet where business can vary greatly from one day to the next?

Likely, you have a number of part-time staff to help you adjust, but it can often be difficult to know in advance how many part-timers will be needed on a given day. Call in too many and staff costs increase, call too few and customer satisfaction suffers.

Wouldn’t it be great to have a simple, easy-to-use tool that can take into account variables like weather or traffic and automatically make reliable predictions based on your past experience?

BellaDati can make this forecast available to you!

Let’s say we’re running a small cafe near a popular park in our city. The main variables affecting business are day of week, time of day, and weather. On a slow day, just two staff members may be enough to serve our customers, while at busy times we need as many as ten.

After running for a few months, we have accumulated a record of past transactions in our point-of-sale system. We can import this data into BellaDati to analyze the number of customers we had on any given day in the past:

Overview of hourly transactions

Assuming nothing else has changed, this already allows us to make predictions based on day of week and time of day. But what about our third variable: the weather?

Weather data is available from a variety of online services. We connect BellaDati to one of them and load historical weather information for the time period of our data. We can now use this information to make more accurate predictions!

Transactions on sunny vs rainy days

By embedding BellaDati, we can take this another step further: We can develop an app that gives us an immediate forecast for any given day.

The app connects to a weather service, getting forecast data for the selected day. It then connects to BellaDati and shows us the predicted data, based on the weather forecast and our past transactions!

Staff need prediction app

As a manager, we no longer need to rely on guesswork to decide how many part-timers to call. All we need to do is open the app, get the prediction and call our staff!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

 

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405
support@belladati.com

Plan your Marketing Campaigns with BellaDati

BellaSports is a sportswear company that is about to release a new line of running shoes. Corporate marketing has created a global advertising campaign to increase awareness with potential customers. Now, we have been tasked to run the campaign in our country’s media.

BellaSports Advertising Poster

We need to evaluate the cost and effectiveness of various media to reach the different segments of our target audience. We want to find a combination of channels that will allow us to reach the highest possible level of awareness given the budget we have received from corporate marketing.

For previous campaigns, we created a spreadsheet containing the various available media channels with their respective cost and audience reached. With this sheet, we could try out various combinations, view their cost and results, and ultimately choose one of them.

Recently, the BellaSports IT department has developed the BellaSports Marketing Planner (BMP), a planning application using embedded BellaDati to increase efficiency for local marketing offices like ours.

With BMP, we can automatically import media demographics and pricing from the advertising agencies, only resorting to manual entry for those who don’t provide their data online yet. Then, once we select the demographics to target and enter a budget, BMP immediately gives us an overview of the most efficient options – without having to go through them all one my one manually!

As we select media to include in our campaign, BMP automatically updates, showing the expected reach and suggestions how to cover the remaining audience segments!

BellaSports Marketing Planner

With BellaDati Embedded, not only did we save a lot of time, we have more thoroughly analyzed our options and created a more efficient campaign run!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

 

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405


support@belladati.com

BellaDati Embedded Supply Chain Management

In this week’s embedding scenario, let’s take a look at supply chain management!

This is BellaBake:

 

BellaBake Shop

 

BellaBake is a bakery making pies, cupcakes and other delicious pastries by processing supplies like flour, milk and eggs from different vendors. To satisfy our customers’ needs, we need to deal with the various unpredictabilities of our supply environment – whether it’s fluctuating prices, stock shortages or changes in delivery schedule.

BellaBake Supply Chain

Using BellaDati, we can easily get and visualize data from our warehouse and external suppliers to track their offers and supply situation. We can aggregate data from different sources to compare prices or combine orders from multiple vendors.

Even better, since we let BellaDati load the data for us, we no longer depend on the vendor to alert us if anything goes wrong on their side. BellaDati will automatically alert us if we’re dangerously low on eggs!
Management Steps

All of this is possible just using BellaDati in your browser. By embedding key analytics, we can take our efficiency another step further!

At BellaBake, we used to make weekly phone calls to the suppliers asking about their current status and placing our orders. Of course there are lots of suppliers offering milk or flour, but we don’t have enough time to call each one of them and find the best offer every time.

To save time, we have built a software that helps us place and track orders with our various suppliers. We now use the supplier data we have available in BellaDati and embed it directly into our ordering system. This way, when we want to place our order, we can at a glance see the conditions offered by the different vendors. We can even let the system make suggestions based on various criteria!

Supply Management Application

What did we gain?

With BellaDati, we can automatically receive updates on our suppliers without having to check them manually. Thanks to our embedded application, we can see the best offers, check our needs and immediately place an order – all accessible on the same screen!

Our supply process has become a lot easier and more transparent. We can save time and money by easily comparing many vendors before taking the best offer!

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

 

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405
support@belladati.com

Streamlined Customer Service with Embedded BellaDati

When was the last time you called customer service and listened to elevator music for ages until a representative got on the line? Did you recently go to your bank or post office and spent your lunch break queuing until it was finally your turn? Or did your kids have to stand in line for two hours to try that cool new ride at the amusement park?

Long queue

Wouldn’t it be great to know in advance how long you were going to wait, perhaps to decide whether to come back later? Even better, wouldn’t it be cool if you knew exactly when to expect the shortest wait time?

With BellaDati Embedded, you can increase your customer’s satisfaction and save their valuable time by making this information available to them!

 

Using BellaDati, it’s easy to gain the insights you need from your data. Import your activity logs, drill down by season and day of week, account for variables like public holidays – within minutes, you can produce charts and indicators predicting your load for any future scenario!

Once you have your reports set up, you can use of the BellaDati SDK to embed them right into your application. This could be your website, your app, an on-site display screen, or even an announcement in your customer service hotline!

Queue time display

Banking app showing queue time

And who says it’s only your customers who benefit? By distributing customer requests more evenly through the day, you can reduce peak load and as well as idle time. This can allow you to deploy your staff more efficiently and cut costs while improving customer experience!

Optimized load distribution

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

 

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405

 

support@belladati.com

HR Performance Evaluation with Embedded BellaDati

In last week’s post, we got a general overview of the BellaDati SDK. Today, we will look at a specific use case to demonstrate the immediate benefits you could gain from embedding BellaDati!

Scenario

Imagine we’re working in the HR department of our business. Among other things, we want to answer the following questions about our staff:

 

  • Which employees could benefit from training?
  • How do we distribute bonus payments?
  • Who should we recommend for raises or promotion?

 

Depending on our organization, we can use different data to evaluate performance. We might know the number of leads generated, the sum of sales made, billable hours worked, or even something as simple as an evaluation by each employee’s supervisor.

Evaluate in BellaDati …

To answer our initial questions, we need to find a way to gain insights from our data. Perhaps we already have a spreadsheet to enter data manually, but we can get there much faster – using BellaDati!

In our example, we’re looking at the sales performance of call center agents. We have imported data tracking each individual call and use it to create a report showing various indicators per staff member.

BellaDati HR Performance Analysis

Once we set up an automatic import from our call tracking system, we never again need to enter data manually! All our reports are right there, updated automatically, in real-time!

 

… and Embed into our HR System!

But we can do even better! At the moment, we still need to log in to BellaDati in order to see the reports. Wouldn’t it be great if we could access this information directly from our HR software?

Let’s check out BellaHR!
BellaHR Embedded HR Analytics

We select a staff member at the top and, next to their HR data, we can immediately view their performance!

What did we gain?

Just by using BellaDati, we already improved our situation. Our reports load their data automatically, saving us a lot of time trying to keep them up to date.

Our embedded solution offers even more advantages:

 

  • We can view data in context. Looking at a staff member, we immediately see their performance, on the same screen!
  • We don’t need to learn how to work with BellaDati. We only work with the HR software we already know!

 

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180
Asia Pacific: (+65) 6274-1260
Europe: (+420) 255-725-405
support@belladati.com

Introducing the BellaDati SDK

For many Business Intelligence users, embedding analytics into their own software is a key feature they expect from their BI solution. This can often be a fiddly process, taking plenty of effort and valuable time to develop.
Thanks to the BellaDati Software Development Kit (SDK), embedding your analytics has become easier than ever before!

Embedded BellaDati

This article is the first in a series that will look at embedding BellaDati on different platforms and for different industries. Today’s post is a general introduction, focused on the exciting possibilities available to you through the SDK!

So what is this SDK?

Can’t we already embed BellaDati using the REST API? Yes, that’s true – and in fact, the API will continue to be enhanced with every future BellaDati release!

The SDK is a library built on top of the existing API, aimed at making embedded analytics much easier and faster to develop. With many generic APIs, developers need to invest time into understanding the interface structure and write code to deal with low-level processes. These tasks can be time-consuming, yet add little or no business value to your application.

The BellaDati SDK increases your productivity by doing those tasks for you. Developers can focus on the core challenges of your application, knowing that the low-level drudgery is taken care of by our libraries. Your development speed increases, resulting in a faster time to market and higher user satisfaction.

Capabilities

Access your analytics using the tools you already know!

undefined

By embedding BellaDati, there’s no need to spend valuable time getting to know a new software. You can work with interactive charts, tables, even entire reports and dashboards without having to leave your own application!

 

Environment

The BellaDati SDK is currently available for Java and Android. You can use it with any language built on the Java Virtual Machine (JVM), such as Scala or Groovy.

sdk-languages.png

Try our Example

We have built an example application that accesses a BellaDati domain with two reports to help you get started. Just head over and give it a try!

If you want to access your own domain or make changes to the example, get the source code on GitHub. It’s easy to build and set up on your own server!

To build your own application, you can check the SDK documentation or use our demo as an example. If you’re curious, the SDK source is also available on GitHub.

Get in Touch

Do you have questions about embedding BellaDati? Do you want to know more about how you can benefit from embedded BellaDati analytics?

We’re looking forward to your call or email!

America: (+1) 866 668-0180

Asia Pacific: (+65) 6274-1260

Europe: (+420) 255-725-405
support@belladati.com