Quantcast
Channel: Tutorials – amCharts Version 3 Documentation
Viewing all 111 articles
Browse latest View live

CSS class names of visual chart elements

$
0
0

Since version 3.12.0 you can enable CSS class names on virtually any internal chart or map object: line, fill, column, bullet, plot area, balloon, legend label, you name it.

You just need to set the addClassNames property to true.

This enables you to manipulate the appearance of virtually any chart item by apply CSS styles.

Below table reflects the names and hierarchy of the classes that are applied to objects.

Class name Element & Comment Type Docs
amcharts-bg background <path> backgroundColor
amcharts-title title <text> titles
amcharts-title-[id] title with title id, if it is set <text> titles
amcharts-label label <text> allLabels
amcharts-label-[id] label with label id, if it is set <text> allLabels
amcharts-main-div div which contains both chart and legend <div> write or makeChart
amcharts-chart-div div which contains chart <div> write or makeChart
amcharts-plot-area background of plot area <path> backgroundColor
amcharts-plot-area-left left side of plot area (only if chart is 3D) <path> backgroundColor
amcharts-plot-area-bottom bottom side of plot area (only if chart is 3D) <path> backgroundColor
amcharts-zoom-out-bg background of zoom-out button <path> zoomOutButtonColor
amcharts-zoom-out-label label of zoom-out button <text> zoomOutText
amcharts-zoom-out-image image of zoom-out button <image> zoomOutButtonImage
amcharts-legend-div div which contains legend <div> divId
amcharts-legend-bg background <path> backgroundColor
amcharts-legend-title title of a legend (used in stock chart only) <text> labelText
amcharts-legend-item-[id] legend item, added if graph has id. It contains all the other elements of legend item. <g> labelText
[custom-class] legend item, added if slice or graph has customClass set. It contains all the other elements of legend item. <g> labelText
amcharts-legend-marker marker of a legend <path>, <circle>, <image> or <rect> markerType
amcharts-legend-label label of a legend item <text> labelText
amcharts-legend-value value text of a legend item <text> valueText
amcharts-legend-switch marker switch which shows if an item is turned on or off <path> switchType
amcharts-pie-item pie item which holds all elements of a slice, set if a classNameField is set on chart and data provider has class names <g> Slice
[custom-class] pie item which holds all elements of a slice, set if a classNameField is set on chart and data provider has class names <g> Slice
amcharts-pie-slice slice of a pie <path> Slice
amcharts-pie-label label of a pie <text> labelText
amcharts-pie-tick tick from slice to label <path> labelTickAlpha
amcharts-funnel-item funnel item which holds all elements of a slice, set if a classNameField is set on chart and data provider has class names <g> Slice
[custom-class] funnel item which holds all elements of a slice, set if a classNameField is set on chart and data provider has class names <g> Slice
amcharts-funnel-slice slice of a funnel <path> Slice
amcharts-funnel-label label of a funnel <text> labelText
amcharts-funnel-tick tick from slice to label <path> labelTickAlpha
amcharts-gauge-arrow gauge arrow. It contains both elements of an arrow – arrow itself and a “nail” at the root of an arrow <g> GaugeArrow
amcharts-gauge-arrow-[id] gauge arrow. It contains both elements of an arrow – arrow itself and a “nail” at the root of an arrow <g> GaugeArrow
amcharts-nail circle at the root of an arrow <circle> nailAlpha
amcharts-arrow arrow of gauge <path> GaugeArrow
amcharts-gauge-axis gauge axis. It contains all elements of an axis <g> GaugeAxis
amcharts-gauge-axis-[id] gauge axis. It contains all elements of an axis <g> GaugeAxis
amcharts-axis-line line (arc) of an axis <path> axisAlpha
amcharts-axis-top-label top label of gauge axis <text> topText
amcharts-axis-bottom-label bottom label of gauge axis <text> bottomText
amcharts-axis-label value label of gauge axis <text> labelFunction
amcharts-axis-band color band of gauge axis <path> GaugeBand
amcharts-axis-band-[id] color band of gauge axis <path> GaugeBand
amcharts-axis-tick tick of gauge axis <path> tickAlpha
amcharts-axis-tick-minor minor tick of gauge axis <path> minorTickInterval
amcharts-category-axis category axis container which contains all elements of axis, including guides <g> CategoryAxis
amcharts-value-axis value axis container which contains all elements of value axis, including value axis guides <g> ValueAxis
amcharts-value-axis-[id] value axis container which contains all elements of value axis, including value axis guides <g> ValueAxis
amcharts-axis-grid axis grid line <path> gridAlpha
amcharts-axis-tick axis tick <path> tickLength
amcharts-axis-fill fill between grid lines <path> fillAlpha
amcharts-axis-label axis label <text> labelsEnabled
amcharts-axis-title axis title <text> title
amcharts-zero-grid rectangular charts only. Grid line at zero value <path> baseValue
amcharts-zero-grid-[id] rectangular charts only. Grid line at zero value. id is id of an axis. <path> baseValue
[custom-class] custom class will be added to all elements of a axis item – tick, label, grid and fill, if it’s serial chart with non-date-based data and classNameField is set for category axis and you have class name specified in your data. <path> or <text> AxisBase
amcharts-guide-fill fill between guides <path> Guide
amcharts-guide-fill-[id] fill between guides, id is id of a guide. <path> Guide
amcharts-guide added to all elements of a guide – tick, grid, label (together with default tick, grid and label classes) <path> or <text> Guide
amcharts-guide-[id] added to all elements of a guide – tick, grid, label (together with default tick, grid and label classes). id is id of a guide. <path> or <text> Guide
amcharts-trend-line trend line <path> TrendLine
amcharts-trend-line-[id] trend line, id is id of a trend line <path> TrendLine
amcharts-balloon-bg background of a balloon <path> AmBalloon
amcharts-balloon-bg-[id] background of a balloon, id is id of a graph or axis <path> AmBalloon
amcharts-balloon-div balloon content div <div> AmBalloon
amcharts-balloon-div-[id] balloon content div, id is id of a graph or axis <div> AmBalloon
amcharts-cursor-line line of a cursor <path> ChartCursor
amcharts-cursor-fill fill of a cursor (when fullWidth is true) <path> ChartCursor
amcharts-cursor-value-line value line of a cursor <path> cursorAlpha
amcharts-cursor-selection selected rectangle <path> selectionAlpha
amcharts-scrollbar-bg background of a scrollbar <g> ChartScrollbar
amcharts-scrollbar-bg-selected background of selected area of a scrollbar <g> backgroundAlpha
amcharts-scrollbar-grip-left image of left grip <image> hideResizeGrips
amcharts-scrollbar-grip-right image of right grip <image> hideResizeGrips
amcharts-graph-[type] container of all graph elements <g> AmGraph
amcharts-graph-[id] container of all graph elements <g> AmGraph
amcharts-graph-stroke stroke element of line, smoothedLine, step and ohlc vertical part. <path> lineAlpha
amcharts-graph-fill fill of area graphs. Note, graph.fillAlphas must be set to >0 in order this element to be drawn <path> fillAlphas
amcharts-graph-stroke-negative negative part of line, smoothedLine and step graphs, drawn only if graph.negativeLineColor is set. <path> negativeLineAlpha
amcharts-graph-fill-negative negative part of area graphs, drawn only if graph.negativeLineColor is set. <path> negativeFillAlphas
amcharts-graph-column-element all elements from which column is made (both 2D and 3D), used by column and candlestick graphs <path> AmGraph
amcharts-graph-column-front front side of column (the only one if the chart is 2D) <path> AmGraph
amcharts-graph-column-back back side of column <path> AmGraph
amcharts-graph-column-top top side of column <path> AmGraph
amcharts-graph-column-bottom bottom side of column <path> AmGraph
amcharts-graph-column-left left side of column <path> AmGraph
amcharts-graph-column-right right side of column <path> AmGraph
amcharts-graph-stroke-open open line of ohlc graph <path> AmGraph
amcharts-graph-stroke-close close line of ohlc graph <path> AmGraph
amcharts-graph-stroke-high high line of candlestick graph <path> AmGraph
amcharts-graph-stroke-low low line of candlestick graph <path> AmGraph
amcharts-graph-bullet bullet of a graph <path> bullet
[custom-class] custom class will be added to a bullet if classNameField is set for this graph and you have class name specified in your data. <path> AmGraph
amcharts-stock-div div which holds all the elements of stock chart <div> AmStockChart
amcharts-left-div div which holds all left-side elements <div> AmStockChart
amcharts-right-div div which holds all right-side elements <div> AmStockChart
amcharts-center-div div which holds all center elements – panels and scrollbar chart <div> AmStockChart
amcharts-scrollbar-chart-div div which holdsscrollbar chart <div> AmStockChart
amcharts-panels-div div which holds all panels <div> StockPanel
amcharts-stock-panel-div div of a panel <div> StockPanel
amcharts-stock-panel-div-[id] div of a panel <div> StockPanel
amcharts-data-set-selector-div div of data set selector <div> DataSetSelector
amcharts-data-set-select data set select <select> DataSetSelector
amcharts-data-set-select-option data set select option <option> DataSetSelector
amcharts-compare-div data set compare div <div> DataSetSelector
amcharts-compare-item-div data set compare div's single element <div> DataSetSelector
amcharts-period-selector-div div of period selector <div> PeriodSelector
amcharts-start-date-input input field of start date <input> PeriodSelector
amcharts-end-date-input input field of end date <input> PeriodSelector
amcharts-period-input predefined period button <input> PeriodSelector
amcharts-period-input-selected predefined period button selected state <input> PeriodSelector
amcharts-drawing-tools container which holds drawing icons <g> StockPanel
amcharts-pencil pencil image of drawing icons <image> StockPanel
amcharts-pencil-selected pencil image of drawing icons, selected state <image> StockPanel
amcharts-eraser eraser image of drawing icons <image> StockPanel
amcharts-eraser-selected eraser image of drawing icons, selected state <image> StockPanel
amcharts-map-area-unlisted map area not listed in data provider <path> MapObject
amcharts-map-area map area <path> MapArea
amcharts-map-area-[id] map area <path> MapArea
amcharts-map-line map line <path> MapLine
amcharts-map-line-[id] map line <path> MapLine
amcharts-map-image map image <path> MapImage
amcharts-map-image-[id] map image <path> MapImage
amcharts-map-image-label map image label <text> MapImage
amcharts-map-image-label-[id] map image label <text> MapImage
amcharts-zoom-control container which holds zoom control and pan control elements <g> ZoomControl
amcharts-zoom-control-zoom container which holds zoom control elements <g> ZoomControl
amcharts-zoom-bg background of zoom-control <rect> ZoomControl
amcharts-zoom-grid grid lines of zoom-control <path> ZoomControl
amcharts-zoom-out zoom-out button <g> ZoomControl
amcharts-zoom-in zoom-in button <g> ZoomControl
amcharts-zoom-dragger dragger of a zoom control <g> ZoomControl
amcharts-zoom-control-pan container which holds pan control elements <g> ZoomControl
amcharts-pan-left left button <g> ZoomControl
amcharts-pan-right right button <g> ZoomControl
amcharts-pan-top top button <g> ZoomControl
amcharts-pan-bottom bottom button <g> ZoomControl
amcharts-pan-home home button <g> ZoomControl
amcharts-small-map container which holds small map elements <g> SmallMap
amcharts-small-map-bg background of small map <rect> SmallMap
amcharts-small-map-image map of small map <g> SmallMap
amcharts-small-map-rectangle rectangle, showing selected area on small map <rect> SmallMap
amcharts-small-map-down button to minimize small map <g> SmallMap
amcharts-small-map-up button to maximize small map <g> SmallMap
amcharts-value-legend container which holds value legend elements <g> AmLegend
amcharts-value-legend-min-label value legend minimum label <text> AmLegend
amcharts-value-legend-max-label value legend maximum label <text> AmLegend
amcharts-value-legend-color color element of value legend <rect> AmLegend
amcharts-value-legend-color-[num] color element of value legend <rect> AmLegend
amcharts-value-legend-gradient color gradient of value legend <rect> AmLegend
amcharts-object-list-div div which holds object list <div> ObjectList
amcharts-object-list-ul ul element of object list <ul> ObjectList
amcharts-object-list-li li element of object list <li> ObjectList
amcharts-object-list-a a element of object list <a> ObjectList
amcharts-description-div div which holds description window <div> description
amcharts-description-close-img close button image <div> description
amcharts-description-title-div description window title div <div> description
amcharts-description-text-div description window text (content) div <div> description

