Home

Awesome

Visavail.js - A Time Data Availability Chart <!-- omit in toc -->

This library visualizes the availability of time-dependent data with a chart on a website.

<br>

Table of Contents <!-- omit in toc -->

<br>

1. Description

The Visavail.js chart allows a quick insight into which periods of time a time-dependent dataset covers. It is visually similar to a Gantt chart and allows easy identification of missing pieces and gaps in large datasets. Missing periods of data are marked in red while blocks of complete periods of data are marked in green. The user discovers dates that define start and end of such periods by tooltips, as shown in the picture below.

Preview of Visavail.js chart

An example use case is the visualization of a dataset that contains time-dependent stock market data. The question the Visavail.js chart tries to answer is

"Do I have continuous stock market data in my dataset and if not, where are the gaps?"

The Visavail.js library takes single data points with dates and information about data availability as inputs, combines them into time blocks, and visualizes these blocks.

<br>

2. Demo

Some example of Visavail.js in action is displayed at Demo. The source code of the a basic demo is shown in the file basic.html.

<br>

3. Usage

Input data format, display style and dependencies have to be considered for using the Visavail.js library successfully. The respective code snippets are explained below.

<br>

3.1. Input Data Format

The input to the Visavail.js library is a JSON-like structure. There are four formats that Visavail.js accepts. Which format is right for you depends on your use case.

<br>

3.1.1. Continuous Data

You should use the continuous data format if you want to display continuous recordings. Visavail.js assumes that information about the availability of some data is valid until the next data point shows up. Thus, the library will plot a continuous bar from the first to the last data point. The last data point will be assumed valid for a period of "interval_s". The below code comments point out the elements that should be included in the input data.

var dataset = [{
    "measure": "Annual Report", // name of the data series, will become y-axis label
    "measure_description": "Descripion of Annual Report" // description of y-axis label, visible with mouse over
    "interval_s": 365 * 24 * 60 * 60, // time period in seconds a single data point is expected to cover
    "data": [
        ["2015-01-01", 0], // data as arrays of period start data string and bit determining
                           // if data are available for that period
        ["2016-01-01", 1],
        ["2017-01-01", 1],
        ["2018-01-01", 1]
    ]
}];

If you want to add some descpription regarding measure, you can add a "measure_description" key to single dataset. Without enable y_title_tooltip enablement you can see the description as a svg title (no html enablement), if you enable the tooltip funziton for y title you can use also html tag for tooltip.

<br>

3.1.2. Data With Time Gaps

You should use the time gap data format if you want to display recordings that are not continuous. The availability data are valid for a specific period of time. This period is defined by a start and an end date, as shown in the code below. In this case, no information about "interval_s" (as explained in the previous use case) is needed.

var dataset = [{
    "measure": "Annual Report", // name of the data series, will become y-axis label
    "data": [
        ["2015-01-01", 0, "2015-03-04"], // data as arrays of period start data string,
                                         // bit determining if data are available for that
                                         // period and period end data string
        ["2016-01-01", 1, "2016-03-03"],
        ["2017-01-01", 1, "2017-03-06"],
        ["2018-01-01", 1, "2018-04-01"]
    ]
}];
<br>

3.1.3. Data With Dates and Times

The library also supports the display of data in smaller units than days as in the previous examples. Visavail.js currently supports display of data in second intervals. The code below is based on the time gap data format outlined above. To display date and time data correctly, all data must be formatted in a 24-hour format.

var dataset = [{
    "measure": "Room Occupancy", // name of the data series, will become y-axis label
    "data": [
        ["2016-01-01 12:00:00", 1, "2016-01-01 13:00:00"], // 24-hour format
        ["2016-01-01 14:22:51", 1, "2016-01-01 16:14:12"],
        ["2016-01-01 19:20:05", 0, "2016-01-01 20:30:00"],
        ["2016-01-01 20:30:00", 1, "2016-01-01 22:00:00"]
    ]
}];
<br>

3.1.4. Data With Custom Categories

If you want to show data in other categories than "data available" and "no data available", the following example is for you. Visavail.js also supports displaying data in custom categories. In this case, you have to assign all of your categories a name and a class that is used for displaying the category in the chart.

The chart legend will not appear on charts with data in custom categories. In adding you have a tooltip_html key that you can use to display some html code when you hover over the bars in the chart. If tooltip_html is empty we display the name of value used on categories.

See the code below for an example.