The post CSS class names of visual chart elements appeared first on amCharts.


CSS animations

$
0
0

Since we have added the possibility to add class names on our chart elements, you are able to animate the SVG elements with CSS. Define custom class names to point out specific data points or attract the users in general by animating the whole graph at all. This gives you more freedom, an interactive feeling and pure satisfaction.

Browser Support

Most of the modern browser already implemented the CSS animation on SVG elements due the W3C drafts. Unfortunately the guys from the Internet Explorer decided to skip this whole subject, which is not a problem at all because the browser will simply ignore those definitions and displays the normal static chart. Please take a look to the official SVG specification to see which properties can be modified.

Possibilities & Benefits

Enjoy the good'ol childhood times and dive into the CSS playground to and create animation as you want. Point out a single data points, highlight whole graphs or add some interactivity with the CSS mouse states - the only limitation is your imagination. By that you will be able to keep the eyes on the important parts, your charts.

See the Pen CSS Animations by amCharts (@amcharts) on CodePen.

Setup & Markup

We've created a namespacing concept which let you animate all element from one type at once or simply pick one and animate it individually. To get started you just need to enable the addClassNames property in your chart setup, then start with the CSS definitions - that's it. We've created a sample file from which you can start of to modify or simply obtain.

<script type="text/javascript">
	var chart = AmCharts.makeChart("chartdiv", {
		type: "serial",
		addClassNames: true,
		classNamePrefix: "amcharts", // Default value
		...
	});
</script>
<link rel="stylesheet" href="http://extra.amcharts.com/support/ameffects.css">
<style type="text/css">
	.amcharts-graph-line {
		-webkit-animation: am-pulsate-line 1s linear infinite;
		animation: am-pulsate-line 1s linear infinite;
	}
</style>

To pick an individual graph simply define an id within the graph setup and use that in your CSS like following, please take a look to the css class name overview to see which elements you can access through the CSS selector.

<script type="text/javascript">
	var chart = AmCharts.makeChart("chartdiv", {
		type: "serial",
		addClassNames: true,,
		classNamePrefix: "amcharts", // Default value
		...
		graphs: [{
			id: "g3",
			...
		}]
	});
</script>
<style type="text/css">
	.amcharts-graph-g3 .amcharts-graph-line {
		-webkit-animation: am-pulsate-line 1s linear infinite;
		animation: am-pulsate-line 1s linear infinite;
	}
</style>

JavaScript Charts

Have a look to those inspirations and see what you can archive only with CSS, pick one of those below and feel free to overtake it or tweak it to your needs.

JavaScript Maps

All effects you've seen above can be applied to our maps as well, we've prepared some different ones for you to get an idea what else can be done to highlight areas or lines.

We hope you'll have that much fun as we had while doing this feature, happy coding!

The post CSS animations appeared first on amCharts.

Changing chart size with CSS

$
0
0

Fixed sizes are so yesterday, nowadays everything needs to be responsive to fit just right on every screen size - otherwise elements get cropped and the user needs to scroll which nobody likes. Since beginning our charts already adapt themselves according to the available space and decides how man grids and axis labels will be shown to present always a good looking chart. But if the chart is within a container with a fixed height and the screen of the device is quite small the result might be unsatisfying - therefore we should take advantage of CSS to create a neat responsive wrapper which adapts it's height according to the width without weird calculations through JavaScript.

Setup & Markup

Simply wrap the chart container in another div and apply the CSS below to adapt the height proportionally to the width - through the bottom padding you can define the relative height.

<div class="responsive-container">
  <div id="chartdiv"></div>
</div>
<style type="text/css">
 .responsive-container {
   position: relative;
   padding-bottom: 60%; /* the higher the bigger the ratio */
 }
 .responsive-container > div {
   position: absolute;
   top: 0;
   right: 0;
   bottom: 0;
   left: 0;
 }
</style>

See the Pen Changing chart size with CSS by amCharts (@amcharts) on CodePen.

Note: no specific/fixed height has been set as usually; this sample uses validateSize on slider updates to demonstrate the window resize

Extend the feature

If you want to get one step further you can also adapt your chart category axis labels to fit even better on smaller or bigger screens, therefore simply add some logic in your labelFunction method within your chart setup to archive such feature:

{
        "categoryAxis": {
            "labelFunction": function(label,item,chart) {
              if ( chart.cellWidth < 60 ) {
                 label = label.split(" ")[1];
               }
               return label;
             }
         },
 }

or take advantage of the drawn event to overwrite the settings to gain more space e.G like in this pie chart

chart.addListener("drawn",function(e) {
  var io = e.chart.divRealWidth < 700;
 
   e.chart.marginTop = io ? -45 : 0;
   e.chart.marginBottom = io ? -45 : 0;
   e.chart.labelRadius = io ? -30 : 20;
   e.chart.color = io ? "#000000" : "#FFFFFF";
 
 });
 

See the Pen Changing chart size with CSS by amCharts (@amcharts) on CodePen.

More possibilities

CSS has more to offer, modern browser are able to animate SVG elements! If you want to tweak your chart even further - ensure to take a look to our CSS Animations tutorial which demonstrates you how to point our specific parts of your chart.

The post Changing chart size with CSS appeared first on amCharts.

Making charts and maps responsive

$
0
0

Starting with version 3.13 amCharts has introduced a plugin which allows transparently enabling responsive features of the charts and maps.

Compatible with all amCharts products - JavaScript Charts, JavaScript Stock Chart and JavaScript Maps - this plugin dynamically scales-down and -up chart's visual features to best suit available viewport.

This article deals on how to enable and tweak the plugin behavior.

What "amCharts Responsive" does?

"Responsive" chart or map will modify it's features dynamically (even as you resize the container) based on the available area. For example: a full fledged line chart with legend guides, labels, titles and other elements will be displayed in all its glory if container is big enough.

Responsive serial chart

If the container shrinks (i.e. you resize a browser window or view it on an iPad), it starts "compacting" the chart. First the legend is removed. Shrink it even further, axis titles are removed and its value labels are moved inside the plot area. Going even smaller, bullets, labels gone. All the way to the sparkline representation of the chart.

Plugin brings a universal set of pre-defined rules that you can use to instantly enable responsiveness. Those are custom-tailored for each chart/map type and
will probably fit your requirements out-of the-box. All you need to do is to enable "responsive" plugin for your chart instance. You can modify those defaults rules, or make your own list. The plugin allows that. (see further down this file for instructions)

Example?

Here's a live example that will help you get a feeling of what responsive charts are all about.

Where do I get it?

Starting with v3.13, the plugin is bundled with all amCharts products. (Please note that the plugin will not work on any earlier versions of amCharts products)

You can also get the latest build directly from its GitHub repository:

https://github.com/amcharts/responsive

Enabling responsive features

1. Include the minified version of file of this plugin. I.e.:

<script src="amcharts/plugins/responsive/responsive.min.js" type="text/javascript"></script>

(this needs to go after all the other amCharts includes)

2. Add the following setting to your chart configuration:

AmCharts.makeChart( "chartdiv", {
  ...,
  "responsive": {
    "enabled": true
  }
} );

Or if you are using non-JSON setup:

chart.responsive = {
  "enabled": true
};

That's it.

Advanced use

Rules

You can modify (or completely overwrite) the default responsive rules used by the plugin.

A plugin works by checking chart area dimensions after each resize. (or after initial build / mobile device orientation change) It then overrides particular settings suitable for these particular dimensions.

Override rules are implemented by defining chart rules, or just "rules" moving forward. Each rule has two things:

1. Dimension conditions;
2. Overrides. (a set of properties to override for this particular rule)

A rule is an object, for example:

{
  "minWidth": 200,
  "maxWidth": 400,
  "maxHeight": 400,
  "minHeight": 200,
  "overrides": {
    "precision": 2,
    "legend": {
      "enabled": false
    },
    "valueAxes": {
      "inside": true
    }
  }
}

The above rule will be applicable to a chart that is between 200px and 400px in width and height.

It is not necessary to add all of the dimensional properties. You just neat at least one.

So for example to make the rule apply to all charts with width 400px or lower, you would do something like this:

{
  "maxWidth": 400,
  "overrides": {
    "precision": 2,
    "legend": {
      "enabled": false
    },
    "valueAxes": {
      "inside": true
    }
  }
}

Please note that there are several other conditional properties besides the ones that deal with chart's dimensions:

  • rotate (true|false) - set this property if you want to make this rule applicable to rotated serial chart only (i.e. bar chart)
  • legendPosition ("top|bottom|left|right") - set this property if you want the rule applied only when the chart legend is set to particular position. Please note that this does not check whether the legend is enabled at all.

Now, on to explaining "overrides". It's an object, that contains properties that you want to override the chart's initial ones with.

It can be either simple properties, like fontSize or "precision", or complex types like object, or array.

To override a property of a child object, such as "legend", you would simply go with JSON representation of the properties you need to override. I.e.:

"legend": {
  "enabled": false
}

This will look for a legend property in chart object, then change it's enabled property to false.

Overriding arrays of objects

Some objects in charts are collected in arrays, i.e. graphs, valueAxes, etc.

There are some ways to override their properties as well.

To override properties for ALL objects in the array, you would provide an override instruction as an object. I.e.:

"graphs": {
  "bullet": "round",
  "lineThickness": 5
}

The above will add a round bullet and set line thickness to all of the graphs on the chart.

You can also target individual items in the array. There are two ways to do that:

a) Use id property;
b) Apply using the same index.

To individually apply property overrides, you will need to supply override instructions as an array:

"graphs": [
  {
    "id": "g1",
    "bullet": "round",
    "lineThickness": 5
  }
]

The above will apply the same properties for the graph with an id of "g1" only. It will not touch the rest of the graphs.

Please note that original graph definition in your chart settings needs to have the id property set so this plugin can target it.

Or you can omit the id and just apply overrides in the same order as you have them defined. I.e.:

"graphs": [
  {
    "bullet": "round"
  },
  {
    "bullet": "square"
  }
]

The above will apply round bullets to the first defined graph, and square bullets to the second graph.

Chaining multiple rules

The cool pat is that you can daisy-chain the override rules, much like in CSS.

The plugin will examine all of the rules if their dimensional conditions match current chart condition and will apply their overrides in the same order they are defined.

Consider this rule set:

"responsive": {
  "enabled": true,
  "rules": [
    // at 400px wide, we hide legend
    {
      "maxWidth": 400,
      "overrides": {
        "legend": {
          "enabled"
        }
      }
    },

    // at 300px or less, we move value axis labels inside plot area
    // the legend is still hidden because the above rule is still applicable
    {
      "maxWidth": 300,
      "overrides": {
        "valueAxes": {
          "inside": true
        }
      }
    },

    // at 200 px we hide value axis labels altogether
    {
      "maxWidth": 200,
      "overrides": {
        "valueAxes": {
          "labelsEnabled": false
        }
      }
    }

  ]
}

In case several rules modify the same property, the last one will always "win".

Combining custom rules with pre-defined ones

The plugin will combine your custom rules with pre-defined ones automatically.

In case you want to go pure and set only your own responsive rules, you can set property addDefaultRules to false. I.e.:

"responsive": {
  "enabled": true,
  "addDefaultRules": false,
  "rules": [
    {
      "maxWidth": 400,
      "overrides": {
        "legend": {
          "enabled"
        }
      }
    }
  ]
}

When your custom rules are combined with pre-defined ones, yours are appended at the end of the list. This means that your rules will always have the "last word".

The post Making charts and maps responsive appeared first on amCharts.

Applying SVG filters on charts and maps

$
0
0

Since 3.13.0 it is possible to define SVG-Filter natively through the chart setup, without touching the actual SVG or messing with the chart events. We have spend a while to think about a way how to provide you the best and easiest solution to define those SVG definitions – and guess what, the simple JavaScript object made it.

You only need to define the defs in your chart setup and enable addClassNames to apply those definitions to your chart elements through CSS, that's it.

Showcase & Awesomeness

See the Pen Using SVG Filters with amCharts by amCharts (@amcharts) on CodePen.

Support & Performance