var dataset = [{
    "measure": "Fat Bike",
    "categories": { // category names and their colors defined here
        "0": {class: "rect_has_no_data", tooltip_html: '<i class="fas fa-fw fa-exclamation-circle tooltip_has_no_data"></i>' },
        "1": {class: "rect_has_data", tooltip_html: '<i class="fas fa-fw fa-check tooltip_has_data"></i>'},
        "Zoe": {class: "rect_purple" , tooltip_html: '<i class="fas fa-fw fa-trophy tooltip_purple"></i>'},
    },
    "category_percentage": "Zoe", // if percentage enable, calculates the percentage of this category
    "data": [
        ["2016-01-01 12:00:00", "Kim", "2016-01-01 13:00:00"],
        ["2016-01-01 14:22:51", "Zoe", "2016-01-01 16:14:12"],
        ["2016-01-01 16:14:12", "Bert", "2016-01-01 17:14:12"],
        ["2016-01-01 19:20:05", "Zoe", "2016-01-01 20:30:00"]
    ]
}];
<br>

3.1.5. Display Style

The display style of the chart is defined by a CSS style. The names of the different CSS classes in the CSS style file are self-explanatory.

<br>

3.1.6. Type of Chart

The library support three type of chart for different type of visualization "bar" (default), "rhombus", "circle". If you want to change type of graph you can follow this code

var options = {
	graph:{
		type: "circle",
		height:30,
		width:30
	}
};
<br>

3.2. Data Options

The options of the data are in JSON format and you can customize everything.

NameTypeDefaultDescription
measurestringName of measure that will be displayed on left side
measure_urlstringUrl that you can set as a link of measure
measure_descriptionstringDescription of mesurament diplayed when y_title_tooltip is enabled
interval_snumberUsed on dataset without defined block to define dimension of last block
data[ [] ... []]Array of Array Object that contain data to be displayed
iconObject{}more infoJson Object that contain icon setting that will be pre-append to y title
percentageObject{}more infoJson Object used in cans og char option: y_percentage.enable and y_percentage.custom_percentage is setted a true

#<br>

3.2.1. Measure Labels with HTML

Measure labels can be expressed in full HTML via the measure_html property in the dataset. Here is an example: At the moment this type of labels are suspended due to incompatibility with IE11 and wrapping text

WE HAVE INTRODUCED measure_description that in combination with y_title_tooltip can support html tag

<br>

3.2.2. Icon property

NameTypeDefaultDescription
urlstringUrl of image
widthintWidth of image to be used
heightintWidth of image to be used
paddingObject{left: int, right: int }Object with 2 key, left, for add margin to left, right to add margin on right
background_classstringClass for customize the circle appended on the background of icon
<br> <br>

3.2.3. Percentage property

NameTypeDefaultDescription
measurestringValue to set on the right of the graph
classstringClass to be used for this custom param
<br>

3.2.4. Complex data example

This is a simple complex example with all data features enabled:

var dataset = [{
    "measure": "Fat Bike",
    "categories": { // category names and their colors defined here
        "0": {class: "rect_has_no_data", tooltip_html: '<i class="fas fa-fw fa-exclamation-circle tooltip_has_no_data"></i>' },
        "1": {class: "rect_has_data", tooltip_html: '<i class="fas fa-fw fa-check tooltip_has_data"></i>'},
        "Zoe": {class: "rect_purple" , tooltip_html: '<i class="fas fa-fw fa-trophy tooltip_purple"></i>'},
    },
    "category_percentage": "Zoe", // if percentage enable, calculates the percentage of this category
    "data": [
        ["2016-01-01 12:00:00", "Kim", "2016-01-01 13:00:00"],
        ["2016-01-01 14:22:51", "Zoe", "2016-01-01 16:14:12"],
        ["2016-01-01 16:14:12", "Bert", "2016-01-01 17:14:12"],
        ["2016-01-01 19:20:05", "Zoe", "2016-01-01 20:30:00"]
    ],
    "icon": {
      "url":"your_url_file",
      "width": 24,
      "height":24,
      "padding": {
          "left": 0,
          "right": 5
      },
      "background_class": "icon_class"
    },
    "percentage": { //used for customize right text
        "measure": "45 %",
        class: "y_percentace_test"
    }
}];
<br>

3.3. Chart Options

The options of the chart are in JSON format and you can customize everything. You can pass the JSON Object to library with custom settings