Depends how many chart elements or total area you are pushing through the filter it might take a while until the final result is being shown but it's totally worth it and your user won't take their eyes off the charts.
The cross browser support isn't bad at all just the Internet Explorer support those since IE10. Don't abandon your mobile user, you might want to lower the complexity of your filter because the higher the processing time the higher the battery consumption. Last but not least check if all target browser render those effects properly, not very browser vendor implemented the filter correctly.

How it works

We have added a simple recursive method which gives you all the freedom you need by defining those definitions/filter and be completly independent from our side in case there are some bleeding edge features you just want to add but first let's dive into the definition.
Assuming you have already addClassNames enabled and got your defs ready to get defined, let's start with a simple blur effect:

var chart = AmCharts.makeChart("chartdiv",{
    defs: {
        "filter": [
            {
                "id": "blur",
                "feGaussianBlur": {
                    "in": "SourceGraphic",
                    "stdDeviation": "10"
                }
            }
        ]
    },
    ...
});

As you may have noted all keys which holds an array or object becomes to an element otherwise they will be attributes of this element. For this specific sample we have used feGaussianBlur and applied this filter on the SourceGraphic with slight deviation of 10, which generates following output:

<defs>
   <filter id="blur">
       <feGaussianBlur in="SourceGraphic" stdDeviation="10"></feGaussianBlur>
   </filter>
</defs>

The SVG side is done now, the only missing part is the link between filter and chart element which can be done through CSS like following:

.amcharts-graph-g1 .amcharts-graph-fill {
  filter: url(#blur);
}

See the Pen Using SVG Filters with amCharts by amCharts (@amcharts) on CodePen.

Possibilities & Inspiration

There are endless variations you can create, take a look to the W3C recommendation to see how many different filter you can apply and be combined with each other.
To give you a starting point we have created few samples to play around:

The post Applying SVG filters on charts and maps appeared first on amCharts.

Saving exported chart image on server

$
0
0

IMPORTANT NOTICE! The information provided in this article is outdated and is here for historical reference. Please refer to this tutorial for further information.

Instead of offering the user to save the image to his hard drive, you might want it to be saved on your web server. As our script allows adding custom click handlers, it's not that difficult to do this. In the sample below we added custom click handler:

"export": {
  "enabled": true,
  "class": "export-main",
  "libs": {
    "path": "../libs/"
  },
  "menu": [ {
    "label": "JPG",
    "class": "export-main",
    "click": function() {
      this.capture( {}, function() {
        this.toJPG( {}, function( data ) {
          console.log(data)
        } );
      } );
    }
  } ]
}

Now, if you click the export button, the script will output image data to your browser's console.

If you are experienced programmer, most likely you know what to do from this point - you should pass this data string to some script which would save it as an image. You have a wide selection of options here and you will need some additional library for this. We will use jQuery, as it is one of the most popular.

So, include jQuery lib to your HTML:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

And add these lines instead of console.log(data):

jQuery.post( "save.php", {
  imageData: encodeURIComponent( data )
},
function( msg ) {
  alert( "image saved" );
} );

Here's a full code:

"export": {
  "enabled": true,
  "class": "export-main",
  "libs": {
    "path": "../libs/"
  },
  "menu": [ {
    "label": "JPG",
    "class": "export-main",
    "click": function() {
      this.capture( {}, function() {
        this.toJPG( {}, function( data ) {
          jQuery.post( "save.php", {
              imageData: encodeURIComponent( data )
            },
            function( msg ) {
              alert( "image saved" );
            } );
        } );
      } );
    }
  } ]
}

Of course, instead of alerting some message, most likely you'll want to do something else.

Now, create save.php file and add these lines to it:

<?php
$data = urldecode($_POST['imageData']);
list($type, $data) = explode(';', $data);
list(, $data)      = explode(',', $data);
$data = base64_decode($data);
file_put_contents('image.png', $data);
?>

Upload all the files to your server, click export button and, if everything is correct - the image should be saved to your server.

Here is a working example illustrating saving image on the server.

The post Saving exported chart image on server appeared first on amCharts.

Exporting charts and maps as static images, data files or PDF

$
0
0

IMPORTANT NOTICE! The information provided in this article is outdated and is here for historical reference. Please refer to this tutorial for further information.

Exporting of charts and maps is done using the "Export" plugin which is included with all amCharts products.

It allows annotating and exporting chart or related data to various bitmap, vector, document or data formats, such as PNG, JPG, PDF, SVG, JSON, XLSX and many more.

Important notice

Please note that due to security measures implemented in modern browsers, some or all export options might not work if the web page is loaded locally (via file:///) or contain images loaded from different host than the web page itself.

Usage

1) Include the minified version of file of this plugin as well as the
bundled CSS file. I.e.:

<script src="amcharts/plugins/export/export.min.js"></script>
<link  type="text/css" href="../export.css" rel="stylesheet">

(this needs to go after all the other amCharts includes)

2) Enable `export` with default options:

AmCharts.makeChart( "chartdiv", {
  ...,
  "export": {
    "enabled": true,
    "libs": {
      "path": "../libs/"
    }
  }
} );

... OR set your own custom options:

AmCharts.makeChart( "chartdiv", {
  ...,
  "export": {
    "enabled": true,
    "libs": {
      "path": "../libs/"
    },
    "menu": [ {
      "class": "export-main",
      "menu": [ {
        "label": "Download",
        "menu": [ "PNG", "JPG", "CSV" ]
      }, {
        "label": "Annotate",
        "action": "draw",
        "menu": [ {
          "class": "export-drawing",
          "menu": [ "PNG", "JPG" ]
        } ]
      } ]
    } ]
  }
} );

Here's how export menu looks like with default options:

See the Pen Exporting the chart to various formats (default config) by amCharts (@amcharts) on CodePen.

Loading external libraries needed for operation of this plugin

The plugin relies on a number of different libraries, to export images, draw annotations or generate download files.

Those libraries need to be loaded for the plugin to work properly.

There are two ways to load them. Choose the one that is right:

1) Automatic (preferred)

All libraries required for plugin operation are included withing plugins */libs* subdirectory.

If you want the plugin to load them on-demand (when it's needed for a certain operation), make sure you set the `path` property under `libs` object to a relative or absolute url.

If you are using relative url, note that it is relative to the web page you are displaying your chart on, not the export.js library.

2) Manual

You can also load all those JavaScript libraries by `<script>` tags. Since loading of libraries is on by default you will need to turn it off by setting "libs": { "autoLoad": false }

Here is a full list of the files that need to be loaded for each operation:

File Located in Required for
blob.js libs/blob.js/ Exporting to any image format
fabric.min.js libs/fabric.js/ Any export operation
FileSaver.js libs/FileSaver.js/ Used to offer download files
pdfmake.min.js libs/pdfmake/ Export to PDF format
vfs_fonts.js libs/pdfmake/ Export to PDF format
jszip.js libs/jszip/ Export to XLSX format
xlsx.js libs/xlsx/ Export to XLSX format

Complete list of available export settings

Property Default Description
backgroundColor #FFFFFF RGB code of the color for the background of the exported image
enabled true Enables or disables export functionality
fileName amCharts A file name to use for generated export files (an extension will be appended to it based on the export format)
legend {} Places the legend in case it is within an external container
libs 3rd party required library settings (see the above section)
menu [] A list of menu or submenu items (see the next chapter for details)
fabric {} Overwrites the default drawing settings (Fabric library)
pdfMake {} Overwrites the default settings for PDF export (pdfMake library)
removeImages true If true export checks for and removes "tainted" images that area lodead from different domains

Configuring export menu

Plugin includes a way to completely control what is displayed on export menu. You can set up menus, sub-menus, down to any level. You can even add custom items there that execute your arbitrary code on click. It's so configurable it makes us sick with power ;)

The top-level menu is configured via `menu` property under `export`. It should always be an array, even if you have a single item in it.

The array items could be either objects or format codes. Objects will allow you to specify labels, action, icon, child items and even custom code to be executedon click.

Simple format codes will assume you need an export to that format.

Simple menu setup

Here's a sample of the simple menu setup that allows export to PNG, JPG and CSV:

"export": {
  "enabled": true,
  "libs": {
    "path": "../libs/"
  },
  "menu": [ {
    "class": "export-main",
    "menu": [ "PNG", "JPG", "CSV" ]
  } ]
}

The above will display a menu out of three options when you hover on export icon:

  • PNG
  • JPG
  • CSV

Here's the live demo:

See the Pen Exporting the chart to various formats (basic options) by amCharts (@amcharts) on CodePen.

When clicked the plugin will trigger export to a respective format.

If that is all you need, you're all set.

Please note that we have wrapped out menu into another menu item, so that only the icon is displayed until we roll over the icon. This means that technicallywe have a two-level hierarchical menu.

If we opmitted that first step, the chart would simply display a format list right there on the chart.

Advanced menu setup

However, you can do so much more with the menu.

Let's add more formats and organize image and data formats into separate submenus.

To add a submenu to a menu item, simply add a `menu` array as its own property:

"export": {
  "enabled": true,
  "libs": {
    "path": "../libs/"
  },
  "menu": [ {
    "class": "export-main",
    "menu": [ {
      "label": "Download as image",
      "menu": [ "PNG", "JPG", "SVG" ]
    }, {
      "label": "Download data",
      "menu": [ "CSV", "XLSX" ]
    } ]
  } ]
}

Now we have a hierarchical menu with the following topology:

  • Download as image
    • PNG
    • JPG
    • SVG
  • Download data
    • CSV
    • XLSX

Here's how it looks live:

See the Pen Exporting the chart to various formats (multi-level export menu) by amCharts (@amcharts) on CodePen.

We can mix "string" and "object" formats the way we see fit, i.e.:

"menu": [
  "PNG", 
  { "label": "JPEG",
    "format": "JPG" },
  "SVG"
]

The magic does not end here, though.

Adding custom click events to menu items

Just like we set `label` and `format` properties for menu item, we can set `click` as well.

This needs to be a function reference. I.e.:

"menu": [
  "PNG", 
  { "label": "JPEG",
    "click": function () {
      alert( "Clicked JPEG. Wow cool!" );
    } },
  "SVG"
]

Printing the chart

Adding menu item to print the chart or map is as easy as adding export ones. You just use "PRINT" as `format`. I.e.:

"menu": [
  "PNG", 
  "SVG",
  "PRINT"
]

Or if you want to change the label:

"menu": [
  "PNG", 
  "SVG",
  { "format": "PRINT",
    "label": "Print Chart"
  }
]

Annotating the chart before export

OK, this one is so cool, you'll need a class 700 insulation jacket.

By default each menu item triggers some kind of export. You can trigger an "annotation" mode instead by including `"action": "draw"` instead.

"menu": [ {
  "class": "export-main",
  "menu": [ {
    "label": "Download",
    "menu": [ "PNG", "JPG", "CSV", "XLSX" ]
  }, {
    "label": "Annotate",
    "action": "draw"
  } ]
} ]

Now, when you click on the "Annotate" item in the menu, the chart will turn into an image editor which you can actual draw on.

As cool as it may sound, there's little we can do if the annotated chart if we can't save the result image.

That's where sub-menus come for the rescue again:

"menu": [ {
  "class": "export-main",
  "menu": [ {
    "label": "Download",
    "menu": [ "PNG", "JPG", "CSV", "XLSX" ]
  }, {
    "label": "Annotate",
    "action": "draw",
    "menu": [ {
      "class": "export-drawing",
      "menu": [ "JPG", "PNG", "SVG", PDF" ]
    } ]
  } ]
} ]

Now, when you turn on the annotation mode, a submenu will display, allowing to export the image into either PNG,JPG,SVG or PDF.

And that's not even the end of it. You can add menu items to cancel, undo, redo.

"menu": [ {
  "class": "export-main",
  "menu": [ {
    "label": "Download",
    "menu": [ "PNG", "JPG", "CSV", "XLSX" ]
  }, {
    "label": "Annotate",
    "action": "draw",
    "menu": [ {
      "class": "export-drawing",
      "menu": [ {
        "label": "Edit",
        "menu": [ "UNDO", "REDO", "CANCEL" ]
      }, {
        "label": "Save",
        "format": "PNG"
      } ]
    } ]
  } ]
} ]

A list of menu item properties

Property Description
action Set to "draw" if you want the item to trigger annotation mode
class Class name applied to the tag
click Function handler invoked upon click on menu item
format A format to export chart/map to upon click (see below for a list of available formats)
icon Icon file (will use chart's pathToImages if the URL is not full)
label Text label to be displayed
menu An array of submenu items
title A title attribute of the link

Available `format` values:

  • JPG
  • PNG
  • SVG
  • CSV
  • JSON
  • PDF
  • XLSX
  • PRINT

Exporting to PDF

When exporting to PDF, you can set and modify the content of the resulting document. I.e. add additional text and/or modify image size, etc.

To do that, you can use menu item's `content` property.

Each item in `content` represents either a text line (string) or an exported image.

To add a text line, simply use a string. It can even be a JavaScript variable or a function that returns a string.

To include exported image, use `image: "reference"`.

Additionally, you can add `fit` property which is an array of pixel dimensions, you want the image to be scaled to fit into.

Here's an example of such export menu item:

{
  "format": "PDF",
  "content": [ "Saved from:", window.location.href, {
    "image": "reference",
    "fit": [ 523.28, 769.89 ] // fit image to A4
  } ]
}

Styling the export menu

The plugin comes with a default CSS file `export.css`. You just need to include it on your page.

Feel free to override any styles defined in it, create your own version and modify as you see fit.

If you choose to modify it, we suggest creating a copy so it does not get overwritten when you update amCharts or plugin.

Plugin API

We explained how you can define custom functions to be executed on click on export menu items.

Those functions can tap into plugin's methods to augment it with some custom functionality.

Here's an example:

menu: [ {
  label: "JPG",
  click: function() {
    this.capture({},function() {
      this.toJPG( {}, function( data ) {
        this.download( data, "image/jpg", "amCharts.jpg" );
      });
    });
  }
} ]

The above will use plugin's internal `capture` method to capture it's current state and `toJPG()`method to export the chart to JPEG format.

Yes, you're right, it's the exact equivalent of just including "JPG" string. The code is here for the explanatory purposes.

Here's a full list of API functions available for your consumption:

Function Parameters Description
toJPG (object) options, (function) callback Prepares a JPEG representation of the chart and passes the binary data to the callback function
toPNG (object) options, (function) callback Prepares a PNG representation of the chart and passes the binary data to the callback function
toSVG (object) options, (function) callback Prepares a SVG representation of the chart and passes the binary data to the callback function
toPDF (object) options, (function) callback Prepares a PDF representation of the chart and passes the binary data to the callback function
toJSON (object) options, (function) callback Prepares a JSON and passes the plain data to the callback function
toCSV (object) options, (function) callback Prepares a CSV and passes the plain data to the callback function
toXLSX (object) options, (function) callback Prepares a XLSX representation of the chart and passes the binary data to the callback function
toBlob (object) options, (function) callback Prepares a BLOB and passes the instance to the callback function
toCanvas (object) options, (function) callback Prepares a Canvas and passes the element to the callback function
toArray (object) options, (function) callback Prepares an Array and passes the data to the callback function

Requirements

This plugin requires at least 3.13 version of JavaScript Charts, JavaScriptStock Chart or JavaScript Maps.

The export will also need relatively recent browsers.

IE10 and up are supported.

Partial support for IE9 will be implemented in the future versions.

IE8 and older are not supported I'm afraid. Hey, it's time to upgrade!

The post Exporting charts and maps as static images, data files or PDF appeared first on amCharts.

Exporting charts and maps: Advanced usage

$
0
0
Unsupported: IE9 and lower are not supported by the export plugin due browser incompatibilities!

Exporting charts to single images or data files might be not enough, there are plenty of other use cases where the export needs to be triggered autonomously or embedded into a company report.

In this article we will guide you through such scenarios and explain how to extend the export plugin to achieve that.

We're going to assume that you already have export running. If you don't, we suggest you go through this tutorial first.

Free-hand export (autonomous)

Imagine you have a monitoring service and you want to inform your administrators about it's activity. In this case you need the possibility to receive the chart imagery without user interaction.

With following adaption you can enable the export plugin but hide it from the user interface and trigger it when ever you need to send the image data to the server.

var chart = AmCharts.makeChart( "chartdiv", {
	"export": {
		"enabled": true,
		"libs": {
			"path": "http://amcharts.com/lib/3/plugins/export/libs/"
		},
		"menu": []
	},
	...
} );

// WAIT UNTIL CHART HAS BEEN RENDERED
chart.addListener( "rendered", function( e ) {

	// WAIT FOR FABRIC
	var interval = setInterval( function() {
		if ( window.fabric ) {
			clearTimeout( interval );

			// CAPTURE CHART
			e.chart.export.capture( {}, function() {

				// SAVE TO JPG
				this.toJPG( {}, function( base64 ) {

					// LOG IMAGE DATA
					console.log( base64 );
				} );
			} );
		}
	}, 100 );

} );

See the Pen #12500 by amCharts (@amcharts) on CodePen.

For demonstration purpose we've added a "link" to open the base64 image in a new tab. Ina real life scenario, you might want to send such data to your server to send an e-mail.

Seamless system reports on the fly

You have running system with some important statistics, probably a handy dashboard which provides your users a quick overview about the current situation. But what if you want to enable your users to download the whole page as a single report file?

You're in luck, because with just few lines of custom code you can create a button which, when clicked, will generate a PDF document with multiple charts and optional a data table in it.

Like in the previous sample we want to enable the export capabilities but hide the menu. We'll pass in an empty menu array to the export setup. In addition we need to save the chart instances for later to be able to collect the imagery and pass them to the PDF layout.

var charts = [];
...
var chart = AmCharts.makeChart( "chartdiv", {
	"export": {
		"enabled": true,
		"libs": {
			"path": "http://amcharts.com/lib/3/plugins/export/libs/"
		},
		"menu": []
	},
	...
} );
charts.push( chart );

After that we need to create a layout which will be used to generate the PDF, it is even possible to create references and use images multiple times. We took advantage of that and created a static layout and simply add the embedded base64 PNG images as references within the images property. You can use that file or start completely from scratch, all available options can be found on the github page of the export plugin. Following is a little snippet of the sample layout to show it's structure.

 

var layout_1 = {
        /*
        ** Array of objects or strings which represents the output
        */
	content: [
		{
			text: "This is a header, using header style",
		}, {
			image: "logo", // reference to the image mapping below
			fit: [595.28,841.89] // fits the image to those dimensions (A4)
		}
	],

	/*
	 ** Mapping object, holds the actual imagery
	 */
	images: {
          logo: "data:image/png;base64, ..."
        }
}

Once everything has been configured and is ready to get exported, we just need to write a function which crawls through all charts to export those to PNG and pass them to the image mapping object of the layout above.

function createReport() {
  var pdf_images = 0;
  var pdf_layout = layout_1; // loaded from another JS file
  for ( chart in charts ) {

    // Capture current state of the chart
    chart.capture( {}, function() {

      // Export to PNG
      this.toPNG( {
        multiplier: 2 // pretend to be lossless

        // Add image to the layout reference
      }, function( data ) {
        pdf_images++;
        pdf_layout.images[ "image_" + pdf_images ] = data;

        // Once all has been processed create the PDF
        if ( pdf_images == AmCharts.charts.length ) {

          // Save as single PDF and offer as download
          this.toPDF( pdf_layout, function( data ) {
            this.download( data, this.defaults.formats.PDF.mimeType, "amcharts.pdf" );
          } );
        }
      } );
    } );
  }
}

See the Pen #12500 by amCharts (@amcharts) on CodePen.

We used the twitter bootstrap dashboard template and modified it a little bit to show you a real use case. We think this might be really interesting for few of you and we hope you have a lot adding this feature.

The post Exporting charts and maps: Advanced usage appeared first on amCharts.


Exporting charts and maps: Quick Intro

$
0
0
Unsupported: IE9 and lower are not supported by the export plugin due browser incompatibilities!

Since you made it to your first chart you probably want to go one step further and offer your users to download those. In this tutorial we will guide you through a few easy steps to get the export functionality working.

First, include the necessary files

First of all you need to include the resources. Since the Version 3.14 of all amCharts products, the export plugin is already included within the download package. In case you don't have it, you can download the plugin separately on the github page or redownload the package from our official download page. Once you have the plugin you only need to include following resources in your <head> tag in your HTML document:

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script src="http://amcharts.com/lib/3/plugins/export/export.js" type="text/javascript"></script>
    <link href="http://amcharts.com/lib/3/plugins/export/export.css" rel="stylesheet" type="text/css">
    <script type="text/javascript">
      ...
    </script>
  </head>
  <body>
    <div id="chartid"></div>
  </body>
</html>

Enable the plugin

When the resources have been included, the only missing step is to enable the plugin itself. The plugin shows an easy touch menu button on the top right corner of your chart and offers everything it has to offer - that's it. Ensure the path to the dependencies (libs) points to the export "libs" folder.

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script src="http://amcharts.com/lib/3/plugins/export/export.js" type="text/javascript"></script>
    <link href="http://amcharts.com/lib/3/plugins/export/export.css" rel="stylesheet" type="text/css">
    <script type="text/javascript">
      var chart = AmCharts.makeChart( "chartdiv", {
        ...
        "export": {
          "enabled": true,
          "libs": {
            "path": "http://amcharts.com/lib/3/plugins/export/libs/"
          }
        }
      } );
    </script>
  </head>
  <body>
    <div id="chartid"></div>
  </body>
</html>

 

See the Pen #12500 by amCharts (@amcharts) on CodePen.

Tune it to your needs

In case you want to cherry-pick, which options to enable, you can easily modify the menu items be modifying the menu array. The array elements can be strings defining export format (such as "JPG" or "SVG") or an action (i.e. "DRAW"):

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script src="http://amcharts.com/lib/3/plugins/export/export.js" type="text/javascript"></script>
    <link href="http://amcharts.com/lib/3/plugins/export/export.css" rel="stylesheet" type="text/css">
    <script type="text/javascript">
      var chart = AmCharts.makeChart( "chartdiv", {
        ...
        "export": {
          "enabled": true,
          "libs": {
            "path": "http://amcharts.com/lib/3/plugins/export/libs/"
          },
          "menu": [{
            "format": "JPG",
            "label": "Save as JPG",
            "title": "Export chart to JPG",
          }, "PNG"]
        }
      } );
    </script>
  </head>
  <body>
    <div id="chartid"></div>
  </body>
</html>

See the Pen #12500 by amCharts (@amcharts) on CodePen.

Conclusion

With just few minor extra steps you can enable the export feature on your charts, which your users can use to save those charts as images or extract it's data to the local file system with no server side-coding whatsoever. If you want to go even further we wrote another tutorial which describes how to export silently with no user interactions, which can be used for email reports or combine multiple chart instances in one PDF to create company reports.

The post Exporting charts and maps: Quick Intro appeared first on amCharts.

Using Data Loader plugin to load external data in CSV or JSON formats

$
0
0

Description

By default all amCharts libraries accept data in JSON format. It needs to be there when the web page loads, defined in-line or loaded via custom code.

This plugin introduces a native wrapper that enables automatic loading of data from external data data sources in CSV and JSON formats.

Most of the times you will just need to provide a URL of the external data source - static file or dynamically generated - and it will do the rest.

Important notice

Due to security measures implemented in most of the browsers, the external data loader will work only when the page with the chart or map is loaded via web server.

So, any of the examples loaded locally (file:///) will not work.

The page needs to be loaded via web server (http://) in order to work properly.

Loading data from another domain than the web page is loaded is possible but is a subject for Access-Control-Allow-Origin policies defined by the web server you are loading data from.

For more about loading data across domains use the following thread:
http://stackoverflow.com/questions/1653308/access-control-allow-origin-multiple-origin-domains

Usage

1) Include the minified version of file of this plugin. I.e.:

<script src="amcharts/plugins/dataloader/dataloader.min.js" type="text/javascript"></script>

(this needs to go after all the other amCharts includes)

2) Add data source properties to your chart configuration.

Regular (Serial, Pie, etc.) charts:

AmCharts.makeChart( "chartdiv", {
  ...,
  "dataLoader": {
    "url": "data.json",
    "format": "json"
  }
} );

Stock chart:

AmCharts.makeChart( "chartdiv", {
  ...,
  "dataSets": [{
    ...,
    "dataLoader": {
      "url": "data.csv"
      "format": "csv",
      "delimiter": ",",       // column separator
      "useColumnNames": true, // use first row for column names
      "skip": 1               // skip header row
    }
  }]
} );

That's it. The plugin will make sure the files are loaded and dataProvider is populated with their content before the chart is built.

Some formats, like CSV, will require additional parameters needed to parse the data, such as "separator".

If the "format" is omitted, the plugin will assume JSON.

Complete list of available dataLoader settings

Property Default Description
async true If set to false (not recommended) everything will wait until data is fully loaded
complete Callback function to execute when loader is done
delimiter , [CSV only] a delimiter for columns (use \t for tab delimiters)
error Callback function to execute if file load fails
format json Type of data: json, csv
load Callback function to execute when file is successfully loaded (might be invoked multiple times)
noStyles false If set to true no styles will be applied to "Data loading" curtain
postProcess If set to function reference, that function will be called to "post-process" loaded data before passing it on to chart
showErrors true Show loading errors in a chart curtain
showCurtain true Show curtain over the chart area when loading data
reload 0 Reload data every X seconds
reverse false [CSV only] add data points in revers order
skip 0 [CSV only] skip X first rows in data (includes first row if useColumnNames is used)
timestamp false Add current timestamp to data URLs (to avoid caching)
useColumnNames false [CSV only] Use first row in data as column names when parsing

Using in JavaScript Stock Chart

In JavaScript Stock Chart it works exactly the same as in other chart types, with the exception that dataLoader is set as a property to the data set definition. I.e.:

var chart = AmCharts.makeChart("chartdiv", {
  "type": "stock",
  ...
  "dataSets": [{
    "title": "MSFT",
      "fieldMappings": [{
        "fromField": "Open",
        "toField": "open"
      }, {
        "fromField": "High",
        "toField": "high"
      }, {
        "fromField": "Low",
        "toField": "low"
      }, {
        "fromField": "Close",
        "toField": "close"
      }, {
        "fromField": "Volume",
        "toField": "volume"
      }],
      "compared": false,
      "categoryField": "Date",
      "dataLoader": {
        "url": "data/MSFT.csv",
        "format": "csv",
        "showCurtain": true,
        "showErrors": true,
        "async": true,
        "reverse": true,
        "delimiter": ",",
        "useColumnNames": true
      }
    }
  }]
});

Can I also load event data the same way?

Sure. You just add a eventDataLoader object to your data set. All the same settings apply.

Translating into other languages

Depending on configuration options the plugin will display a small number of text prompts, like 'Data loading...'.

Plugin will try matching chart's language property and display text prompts in a corresponding language. For that the plugin needs to have the translations.

Some of the plugin translations are in lang subdirectory. Simply include the one you need.

If there is no translation to your language readily available, just grab en.js, copy it and translate.

The structure is simple:

'The phrase in English': 'Translation'

The phrase in English must be left intact.

When you're done, you can include your language as a JavaScript file.

P.S. send us your translation so we can include it for the benefits of other users. Thanks!

Requirements

This plugin requires at least 3.13 version of JavaScript Charts, JavaScript Stock Chart or JavaScript Maps.

The post Using Data Loader plugin to load external data in CSV or JSON formats appeared first on amCharts.

Automate report generation using PhantomJS

$
0
0

Intro

You are already using amCharts libraries to visualize your data to your users on your website, intranet, CMS, even mobile applications.

But what about the situations when you want to generate the reports to your users. Automatically. On server-side. Without any human interaction whatsoever?

That's where server-side browsers come in.

Introducing PhantomJS - the crown jewel of such software. PhantomJS is a free, headless browser, that can generate an image or a PDF out of any web page, including dynamic content, such as charts and maps.

It's available for virtually any platform - Windows, Linux, Max OS, you name it. And it's using the same rendering engine as the Chrome and Safari browsers, so you know your code is compatible.

Download and Install

The installation depends on the platform.

You can download PhantomJS binaries for Windows or Mac OS, or source code, to compile on Linux directly from their Downloads page:

http://phantomjs.org/download.html

There are no official binaries available for Linux builds, yet. Individual Linux distributions like RedHat and Ubuntu might have their own binary packages available for install. Make sure you verify if maybe a ready-made package is already available for your Linux flavor.

Alternatively, you can follow PhantomJS own tutorial on how to compile your own binaries out of the source code:

http://phantomjs.org/build.html

Verify PhantomJS Install

Try running this command in your shell/command prompt:

phantomjs --version

Get PhantomJS version info? Great. Let's move on.

Getting Started

PhantomJS works by executing its binary in the shell or command prompt. It can be typed in by admin user, invoked from some script or scheduled job. (CRON)

To run PhantomJS, it needs a config file, which is basically a JavaScript code. You specify as a first parameter to phantomjs binary. I.e.:

phantomjs report.js

The PhantomJS quick intro tutorial does a good job of explaining the basics. Make sure you go through it before proceeding with this article. We're not going to repeat that here:

http://phantomjs.org/quick-start.html

Generating a Report

Now that we know how PhantomJS works, let's build a config script that:

  1. Accepts the URL of the web page to generate as a PDF;
  2. Requests that page and produces the output, which is then saved to the some directory.

Here we have a report-like test page, with several charts we're going to be using as a lab test rat.

See the Pen Multiple charts on the page (PhantomJS article asset) by amCharts (@amcharts) on CodePen.

Let's build a PhantomJS script that will grab that (or any other) page:

var page = require( 'webpage' ).create();
page.open( 'http://s.codepen.io/amcharts/debug/cd2e8ce27e3a96f43bb79d5d23722d11', function( status ) {
  console.log( "Status: " + status );
  if ( status === "success" ) {
    page.render( 'example.pdf' );
  }
  phantom.exit();
} );

Now if I run this command, I get a nice copy of the our test page as an example.pdf:

phantomjs report.js

Let's enhance our script to accept two parameters: a URL of the web page to grab and output path/filename.

/**
 * Create page object
 */
var page = require( 'webpage' ).create(),
    system = require('system');

/**
 * Check for required parameters
 */
if ( system.args.length < 3 ) {
  console.log( 'Usage: report.js <some URL> <output path/filename>' );
  phantom.exit();
}

/**
 * Grab the page and output it to specified target
 */
page.open( system.args[ 1 ], function( status ) {
  console.log( "Status: " + status );

  /**
   * Output the result
   */
  if ( status === "success" ) {
    page.render( system.args[ 2 ] );
  }

  phantom.exit();
} );

By the way, PhantomJS will recognize the output format from the extension of the output file name, so if you will specify something like report.png, it will product a nice PNG image. Cool, huh?

So, now to produce PDF of the page, we're going to use this line:

phantomjs report.js http://s.codepen.io/amcharts/debug/cd2e8ce27e3a96f43bb report.pdf

And, when we're in the mood for some PNG:

phantomjs report.js http://s.codepen.io/amcharts/debug/cd2e8ce27e3a96f43bb report.png
And… voila!

And… voila!

Dealing with Chart Animations

So far the script we were using did a good job of producing the output. There's one caveat, though: the export kicks in as soon as the page loads. Which means that if your charts are set up to play animations, they will be exported before animations finish, resulting in incomplete appearance.

Oh noes!

Oh noes!

We could delay our rendering operation in PhantomJS script by a few seconds. However, we're not going to do that since we don't want our exports to take that long. Instead we're going to disable all animations before they have a chance to execute.

AmCharts.addInitHandler is the perfect place for that. We're going to couple it with PhantomJS page.onResourceReceived event to add amCharts-wide overrides to reset animation settings.

/**
 * Create page object
 */
var page = require( 'webpage' ).create(),
  system = require( 'system' );

/**
 * Check for required parameters
 */
if ( system.args.length < 3 ) {
  console.log( 'Usage: report.js <some URL> <output path/filename>' );
  phantom.exit();
}

/**
 * Check when amCharts main library is loaded. Add overrides then.
 */
page.onResourceReceived = function() {
  if ( arguments[ 0 ].url.match( /(amcharts\.js)|(ammap\.js)/ ) ) {
    page.evaluate( function() {
      setTimeout( function() {
        if ( AmCharts === undefined )
          return;
        AmCharts.addInitHandler( function( chart ) {
          if ( chart.type == "stock" )
            chart.panelsSettings.startDuration = 0;
          else if ( chart.type == "map" )
            chart.zoomDuration = 0;
          else
            chart.startDuration = 0;
        } );
      } );
    }, 100 );
  }
}

/**
 * Grab the page and output it to specified target
 */
page.open( system.args[ 1 ], function( status ) {
  console.log( "Status: " + status );
  if ( status === "success" ) {
    page.render( system.args[ 2 ] );
  }
  phantom.exit();
} );

Conclusion

PhantomJS can be powerful server-side automation tool. Remember, anything you can do with JavaScript, you can do with PhantomJS.

Here's more information about it:

http://phantomjs.org/page-automation.html

Please note, that PhantomJS JavaScript code runs in it's own scope. You can't reference web page objects and code directly from PhantomJS code and vice versa.

If you would need to execute some code in the scope of the web page you are requesting, you need to use PhantomJS's page.render function:

http://phantomjs.org/api/webpage/method/evaluate.html

Assets

Download the final PhantomJS configuration script used in this article:

amcharts_phantomjs.zip

The post Automate report generation using PhantomJS appeared first on amCharts.

Use amCharts to visualize Google Analytics data

$
0
0

Intro

Google exposes data from its Analytics service using a number of various APIs.

CORE REPORTING API (Create custom reports by querying for dimensions and metrics)
MULTI-CHANNEL FUNNELS REPORTING API (Access attribution and conversion path data for your users)
REAL TIME REPORTING API (Access activity occurring on your property right now)
EMBED API (Embed dashboards on a 3rd-party site in minutes)
METADATA API (Access the list of API dimensions and metrics and attributes)

We’re going to to look into the most basic - CORE REPORTING API - which is used to extract analytics data for your website usage.

NOTE: you can download the files created in this tutorial using link at the bottom.

Setting up Google Analytics API

Before you can extract data from your Analytics account, you will need to set up an application and API access to it.

Since our main aim is to display Analytics data to users who don’t necessarily have access to our GA accounts, we’ll need the server-to-server authentication and a server-side script to act as a proxy between the user and Google API.

To use that you’ll need to set up a “Service account” in your Google Console.

Follow this excellent tutorial to do so:

Hello Analytics API: PHP quickstart for service accounts

Creating a GA service account

Creating a GA service account

Once you create the Service account, you’ll be offered to save a P12 file. Do it. You’ll need it to authenticate your PHP script’s access to Analytics.

Also note the Email address auto-generated for your application. You’ll need it to set up authentication as well.

Service account information

Service account information

Using PHP to extract Google Analytics data

Prerequisites

Google has provided a PHP library to access their API services. Download or better yet check it out directly from their GitHub repository:

https://github.com/google/google-api-php-client

We’ll also be using slightly modified version of the sample PHP script shown in this Google tutorial:

Hello Analytics API: PHP quickstart for service accounts

Authorizing

As mentioned earlier, you’ll need three things to authorize your PHP script for access to your Analytics data:

  • Service account email
  • Authorization file
  • Analytics profile ID

We took the code from Google tutorial and modified it to be slightly more universal:

<?php
/**
 * Load Google API library
 */
require_once 'google-api-php-client/src/Google/autoload.php';

/**
 * Start session to store auth data
 */
session_start();

/**
 * Set Google service account details
 */
$google_account = array(
  'email'   => '********@developer.gserviceaccount.com',
  'key'     => file_get_contents( '********.p12' ),
  'profile' => '85639843'
);

/**
 * Get Analytics API object
 */
function getService( $service_account_email, $key ) {
  // Creates and returns the Analytics service object.

  // Load the Google API PHP Client Library.
  require_once 'google-api-php-client/src/Google/autoload.php';

  // Create and configure a new client object.
  $client = new Google_Client();
  $client->setApplicationName( 'Google Analytics Dashboard' );
  $analytics = new Google_Service_Analytics( $client );

  // Read the generated client_secrets.p12 key.
  $cred = new Google_Auth_AssertionCredentials(
      $service_account_email,
      array( Google_Service_Analytics::ANALYTICS_READONLY ),
      $key
  );
  $client->setAssertionCredentials( $cred );
  if( $client->getAuth()->isAccessTokenExpired() ) {
    $client->getAuth()->refreshTokenWithAssertion( $cred );
  }

  return $analytics;
}

/**
 * Get Analytics API instance
 */
$analytics = getService(
  $google_account[ 'email' ],
  $google_account[ 'key' ]
);

/**
 * Query the Analytics data
 */
$results = $analytics->data_ga->get(
  'ga:' . $google_account[ 'profile' ],
  '30daysAgo',
  'today',
  'ga:sessions',
  array(
    'dimensions'  => 'ga:country',
    'sort'        => '-ga:sessions',
    'max-results' => 20
  ) );
$rows = $results->getRows();
var_dump($rows);

When you run this file, if you have correctly configured your Google API credentials, added Service account email to your Analytics properties, you should see the PHP script print out the number of sessions your web property received in the past 7 days.

array (size=1)
  0 => 
    array (size=1)
      0 => string '7279' (length=4)

Authorization works!

Querying the data

Data from Analytics is extracted using “queries”. In the previous example we used query “ga:sessions” to extract a single number of visitor sessions.

Now let’s do something more interesting. Let’s extract number of sessions from the last 30 days per country.

We’ll replace our query’s start date to “30daysAgo”.

Will leave metric at “ga:sessions”.

We’ll also add additional parameters: dimension (country), sort order, and number of results to return.

$results = $analytics->data_ga->get(
  'ga:' . $profile,
  '30daysAgo',
  'today',
  'ga:sessions',
  array(
    'dimensions'  => 'ga:country',
    'sort'        => '-ga:sessions',
    'max-results' => 10
  ) );
$rows = $results->getRows();
var_dump($rows);

You’ll notice we have introduced the 5th parameter to the get() method call, which is an associative array of optional parameters.

The Google Analytics parameter value usually is prefixed with a “ga:” prefix.

The minus sign in front of “ga:sessions” means I want it to order in ascending order.

Now, when you run the above, you’ll get something like this:

array (size=10)
  0 => 
    array (size=2)
      0 => string 'United States' (length=13)
      1 => string '4858' (length=4)
  1 => 
    array (size=2)
      0 => string 'India' (length=5)
      1 => string '4020' (length=4)
  2 => 
    array (size=2)
      0 => string 'France' (length=6)
      1 => string '1305' (length=4)
  3 => 
    array (size=2)
      0 => string 'Russia' (length=6)
      1 => string '1203' (length=4)
  4 => 
    array (size=2)
      0 => string 'China' (length=5)
      1 => string '1170' (length=4)
...

Neat, huh?

Using Query Explorer to construct and test API queries

Google has provided a powerful tool, that you can use to construct and test API queries, called Query Explorer.

As a side effect of using Query Explorer you can also find out the profile ID of your Analytics property.

Charting extracted data

Now that we have the data, we can go about plotting it with the chart.

Formatting data in JSON

While the data we extracted (session per country) might look OKish on screen, it can’t be used directly by chart. Let’s re-format it to JSON - a format much more suitable for charts.

/**
 * Format and output data as JSON
 */
$data = array();
foreach( $rows as $row ) {
  $data[] = array(
    'country'   => $row[0],
    'sessions'  => $row[1]
  );
}

echo json_encode( $data );

Now that produces a perfect and valid, object-oriented JSON:

[ {
  "country": "United States",
  "sessions": "4867"
}, {
  "country": "India",
  "sessions": "4029"
}, {
  "country": "France",
  "sessions": "1311"
}, {
  "country": "Russia",
  "sessions": "1203"
}, {
  "country": "China",
  "sessions": "1171"
}, {
  "country": "Germany",
  "sessions": "1151"
}, {
  "country": "South Korea",
  "sessions": "1096"
}, {
  "country": "United Kingdom",
  "sessions": "1087"
}, {
  "country": "Japan",
  "sessions": "1064"
}, {
  "country": "Brazil",
  "sessions": "931"
} ]

We’re done with the data.php file for now.

Using the data in chart

We’re going to use amChart’s plugin Data Loader, to automatically load external data:

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>amCharts - Google Analytics example</title>
    <script src="http://www.amcharts.com/lib/3/amcharts.js"></script>
    <script src="http://www.amcharts.com/lib/3/serial.js"></script>
    <script src="http://www.amcharts.com/lib/3/plugins/dataloader/dataloader.min.js"></script>
    <style>
    body, html {
      font-family: Verdana;
      font-size: 12px;
    }
    #chartdiv {
      width: 100%;
      height: 400px;
    }
    </style>
    <script>
    var chart = AmCharts.makeChart("chartdiv", {
     "type": "serial",
     "dataLoader": {
        "url": "data.php",
        "format": "json"
     },
     "categoryField": "country",
     "categoryAxis": {
       "gridAlpha": 0.07,
       "title": "Country"
     },
     "valueAxes": [{
       "stackType": "regular",
       "gridAlpha": 0.07,
       "title": "Sessions"
     }],
     "graphs": [{
       "type": "column",
       "title": "Sessions",
       "valueField": "sessions",
       "lineAlpha": 0,
       "fillAlphas": 0.6
     }],
    });
    </script>
  </head>

  <body>
    <div id="chartdiv"></div>
  </body>

</html>

This produces a nice result:

A chart generated from GA data

A chart generated from GA data

Combining multiple metrics in a single query

Let’s say you want to display a number of metrics in the same dashboard. For example, along sessions you could want to plot number of unique users and page views as well. Naturally, it would be very inefficient to create separate queries for each of those metrics.

Luckily, Analytics API allows to specify several metrics in the same request. You just need to separate them by comma:

/**
 * Query the Analytics data
 */
$results = $analytics->data_ga->get(
  'ga:' . $google_account[ 'profile' ],
  '30daysAgo',
  'today',
  'ga:sessions,ga:users,ga:pageviews',
  array(
    'dimensions'  => 'ga:country',
    'sort'        => '-ga:sessions',
    'max-results' => 10
  ) );
$rows = $results->getRows();

/**
 * Format and output data as JSON
 */
$data = array();
foreach( $rows as $row ) {
  $data[] = array(
    'country'   => $row[0],
    'sessions'  => $row[1],
    'users'     => $row[2],
    'pageviews' => $row[3]
  );
}

echo json_encode( $data );

Now let’s update our chart code to display all that new data:

var chart = AmCharts.makeChart( "chartdiv", {
  "type": "serial",
  "dataLoader": {
    "url": "data.php",
    "format": "json"
  },
  "creditsPosition": "top-right",
  "categoryField": "country",
  "categoryAxis": {
    "gridAlpha": 0.07,
    "gridPosition": "start",
    "tickPosition": "start",
    "title": "Country"
  },
  "valueAxes": [ {
    "id": "v1",
    "gridAlpha": 0.07,
    "title": "Users/Sessions"
  }, {
    "id": "v2",
    "gridAlpha": 0,
    "position": "right",
    "title": "Page views"
  } ],
  "graphs": [ {
    "type": "column",
    "title": "Sessions",
    "valueField": "sessions",
    "lineAlpha": 0,
    "fillAlphas": 0.6
  }, {
    "type": "column",
    "title": "Users",
    "valueField": "users",
    "lineAlpha": 0,
    "fillAlphas": 0.6
  }, {
    "type": "line",
    "valueAxis": "v2",
    "title": "Page views",
    "valueField": "pageviews",
    "lineThickness": 2,
    "bullet": "round"
  } ],
  "legend": {}
} );