NameTypeDefaultDescription
id_div_containerstringvisavail_containerId of div that contain the graph tag
moment_localestringautodetectThe lib autodetect language browser and set the moment library automatically. You can change this parameter with a string contained into locale moment.js lib. if you set to null moment use "en" format as default (see moment.js library)
marginObject{}more infoJson Object that contain margin of graphs include title, legent etc.
paddingObject{}more infoJson Object that contain padding of graphs
widthnumber960Width of the graph, this option was ignored if option resposive is enabled
reduce_space_wrapnumber36Space for three dots when you use a simple title of mesurment
line_spacingnumber16Space between two row of dataset
emphasize_year_ticksbooleantrueEmphasize the year when the range of data cover one more year
emphasize_month_ticksbooleantrueEmphasize the month when the range of data cover one more month and not exceed the year
max_display_datasetsnumber0max. no. of datasets that is displayed, 0: all (is the same option of original library)
ticks_for_graphnumber6number of ticks that is displayed, null: max enter in the tick (may cause overlap problem). N.B the ticks are controlled by d3.js lib. in some case this value will be ignored but help you for prevent overlap xaxis top
cur_display_first_datasetnumber0current first dataset to display (is the same option of original library)
display_date_rangeArray[][0,0]range of dates that will be shown. If from-date (1st element) or to-date (2nd element) is zero, it will be determined according to your data (default: automatically)
custom_categoriesbooleanfalseSet to true if you want to use custom category
is_date_only_formatbooleanfalseCheck if the date is with date only ( will set Automatically)
show_y_titlebooleantrueIf you set to fale, reminder to set properly margin and padding left
y_title_some_unavailability_classstringsome_unavailabilitySet a additional custom class to y_title when some unavailability, if you want
y_title_total_unavailability_classstringtotal_unavailabilitySet a additional custom class to y_title when total unavailability, if you want
y_title_total_availability_classstringtotal_availabilitySet a additional custom class to y_title when total availability, if you want
date_in_utcbooleanfalseSet true or false in base of your type of date. If true we use moment to set the date in the current user timezone or in the timezone set by script. For improve the speed of graph we suggest to you to set this parameter to false and convert your dataset with moment before send to graph
date_is_descendingbooleanfalseSet true if you want display your dataset is descending version (from now to old). If false the data was diplayed in standard view N.B.: the data in dataset is in ascending order
defined_blocksbooleanfalseIf set to true the we ignore interval_s options in datasets and we use a block defined. This option is set automatically if in there is a date/time defined
onClickBlockfunction(d,i)nullreturn "d" an arry with date and value precessed and "i" value of block clicked item
y_title_tooltipObject{}more infoJson Object that contain tooltip option for the graph. For the content of div we use "measure_description" tag that can be contain also html tag
y_percentageObject{}more infoJson Object that contain y_percentage option for the graph
tooltipObject{}more infoJson Object that contain tooltip option for the graph
legendObject{}more infoJson Object that contain legend option for the graph
titleObject{}more infoJson Object that contain title option for the graph
sub_titleObject{}more infoJson Object that contain sub-title option for the graph
iconObject{}more infoJson Object that contain icon option for the graph
graphObject{}more infoJson Object that contain option for custom type of graph
responsiveObject{}more infoJson Object that contain option for responsive layout of graph
zoomObject{}more infoJson Object that contain option for zoom in the graph
sub_chartObject{}more infoJson Object that contain option for enable sub-chart in the graph
custom_time_formatObject{}more infoJson Object that contain option for customize the x-axes tick into graph
<br>

3.3.1. Margin

NameTypeDefaultDescription
topnumber65Number express in px
bottomnumber40Number express in px
rightnumber20Number express in px
leftnumber100Number express in px
<br>

3.3.2. Padding

NameTypeDefaultDescription
topnumber-50Number express in px
bottomnumber10Number express in px (not used at the moment)
rightnumber0Number express in px, used for move the y percentage on the right
leftnumber-100Number express in px, used for move the y title on the left
<br>

3.3.3. Y Title Tooltip

NameTypeDefaultDescription
enabledbooleanfalseenable possibility to activate tooltip over on Y lable
classstringy-tooltipSet a custrom class if you want
typestringrightThree type of tooltip: "top" is a div on top of y label, "bottom" is a div on bottom of y label,"right" is a div on right of y label,
spacingObject{}{left: 15, right:15, top: 15,bottom:10}used to add space to tooltip in base of tooltip type selected
fixedbooleanfalseValid only on "left" tooltip type, if true fixed the tooltip all right of y lable
durationnumber150Number in ms for the animation duration (all tooltip otpion)
<br>

3.3.4. Tooltip