And voila:

Combined data from GA using single query

Combined data from GA using single query

Files used in this article

Download the final files of the files produced in this article:
amcharts_google_analytics_files.zip

The post Use amCharts to visualize Google Analytics data appeared first on amCharts.

Exporting charts and maps: PDF with multiple charts and related info

$
0
0

Intro

If you are looking on how to automatically generate PDF reports, you should probably explore some server-side options, like PhantomJS. We have a handy tutorial ready about the latter here.

However, sometimes, you just need to export a chart or two, along with some additional info on-demand, triggered by the user. In those cases you can use our own Export plugin.

This article provides instructions on how to set up your export to do just that.

If you're not a big fan of reading a lot of text, jump to the bottom of this article. It contains a link to a full working chart that we are going to build during the course of the tutorial.

Prerequisites

We assume that you are familiar with Export plugin. If you're not, we suggest you start here.

For any of the below technique to work, Export plugin must be loaded on the web page. Each chart to be exported should also have "export" option enabled, i.e. contain Export plugin configuration block:

"export": {
  "enabled": true,
  "menu": []
}

Empty "menu" array means the plugin is active, but it will not show its export button.

Test report

Let's say we have something like this as a report page:

An HTML-based report sample page, we're going to export to PDF

An HTML-based report sample page, we're going to export to PDF

When user clicks "Export PDF", I want something similar to be dumped into a PDF, which then user can save on his or her computer.

Say, the button will execute a custom function:

function exportReport() {
  console.log("Starting export...");
}

Live version.

We're going to continue building up this function, placing the code that does actual export in there.
Step #1: Exporting the charts to images
Since PDF can't contain dynamic content like JavaScript, we'll need to grab each and every chart we want to export as a bitmap image representation of their current states.

We're going to be using Export plugin's "toPNG()" function.

One thing to note is that "toPNG()" function is asynchronous. Meaning that we will need their completion handler functions to grab the output as well as check the total number of exported charts, so that we know we have all of them and can move on to the next step.

Here's how this might look code-wise:

function exportReport() {

  // So that we know export was started
  console.log("Starting export...");

  // Define IDs of the charts we want to include in the report
  var ids = ["chartdiv1", "chartdiv2", "chartdiv3", "chartdiv4"];

  // Collect actual chart objects out of the AmCharts.charts array
  var charts = {}
  var charts_remaining = ids.length;
  for (var i = 0; i < ids.length; i++) {
    for (var x = 0; x < AmCharts.charts.length; x++) {
      if (AmCharts.charts[x].div.id == ids[i])
        charts[ids[i]] = AmCharts.charts[x];
    }
  }

  // Trigger export of each chart
  for (var x in charts) {
    if (charts.hasOwnProperty(x)) {
      var chart = charts[x];
      chart["export"].capture({}, function() {
        this.toPNG({}, function(data) {

          // Save chart data into chart object itself
          this.setup.chart.exportedImage = data;

          // Reduce the remaining counter
          charts_remaining--;

          // Check if we got all of the charts
          if (charts_remaining == 0) {
            // Yup, we got all of them
            // Let's proceed to putting PDF together
            generatePDF();
          }

        });
      });
    }
  }

  function generatePDF() {

    // Log
    console.log("Generating PDF...");

  }
}

Once this run, we will have all four of our chart objects, in a neat "charts" object, with their static bitmap representations stored in their respective "exportedImage" properties.

For the sake of structural clarity, we will declare a new local function "generatePDF()" that will be executed once our remaining charts counter hits zero.

Step #2: Putting the PDF together

Now that we have all of our charts as images, we might start layouting a PDF. Once all of the charts are exported to images, our code will execute "generatePDF" function, which will do the grunt work.

Export plugin uses an excellent library - pdfmake. It allows adding various objects into a "layout" object, which can then be rendered into a PDF document.

Complete information of what can go into a pdfmake layout is here.

We're going to be using just a few of the available layout and formatting options. Use the link above to find out how much more you can cram into a PDF using this library.

OK, so for starters we initialize an empty layout object. The actual content objects that goe into PDF is contained in layout's "content" property:

var layout = {
  "content": []
}

Now let's start adding actual content objects.

Adding text

The most basic object is text. Let's add a title and intro text:

// Let's add a custom title
layout.content.push({
  "text": "Lorem ipsum dolor sit amet, consectetur adipiscing",
  "fontSize": 15
});

// Now let's grab actual content from our 

intro tag layout.content.push({ "text": document.getElementById("intro").innerHTML; });

Now, if I exported PDF as it is, I'd get a document that would look something like this:

A PDF with a little bit of text

A PDF with a little bit of text

Adding images

That's a good start. Now let's add our first chart.

We're going to use image type object in out layout:

layout.content.push({
  "image": charts["chartdiv1"].exportedImage,
  "fit": [ 523, 300 ]
});

Notice the "fit" parameter. It's a special pdfmake parameter telling it to downsize the image to 523x300 pixels if it does not fit.

OK, so here's what we would get now:

A PDF with text and an image of a chart

A PDF with text and an image of a chart

Our report is really coming together.

Adding tables