NameTypeDefaultDescription
classstringtooltipSet a custrom class if you want
heightnumber10height of tooltip , correspond to line-height of class tooltip from css)
positionstringtopTwo type of tooltip: "top" is a div before bar follow the mouse only left, "overlay" follow the mouse left and height
left_spacingnumber0Left space from tooltip and mouse
date_plus_timebooleanfalseenable date and time on tooltip (override the is_date_only_format option)
only_first_datebooleanfalseshow only first date on tooltip (we suggest to use this on rhombus or circle graph)
durationnumber150Number in ms for the animation duration (all tooltip otpion)
hover_zoomObject{}more infooption for zoom block on hover

#<br>

3.3.5. 3.3.4.1 Hover Zoom Option

NameTypeDefaultDescription
enabledbooleanfalseEnable block zoom whe mouse hover
rationumber0.4Number from 0 to 1 that incrase the block size. It will be multiplied with option line_spacing
<br>

3.3.6. Legend

NameTypeDefaultDescription
enabledbooleantrueEnable the legend (If you use a custom categories the legend is hidden)
line_spacenumber12height of legend font , correspond to line-height of class tooltip from css)
offsetnumber5Distance from two data of legend
x_right_offsetnumber150Legend position distance from right
has_no_data_textstringNo Data availableString for no data available
has_data_textstringData availableString for no data available
<br>

3.3.7. Title

NameTypeDefaultDescription
enabledbooleantrueEnable the title
line_spacenumber16height of legend font , correspond to line-height of class tooltip from css)
textstringData Availability PlotString Title
<br>

3.3.8. Sub Title

NameTypeDefaultDescription
enabledbooleantrueEnable the title
line_spacenumber16height of legend font , correspond to line-height of class tooltip from css)
from_textstringfromString for from date
to_textstringtoString for to date
<br>

3.3.9. Icon

NameTypeDefaultDescription
class_has_datastringfas fa-fw fa-checkcustom icon call (for example font awesome)
class_has_no_datastringfas fa-fw fa-timescustom icon call (for example font awesome)
<br>

3.3.10. Graph

NameTypeDefaultDescription
typestringbarThere are three type of graph; "bar" is a classical horizzontal bar, "rhombus" use a rhombus for a simple alert, "circle" a drop for a event chart
heightnumber20height of type of graph
widthnumber20width of type of graph, used only for rhombus type and circle type
<br>

3.3.11. Responsive

NameTypeDefaultDescription
enabledbooleanfalseEnable the resposive chart for a responsive layout (this option recreate the chart when the page or div of chart will be resized)
onresizefunctionnullat the moment not supported
<br>

3.3.12. Zoom

NameTypeDefaultDescription
enabledbooleanfalseEnable the zoom in the chart. We can zoom with mousewheel and you can mof left-right for move in the graph
onZoomfunction(e)nullreturn a current array with current domain of current zoom in date format
onZoomStartfunction(e)nullreturn a d3.event json object when zoom start
onZoomEndfunction(e)nullreturn a array with current domain of current zoom in date format at the end of the zoom
<br>

3.3.13. Sub Chart

NameTypeDefaultDescription
enabledbooleanfalseEnable the sub-chart under the chart. We can drag, move, zoom with this
heightnumber0Height of bottom sub chart
animationbooleantrueEnable animation when you drag, move the sub_chart bar
marginObject{}{top:20, bottom:0}Integer value to add some space top or bottom after sub_chart
graphObject{}more infooption for zoom block on hover

#<br>

3.3.14. Sub Chart Graph Option

NameTypeDefaultDescription
enabledbooleantrueCreate a mini chart into sub_chart bar (need to have a sufficient height to contain the graph)
widthnumber7width of type of graph, used only for rhombus type and circle type
heightnumber7height of type of graph into sub_chart
line_spacingnumber7Space between two row of dataset into sub_chart
<br>

3.3.15. Custom Tick Format

This library use moment.js to customize and convert the date format/language in base of moment.locale() function (we autodetect the browser language!). If you what change manually the tick format you can customize with this option.

With set this option you override the automatic tick format execute by library for a specific locale.

NameTypeDefaultDescription
format_millisecondstringmoment convertioncustom format for millisecond
format_secondstringmoment convertioncustom format for second
format_minutestringmoment convertioncustom format for minute
format_hourstringmoment convertioncustom format for hour
format_daystringmoment convertioncustom format for day
format_weekstringmoment convertioncustom format for week
format_monthstringmoment convertioncustom format for month
format_yearstringmoment convertioncustom format for year
<br>

3.3.16. Y Percentage

NameTypeDefaultDescription
enabledbooleanfalseenable percentage
some_unavailability_classstringsome_unavailabilitySet a additional custom class to y_percentage when some unavailability, if you want
total_unavailability_classstringtotal_unavailabilitySet a additional custom class to y_percentage when total unavailability, if you want
total_availability_classstringtotal_availabilitySet a additional custom class to y_percentage when total availability, if you want
percentageFormatfunctionSee codeSet a custom percentage format function if you want
unavailabililty_percentagebooleanfalseIf true, calculates the percentage of unavailability instead of availability. Not valid if custom categories enabled
custom_percentagebooleanfalseIf true, append a custom text present in the measurment data under key: percentage.measure
<br>

3.3.17. Example Usage

In this example we use a custom id for a div container and div graph, custom icon for tooltip, enabled zoom and resposive layout

var options = {
	id_div_container: "visavail_container",
	id_div_graph: "visavail_graph",
	icon: {
		class_has_data: 'fas fa-fw fa-check',
		class_has_no_data: 'fas fa-fw fa-exclamation-circle'
	},
	zoom:{
		enabled:true,
	},
	responsive:{
		enabled:true,
	}
};
<br>

3.3.18. Implementation

To use the chart in your project, follow these steps:

  1. Copy the visavail.js and visavail.css into your css and js forder project (for minify version).

  2. Assuming that your website is in the root folder, add the following lines to the <head> of your website:

    <link href="https://fonts.googleapis.com/css?family=Muli" rel="stylesheet" type="text/css">
    <link href="./css/visavail.css" rel="stylesheet" type="text/css">
    <link href="./css/font-awesome.min.css" rel="stylesheet" type="text/css">
    
  3. And the following lines to the <body> of your website:

    <script src="./js/moment-with-locales.min.js" type="text/javascript"></script>
    <script src="./js/d3.min.js" charset="utf-8"></script>
    <script src="./visavail/js/visavail.js"></script>
    
    <div style="overflow: hidden;" class="visavail" id="visavail_container">
    	<p id="visavail_graph"><!-- Visavail.js chart will be placed here --></p>
    </div>
    
    <script type="text/javascript">
    	moment.locale("en");
    	var dataset = ... // see examples/example_basic.htm
    	var options = {
    		id_div_container: "visavail_container",
    		id_div_graph: "visavail_graph",
    	};
    	
    	var chart = visavail.generate(options, dataset)
    </script>
    
<br>

3.3.19. Integrate into Angular

You can use this library in your Anular 2+ project (tested in versions 2 to 8). Follow these steps to integrate it:

  1. Add to your package.json d3, moment and visavail package with npm installation

  2. In your component in the import section insert this line

    import * as visavail from "visavail";
    
  3. Create a JSON object in your component class that can be contain the dataset, options and chart

  4. Add the div in your html where you want to put the graph

  5. Call visavail.generate(...) funtion to generate the graph

You can find an example implementation HERE

<br>

3.3.20. Integrate into React.js

You can use this library in your React project (not completely tested). Follow these steps to integrate it:

  1. Add to your package.json d3, moment and visavail package with npm installation

  2. In your component in the import section insert this line

    import * as visavail from "visavail";
    
  3. Create a JSON object in your component class that can be contain the dataset, options and chart

  4. Add the div in your render() function

  5. Call visavail.generate(...) funtion to generate the graph into componentDidMount()

  6. If you want update the chart with new data, you can call the updateGraph(dataset) function into componentDidUpdate() react function

You can find an example of implementation HERE

<br>

3.3.21. 3.1.29.Visavail Function

The Visavail library contains functions to update, change and delete the graph without using manual functions, explained in the table below.

You can associate chart = visavail.generate(.....) and call chart.someFunctio() to change the graph

NameArgumentDescription
udpateGraph(options, dataset)options: JSON object with options, dataset: Array of JSONWith this function you can update the graph with new optiorn or new data or something related to dataset object. If you wnat mantain same oprion, you che put the first argument as null
resizeWidth(width)width: NumberWith this function you can update manually the width of the graph
displayDateRange(date_range, dataset)date_range: [first date, second_date], dataset: Array of JSONWith this function you can update the date range of the graph to focus the graph in a specific time of period
destroy()emptyWith this function you can delete the graph and all div generate by library
<br>

4. Public Projects With Visavail.js

<br>

5. Download

An archive with the library can be downloaded from the releases page.

<br>

6. Dependencies

Visavail.js depends on these libraries:

<br>

7. Contribution

We welcome any contribution or feedback. Please let us know about your comments via the Issues tab on GitHub

<br>

8. License

The Visavail.js library is distributed under the MIT License (MIT). Please also take note of the licenses of the dependencies.