pdfmake allows adding tables to PDF as well:

layout.content.push({
  "table": {
    // headers are automatically repeated if the table spans over multiple pages
    // you can declare how many rows should be treated as headers
    "headerRows": 1,
    "widths": ["16%", "16%", "16%", "16%", "16%", "*"],
    "body": [
      ["USA", "UK", "Canada", "Japan", "France", "Brazil"],
      ["5000", "4500", "5100", "1500", "9600", "2500"],
      ["5000", "4500", "5100", "1500", "9600", "2500"],
      ["5000", "4500", "5100", "1500", "9600", "2500"]
    ]
  }
});

Organizing information into columns

Now, let's put our two other charts side by side. We'll need to put those into columns.

layout.content.push({
  "columns": [{
    "width": "50%",
    "image": charts["chartdiv2"].exportedImage,
    "fit": [250, 300]
  }, {
    "width": "50%",
    "image": charts["chartdiv3"].exportedImage,
    "fit": [250, 300]
  }]
});

Each column is an array which can hold other objects. Just like the main layout file.

Please refer to the pdfmake documentation for description of "width".

We'll use columns to add our last chart and text duo as well:

layout.content.push({
  "columns": [{
    "width": "25%",
    "image": charts["chartdiv4"].exportedImage,
    "fit": [125, 300]
  }, {
    "width": "*",
    "stack": [
      document.getElementById("note1").innerHTML,
      "\n\n",
      document.getElementById("note2").innerHTML
    ]
  }],
  "columnGap": 10
});

And here we go:

Final exported PDF

Final exported PDF

Conclusion

The final PDF document could use some styling, like borders and margins around paragraphs. We'll leave you to pdfmake documentation to apply those.

The final working example of the above report can be found here.

If you have questions, drop as a line on contact@amcharts.com.

The post Exporting charts and maps: PDF with multiple charts and related info appeared first on amCharts.

Adding event listeners within chart config

$
0
0

If you are creating chart using AmCharts.makeChart(divId, config) method, instead of using chart.addListener method, a much better approach would be adding listeners directly to chart config. This is done using listeners property of a AmChart or ChartScrollbar or ChartCursor (any object which has events). listeners property accepts array of objects each of them must have event and method properties, like:

   "type": "serial",
   "listeners": [{
      "event": "rendered",
      "method": handleRender
      }, {
      "event": "zoomed",
      "method": handleZoom
   }],
   // rest of config

This way is better because you will be sure the listener will be added before chart is build for the first time, as if the page is fully loaded, makeChart can be completed and events like init, rendered and similar fired even before you add listeners using chart.addListener method.

The post Adding event listeners within chart config appeared first on amCharts.

Accessible charts


Making charts and maps responsive

$
0
0

Starting with version 3.13 amCharts has introduced a plugin which allows transparently enabling responsive features of the charts and maps.

Compatible with all amCharts products – JavaScript Charts, JavaScript Stock Chart and JavaScript Maps – this plugin dynamically scales-down and -up chart’s visual features to best suit available viewport.

This article deals on how to enable and tweak the plugin behavior.

What “amCharts Responsive” does?

“Responsive” chart or map will modify it’s features dynamically (even as you resize the container) based on the available area. For example: a full fledged line chart with legend guides, labels, titles and other elements will be displayed in all its glory if container is big enough.

Responsive serial chart

If the container shrinks (i.e. you resize a browser window or view it on an iPad), it starts “compacting” the chart. First the legend is removed. Shrink it even further, axis titles are removed and its value labels are moved inside the plot area. Going even smaller, bullets, labels gone. All the way to the sparkline representation of the chart.

Plugin brings a universal set of pre-defined rules that you can use to instantly enable responsiveness. Those are custom-tailored for each chart/map type and
will probably fit your requirements out-of the-box. All you need to do is to enable “responsive” plugin for your chart instance. You can modify those defaults rules, or make your own list. The plugin allows that. (see further down this file for instructions)

Example?

Here’s a live example that will help you get a feeling of what responsive charts are all about.

Where do I get it?

Starting with v3.13, the plugin is bundled with all amCharts products. (Please note that the plugin will not work on any earlier versions of amCharts products)

You can also get the latest build directly from its GitHub repository:

https://github.com/amcharts/responsive

Enabling responsive features

1. Include the minified version of file of this plugin. I.e.:

<script src="amcharts/plugins/responsive/responsive.min.js" type="text/javascript"></script>

(this needs to go after all the other amCharts includes)

2. Add the following setting to your chart configuration:

AmCharts.makeChart( "chartdiv", {
  ...,
  "responsive": {
    "enabled": true
  }
} );

Or if you are using non-JSON setup:

chart.responsive = {
  "enabled": true
};

That’s it.

Advanced use

Rules

You can modify (or completely overwrite) the default responsive rules used by the plugin.

A plugin works by checking chart area dimensions after each resize. (or after initial build / mobile device orientation change) It then overrides particular settings suitable for these particular dimensions.

Override rules are implemented by defining chart rules, or just “rules” moving forward. Each rule has two things:

1. Dimension conditions;
2. Overrides. (a set of properties to override for this particular rule)

A rule is an object, for example:

{
  "minWidth": 200,
  "maxWidth": 400,
  "maxHeight": 400,
  "minHeight": 200,
  "overrides": {
    "precision": 2,
    "legend": {
      "enabled": false
    },
    "valueAxes": {
      "inside": true
    }
  }
}

The above rule will be applicable to a chart that is between 200px and 400px in width and height.

It is not necessary to add all of the dimensional properties. You just neat at least one.

So for example to make the rule apply to all charts with width 400px or lower, you would do something like this:

{
  "maxWidth": 400,
  "overrides": {
    "precision": 2,
    "legend": {
      "enabled": false
    },
    "valueAxes": {
      "inside": true
    }
  }
}

Please note that there are several other conditional properties besides the ones that deal with chart’s dimensions:

  • rotate (true|false) – set this property if you want to make this rule applicable to rotated serial chart only (i.e. bar chart)
  • legendPosition (“top|bottom|left|right”) – set this property if you want the rule applied only when the chart legend is set to particular position. Please note that this does not check whether the legend is enabled at all.

Now, on to explaining “overrides”. It’s an object, that contains properties that you want to override the chart’s initial ones with.

It can be either simple properties, like fontSize or “precision”, or complex types like object, or array.

To override a property of a child object, such as “legend”, you would simply go with JSON representation of the properties you need to override. I.e.:

"legend": {
  "enabled": false
}

This will look for a legend property in chart object, then change it’s enabled property to false.

Overriding arrays of objects

Some objects in charts are collected in arrays, i.e. graphs, valueAxes, etc.

There are some ways to override their properties as well.

To override properties for ALL objects in the array, you would provide an override instruction as an object. I.e.:

"graphs": {
  "bullet": "round",
  "lineThickness": 5
}

The above will add a round bullet and set line thickness to all of the graphs on the chart.

You can also target individual items in the array. There are two ways to do that:

a) Use id property;
b) Apply using the same index.

To individually apply property overrides, you will need to supply override instructions as an array:

"graphs": [
  {
    "id": "g1",
    "bullet": "round",
    "lineThickness": 5
  }
]

The above will apply the same properties for the graph with an id of “g1” only. It will not touch the rest of the graphs.

Please note that original graph definition in your chart settings needs to have the id property set so this plugin can target it.

Or you can omit the id and just apply overrides in the same order as you have them defined. I.e.:

"graphs": [
  {
    "bullet": "round"
  },
  {
    "bullet": "square"
  }
]

The above will apply round bullets to the first defined graph, and square bullets to the second graph.

Chaining multiple rules

The cool pat is that you can daisy-chain the override rules, much like in CSS.

The plugin will examine all of the rules if their dimensional conditions match current chart condition and will apply their overrides in the same order they are defined.

Consider this rule set:

"responsive": {
  "enabled": true,
  "rules": [
    // at 400px wide, we hide legend
    {
      "maxWidth": 400,
      "overrides": {
        "legend": {
          "enabled": false
        }
      }
    },

    // at 300px or less, we move value axis labels inside plot area
    // the legend is still hidden because the above rule is still applicable
    {
      "maxWidth": 300,
      "overrides": {
        "valueAxes": {
          "inside": true
        }
      }
    },

    // at 200 px we hide value axis labels altogether
    {
      "maxWidth": 200,
      "overrides": {
        "valueAxes": {
          "labelsEnabled": false
        }
      }
    }

  ]
}

In case several rules modify the same property, the last one will always “win”.

Combining custom rules with pre-defined ones

The plugin will combine your custom rules with pre-defined ones automatically.

In case you want to go pure and set only your own responsive rules, you can set property addDefaultRules to false. I.e.:

"responsive": {
  "enabled": true,
  "addDefaultRules": false,
  "rules": [
    {
      "maxWidth": 400,
      "overrides": {
        "legend": {
          "enabled": false
        }
      }
    }
  ]
}

When your custom rules are combined with pre-defined ones, yours are appended at the end of the list. This means that your rules will always have the “last word”.

The post Making charts and maps responsive appeared first on amCharts.

Applying SVG filters on charts and maps

$
0
0

Since 3.13.0 it is possible to define SVG-Filter natively through the chart setup, without touching the actual SVG or messing with the chart events. We have spend a while to think about a way how to provide you the best and easiest solution to define those SVG definitions – and guess what, the simple JavaScript object made it.

You only need to define the defs in your chart setup and enable addClassNames to apply those definitions to your chart elements through CSS, that’s it.

Showcase & Awesomeness

See the Pen Using SVG Filters with amCharts by amCharts (@amcharts) on CodePen.

Support & Performance

Depends how many chart elements or total area you are pushing through the filter it might take a while until the final result is being shown but it’s totally worth it and your user won’t take their eyes off the charts.
The cross browser support isn’t bad at all just the Internet Explorer support those since IE10. Don’t abandon your mobile user, you might want to lower the complexity of your filter because the higher the processing time the higher the battery consumption. Last but not least check if all target browser render those effects properly, not very browser vendor implemented the filter correctly.

How it works

We have added a simple recursive method which gives you all the freedom you need by defining those definitions/filter and be completly independent from our side in case there are some bleeding edge features you just want to add but first let’s dive into the definition.
Assuming you have already addClassNames enabled and got your defs ready to get defined, let’s start with a simple blur effect:

var chart = AmCharts.makeChart("chartdiv",{
    defs: {
        "filter": [
            {
                "id": "blur",
                "feGaussianBlur": {
                    "in": "SourceGraphic",
                    "stdDeviation": "10"
                }
            }
        ]
    },
    ...
});

As you may have noted all keys which holds an array or object becomes to an element otherwise they will be attributes of this element. For this specific sample we have used feGaussianBlur and applied this filter on the SourceGraphic with slight deviation of 10, which generates following output:

<defs>
   <filter id="blur">
       <feGaussianBlur in="SourceGraphic" stdDeviation="10"></feGaussianBlur>
   </filter>
</defs>

The SVG side is done now, the only missing part is the link between filter and chart element which can be done through CSS like following:

.amcharts-graph-g1 .amcharts-graph-fill {
  filter: url(#blur);
}

See the Pen Using SVG Filters with amCharts by amCharts (@amcharts) on CodePen.

Possibilities & Inspiration

There are endless variations you can create, take a look to the W3C recommendation to see how many different filter you can apply and be combined with each other.
To give you a starting point we have created few samples to play around:

The post Applying SVG filters on charts and maps appeared first on amCharts.

Exporting charts and maps: Advanced usage

$
0
0
Unsupported: IE9 and lower are not supported by the export plugin due browser incompatibilities!

Exporting charts to single images or data files might be not enough, there are plenty of other use cases where the export needs to be triggered autonomously or embedded into a company report.

In this article we will guide you through such scenarios and explain how to extend the export plugin to achieve that.

We’re going to assume that you already have export running. If you don’t, we suggest you go through this tutorial first.

Free-hand export (autonomous)

Imagine you have a monitoring service and you want to inform your administrators about it’s activity. In this case you need the possibility to receive the chart imagery without user interaction.

With following adaption you can enable the export plugin but hide it from the user interface and trigger it when ever you need to send the image data to the server.

var chart = AmCharts.makeChart( "chartdiv", {
	"export": {
		"enabled": true,
		"menu": []
	},
	...
} );

// WAIT UNTIL CHART HAS BEEN RENDERED
chart.addListener( "rendered", function( e ) {

	// WAIT FOR FABRIC
	var interval = setInterval( function() {
		if ( window.fabric ) {
			clearTimeout( interval );

			// CAPTURE CHART
			e.chart["export"].capture( {}, function() {

				// SAVE TO JPG
				this.toJPG( {}, function( base64 ) {

					// LOG IMAGE DATA
					console.log( base64 );
				} );
			} );
		}
	}, 100 );

} );

See the Pen #12500 by amCharts (@amcharts) on CodePen.11061

For demonstration purpose we’ve added a “link” to open the base64 image in a new tab. Ina real life scenario, you might want to send such data to your server to send an e-mail.

Seamless system reports on the fly

You have running system with some important statistics, probably a handy dashboard which provides your users a quick overview about the current situation. But what if you want to enable your users to download the whole page as a single report file?

You’re in luck, because with just few lines of custom code you can create a button which, when clicked, will generate a PDF document with multiple charts and optional a data table in it.

Like in the previous sample we want to enable the export capabilities but hide the menu. We’ll pass in an empty menu array to the export setup. In addition we need to save the chart instances for later to be able to collect the imagery and pass them to the PDF layout.

var charts = [];
...
var chart = AmCharts.makeChart( "chartdiv", {
	"export": {
		"enabled": true,
		"menu": []
	},
	...
} );
charts.push( chart );

After that we need to create a layout which will be used to generate the PDF, it is even possible to create references and use images multiple times. We took advantage of that and created a static layout and simply add the embedded base64 PNG images as references within the images property. You can use that file or start completely from scratch, all available options can be found on the github page of the export plugin. Following is a little snippet of the sample layout to show it’s structure.

 

var layout_1 = {
        /*
        ** Array of objects or strings which represents the output
        */
	content: [
		{
			text: "This is a header, using header style",
		}, {
			image: "logo", // reference to the image mapping below
			fit: [515.28, 761.89 - 14.064 ] // fits the image to those dimensions (A4); 14.064 is the lineheight
		}
	],

	/*
	 ** Mapping object, holds the actual imagery
	 */
	images: {
          logo: "data:image/png;base64, ..."
        }
}

Once everything has been configured and is ready to get exported, we just need to write a function which crawls through all charts to export those to PNG and pass them to the image mapping object of the layout above.

function createReport() {
  var pdf_images = 0;
  var pdf_layout = layout_1; // loaded from another JS file
  for ( chart in charts ) {

    // Capture current state of the chart
    chart.capture( {}, function() {

      // Export to PNG
      this.toPNG( {
        multiplier: 2 // pretend to be lossless

        // Add image to the layout reference
      }, function( data ) {
        pdf_images++;
        pdf_layout.images[ "image_" + pdf_images ] = data;

        // Once all has been processed create the PDF
        if ( pdf_images == AmCharts.charts.length ) {

          // Save as single PDF and offer as download
          this.toPDF( pdf_layout, function( data ) {
            this.download( data, this.defaults.formats.PDF.mimeType, "amcharts.pdf" );
          } );
        }
      } );
    } );
  }
}

See the Pen #12500 by amCharts (@amcharts) on CodePen.11061

We used the twitter bootstrap dashboard template and modified it a little bit to show you a real use case. We think this might be really interesting for few of you and we hope you have a lot adding this feature.

The post Exporting charts and maps: Advanced usage appeared first on amCharts.

Setting custom column names for exported chart data

$
0
0

Besides exporting charts to images and PDF, you can use our Export plugin for other things, like exporting it’s data to CSV, Excel and other formats.

By default, column names will be exported using their “internal” field names – the same way they appear in data. I.e. “value”, “volume”, etc.

Using graph names to replace internal column names with user-friendly names

Probably the easiest way is to set export’s option exportTitles:

"export": {
  "enabled": true,
  "exportTitles": true
}

Now the export will try to replace column names by using title of the graph that is attached to this specific column in data via valueField. Please note that the graph needs to have its title property set in order for it to work.

Setting completely custom names

If the above approach is not enough, or you have columns in your data that do not have graphs attached to them, but still wanted those to be exported, you can use export’s option columnNames.

It’s basically an object where it’s property key is a field in data and the property value is a text how it should be named in exported data:

"export": {
  "enabled": true,
  "columnNames": {
    "value": "Selling price, $",
    "volume": "Volume of sales, $M"
  }
}

Working with multiple-dataset Stock Chart

Multiple-dataset Stock Chart can be trickier.

When exporting data on such chart, export names the fields for main selected data set just like for any other chart.

For compared data sets it is using the following syntax to construct column names: “[dataset id]_[field name]”.

For example, “volume” field for data set with an id “ds2” will become “ds2_volume”.

Luckily, you can use those “generated” names in columnNames just as well:

"export": {
  "enabled": true,
  "exportFields": [
    "value",
    "volume",
    "ds2_value",
    "ds2_volume",
    "ds3_value",
    "ds3_volume",
    "ds4_value",
    "ds4_volume",
    "ds5_value",
    "ds5_volume"
  ],
  "columnNames": {
    "value": "Data Set #1 (Price)",
    "volume": "Data Set #1 (Volume)",
    "ds2_value": "Data Set #2 (Price)",
    "ds2_volume": "Data Set #2 (Volume)",
    "ds3_value": "Data Set #3 (Price)",
    "ds3_volume": "Data Set #3 (Volume)",
    "ds4_value": "Data Set #4 (Price)",
    "ds4_volume": "Data Set #4 (Volume)",
    "ds5_value": "Data Set #5 (Price)",
    "ds5_volume": "Data Set #5 (Volume)"
  }
}

The post Setting custom column names for exported chart data appeared first on amCharts.

Exporting charts and maps: PDF with multiple charts and related info

$
0
0

Intro

If you are looking on how to automatically generate PDF reports, you should probably explore some server-side options, like PhantomJS. We have a handy tutorial ready about the latter here.

However, sometimes, you just need to export a chart or two, along with some additional info on-demand, triggered by the user. In those cases you can use our own Export plugin.

This article provides instructions on how to set up your export to do just that.

If you’re not a big fan of reading a lot of text, jump to the bottom of this article. It contains a link to a full working chart that we are going to build during the course of the tutorial.

Prerequisites

We assume that you are familiar with Export plugin. If you’re not, we suggest you start here.

For any of the below technique to work, Export plugin must be loaded on the web page. Each chart to be exported should also have “export” option enabled, i.e. contain Export plugin configuration block:

"export": {
  "enabled": true,
  "menu": []
}

Empty “menu” array means the plugin is active, but it will not show its export button.

Test report

Let’s say we have something like this as a report page:

Sample report
An HTML-based report sample page, we’re going to export to PDF

When user clicks “Export PDF”, I want something similar to be dumped into a PDF, which then user can save on his or her computer.

Say, the button will execute a custom function:

function exportReport() {
  console.log("Starting export...");
}

Live version.

We’re going to continue building up this function, placing the code that does actual export in there.
Step #1: Exporting the charts to images
Since PDF can’t contain dynamic content like JavaScript, we’ll need to grab each and every chart we want to export as a bitmap image representation of their current states.

We’re going to be using Export plugin’s “toPNG()” function.

One thing to note is that “toPNG()” function is asynchronous. Meaning that we will need their completion handler functions to grab the output as well as check the total number of exported charts, so that we know we have all of them and can move on to the next step.

Here’s how this might look code-wise:

function exportReport() {

  // So that we know export was started
  console.log("Starting export...");

  // Define IDs of the charts we want to include in the report
  var ids = ["chartdiv1", "chartdiv2", "chartdiv3", "chartdiv4"];

  // Collect actual chart objects out of the AmCharts.charts array
  var charts = {}
  var charts_remaining = ids.length;
  for (var i = 0; i < ids.length; i++) {
    for (var x = 0; x < AmCharts.charts.length; x++) {
      if (AmCharts.charts[x].div.id == ids[i])
        charts[ids[i]] = AmCharts.charts[x];
    }
  }

  // Trigger export of each chart
  for (var x in charts) {
    if (charts.hasOwnProperty(x)) {
      var chart = charts[x];
      chart["export"].capture({}, function() {
        this.toPNG({}, function(data) {

          // Save chart data into chart object itself
          this.setup.chart.exportedImage = data;

          // Reduce the remaining counter
          charts_remaining--;

          // Check if we got all of the charts
          if (charts_remaining == 0) {
            // Yup, we got all of them
            // Let's proceed to putting PDF together
            generatePDF();
          }

        });
      });
    }
  }

  function generatePDF() {

    // Log
    console.log("Generating PDF...");

  }
}

Once this run, we will have all four of our chart objects, in a neat “charts” object, with their static bitmap representations stored in their respective “exportedImage” properties.

For the sake of structural clarity, we will declare a new local function “generatePDF()” that will be executed once our remaining charts counter hits zero.

Step #2: Putting the PDF together

Now that we have all of our charts as images, we might start layouting a PDF. Once all of the charts are exported to images, our code will execute “generatePDF” function, which will do the grunt work.

Export plugin uses an excellent library – pdfmake. It allows adding various objects into a “layout” object, which can then be rendered into a PDF document.

Complete information of what can go into a pdfmake layout is here.

We’re going to be using just a few of the available layout and formatting options. Use the link above to find out how much more you can cram into a PDF using this library.

OK, so for starters we initialize an empty layout object. The actual content objects that goe into PDF is contained in layout’s “content” property:

var layout = {
  "content": []
}

Now let’s start adding actual content objects.

Adding text

The most basic object is text. Let’s add a title and intro text:

// Let's add a custom title
layout.content.push({
  "text": "Lorem ipsum dolor sit amet, consectetur adipiscing",
  "fontSize": 15
});

// Now let's grab actual content from our

intro tag layout.content.push({ “text”: document.getElementById(“intro”).innerHTML; });

Now, if I exported PDF as it is, I’d get a document that would look something like this:

PDF with just text
A PDF with a little bit of text

Adding images

That’s a good start. Now let’s add our first chart.

We’re going to use image type object in out layout:

layout.content.push({
  "image": charts["chartdiv1"].exportedImage,
  "fit": [ 523, 300 ]
});

Notice the “fit” parameter. It’s a special pdfmake parameter telling it to downsize the image to 523×300 pixels if it does not fit.

OK, so here’s what we would get now:

PDF with text and image
A PDF with text and an image of a chart

Our report is really coming together.

Adding tables

pdfmake allows adding tables to PDF as well:

layout.content.push({
  "table": {
    // headers are automatically repeated if the table spans over multiple pages
    // you can declare how many rows should be treated as headers
    "headerRows": 1,
    "widths": ["16%", "16%", "16%", "16%", "16%", "*"],
    "body": [
      ["USA", "UK", "Canada", "Japan", "France", "Brazil"],
      ["5000", "4500", "5100", "1500", "9600", "2500"],
      ["5000", "4500", "5100", "1500", "9600", "2500"],
      ["5000", "4500", "5100", "1500", "9600", "2500"]
    ]
  }
});

Organizing information into columns

Now, let’s put our two other charts side by side. We’ll need to put those into columns.

layout.content.push({
  "columns": [{
    "width": "50%",
    "image": charts["chartdiv2"].exportedImage,
    "fit": [250, 300]
  }, {
    "width": "50%",
    "image": charts["chartdiv3"].exportedImage,
    "fit": [250, 300]
  }]
});

Each column is an array which can hold other objects. Just like the main layout file.

Please refer to the pdfmake documentation for description of “width”.

We’ll use columns to add our last chart and text duo as well:

layout.content.push({
  "columns": [{
    "width": "25%",
    "image": charts["chartdiv4"].exportedImage,
    "fit": [125, 300]
  }, {
    "width": "*",
    "stack": [
      document.getElementById("note1").innerHTML,
      "nn",
      document.getElementById("note2").innerHTML
    ]
  }],
  "columnGap": 10
});

And here we go:

Final exported PDF
Final exported PDF

Conclusion

The final PDF document could use some styling, like borders and margins around paragraphs. We’ll leave you to pdfmake documentation to apply those.

The final working example of the above report can be found here.

If you have questions, drop as a line on contact@amcharts.com.

The post Exporting charts and maps: PDF with multiple charts and related info appeared first on amCharts.

Viewing all 111 articles
Browse latest View live


Latest Images