{"id":281258,"date":"2019-01-16T08:44:20","date_gmt":"2019-01-16T15:44:20","guid":{"rendered":"http:\/\/css-tricks.com\/?p=281258"},"modified":"2019-01-16T08:44:20","modified_gmt":"2019-01-16T15:44:20","slug":"making-movies-with-amcharts","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/making-movies-with-amcharts\/","title":{"rendered":"Making Movies With amCharts"},"content":{"rendered":"

In this article, I want to show off the flexibility and real power of amCharts 4<\/a>. We\u2019re going to learn how to combine multiple charts that run together with animations that form a movie experience. Even if you\u2019re only interested in creating a different kind of animation that has nothing to do with charts, you can still use this library, since it\u2019s more than making charts. The core of amCharts is made to help with everything SVG: creation, layout, animation \u2014 basically a library that makes working with SVG fun!<\/p>\n

<\/p>\n

Here\u2019s the kind of thing I\u2019m talking about. It’s actually a demonstration of seven different charts<\/em> animated together. We\u2019ll walk through this together, covering how it works and how to re-create it so you can have amCharts in your tool belt the next time you\u2019re working with charts or complex animations.<\/p>\n

See the Pen React Hook: setEffect example<\/a> by amCharts team (@amcharts<\/a>) on CodePen<\/a>.<\/p>\n

First, let\u2019s outline the stages of the movie<\/h3>\n

There\u2019s a lot going on in the movie. Let\u2019s break it up into digestible parts that allow us to parse out what\u2019s going on and re-create those parts under the hood.<\/p>\n

Here\u2019s the gist of what we\u2019re working with:<\/p>\n

    \n
  1. The initial animations and states<\/a><\/li>\n
  2. The pie chart pops up<\/a><\/li>\n
  3. The pie chart morphs to a country<\/a><\/li>\n
  4. The plane flies to some other country<\/a><\/li>\n
  5. The plane becomes big and flies away<\/a><\/li>\n
  6. The column chart appears and bends to a radar column chart<\/a><\/li>\n<\/ol>\n

    The initial animations and states<\/h3>\n

    The first thing we\u2019re hit is a pie chart rising from the depths with a curved line wrapped around it. There\u2019s nothing special about the pie chart at this point, but we\u2019ll cover it in the next section.<\/p>\n

    But what about that curved line? Remember, we make charts, so this line is simply a XY chart<\/a> with a single line on it. All the other details \u2014 grid, labels, tick marks, etc. \u2014 are hidden. So, what we\u2019re really looking at is a stripped-down line chart!<\/p>\n

    Setting up the line and pie chart animations<\/h4>\n

    amCharts calls the lines on this chart a line series. A line series has a variable called tensionX<\/code> and, in this case, it\u2019s been set to 0.75, making for a curvy line. We have to think of tension like we would a rope that is being held by two people and both ends: the tighter the rope is pulled, the greater the tension; conversely, the tension gets looser as the two ends let up. That 0.75 value is a taking a quarter of a unit away from the initial value (1), creating less tension.<\/p>\n

    \/\/ Creates the line on the chart\r\nvar lineSeries = lineChart.series.push(new am4charts.LineSeries());\r\nlineSeries.dataFields.dateX = \"date\";\r\nlineSeries.dataFields.valueY = \"value\";\r\nlineSeries.sequencedInterpolation = true;\r\nlineSeries.fillOpacity = 0.3;\r\nlineSeries.strokeOpacity = 0;\r\nlineSeries.tensionX = 0.75; Loosens the tension to create a curved line\r\nlineSeries.fill = am4core.color(\"#222a3f\");\r\nlineSeries.fillOpacity = 1;<\/code><\/pre>\n

    Initially, all the values of the series are the same: a flat line. Then, we set valueY<\/code> value of the line\u2019s animation to 80, meaning it pops up to the eights row of the chart height \u2014 that will make plenty of room for the pie when it comes in.<\/p>\n

    \/\/ Defines the animation that reveals the curved line\r\nlineSeries.events.on(\"shown\", function(){\r\n  setTimeout(showCurve, 2000)\r\n});\r\n\r\n\/\/ Sets the animation properties and the valueY so the line bounces up to\r\n\/\/ 80 on the chart's y-axis\r\nfunction showCurve() {\r\n  lineSeries.interpolationEasing = am4core.ease.elasticOut;\r\n  lineSeries.dataItems.getIndex(3).setValue(\"valueY\", 80, 2000);\r\n  setTimeout(hideCurve, 2000);\r\n}\r\n\r\n\/\/ This is the initial state where the line starts at 30 on the y-axis\r\n\/\/ before it pops up to 80\r\nfunction hideCurve() {\r\n  lineSeries.interpolationEasing = am4core.ease.elasticOut;\r\n  lineSeries.dataItems.getIndex(3).setValue(\"valueY\", 30, 2000);\r\n  setTimeout(showCurve, 2000);\r\n}<\/code><\/pre>\n

    Here is the line chart alone so we have a better visual for how that looks:<\/p>\n

    See the Pen deconstructing amCharts movie, stage 1<\/a> by amCharts team (@amcharts<\/a>) on CodePen<\/a>.<\/p>\n

    Next, the pie chart pops up from the bottom. Like a line series, amCharts includes a pie series and it has a dy<\/code> property that we can set to hidden with a state of 400. <\/p>\n

    \/\/ Make the circle to show initially, meaning it will animate its properties from hidden state to default state\r\ncircle.showOnInit = true;\r\n\r\n\/\/ Set the circle's easing and the duration of the pop up animation\r\ncircle.defaultState.transitionEasing = am4core.ease.elasticOut;\r\ncircle.defaultState.transitionDuration = 2500;\r\n\r\n\/\/ Make it appear from bottom by setting dy of hidden state to 300;\r\ncircle.hiddenState.properties.dy = 300;<\/code><\/pre>\n

    To illustrate this concept, here is a demo with that simple circle in place of a pie chart:<\/p>\n

    See the Pen deconstructing amCharts movie, initial animation<\/a> by amCharts team (@amcharts<\/a>) on CodePen<\/a>.<\/p>\n

    A brief overview of amChart states<\/h4>\n

    The idea of states in amCharts<\/a> is this: you can have any number of custom states on any sprite. Then, instead of creating multiple animations with a slew of various different properties, state is changed from one to another and all the required properties that are set on the target state will animate from current values to the new state values.<\/p>\n

    Any numeric, percentage or color property of a sprite can be animated. By default, sprites have hidden and default states baked in. The hidden state is applied initially and followed by the revealed state, which is the default. There are other states, of course, like hover<\/em>, active<\/em>, disabled<\/em>, among others<\/a>, including custom states. Here is another demo showing a slice chart with innerRadius<\/code>, radius<\/code> and fill<\/code> animating on hover:<\/p>\n

    See the Pen deconstructing amCharts movie, understanding states<\/a> by amCharts team (@amcharts<\/a>) on CodePen<\/a>.<\/p>\n

    The pie chart pops up<\/h3>\n

    Here is a demo of a basic pie chart. After some time, we\u2019ll hide all the slices, except one, then show them all again.<\/p>\n

    See the Pen deconstructing amCharts movie, pie chart<\/a> by amCharts team (@amcharts<\/a>) on CodePen<\/a>.<\/p>\n

    If you look at the code in the demo, you will see some of properties of the slices are customized via pieSeries.slices.template<\/code> or pieSeries.labels.template<\/code>. Most of the customization, of course, can be done using themes<\/a> (amCharts 4 supports using multiple themes at the same time), but since we only need to change a few properties, we can use a template<\/a>. We\u2019re using a pie chart type and all of the slices of the pie series will be created using the provided template which passes any of the inherited properties we use from the template onto our pie chart.<\/p>\n

    \/\/ Call included themes for styling and animating\r\nam4core.useTheme(am4themes_amchartsdark);\r\nam4core.useTheme(am4themes_animated);\r\n\/\/ ...\r\n\/\/ Call the Pie Chart template\r\nvar pieChart = mainContainer.createChild(am4charts.PieChart);<\/code><\/pre>\n

    What if you want to set a custom color for the chart\u2019s font? We can do this by adding a field in the data, like fontColor<\/code>. That allows us to set custom colors there and then tell the label template that it should look at the field to inform the color<\/code> property value.<\/p>\n

    \/\/ Define custom values that override one provided by the template\r\npieChart.data = [{\r\n  \"name\": \"[bold]No[\/]\",\r\n  \"fontColor\": am4core.color(\"#222a3f\"),\r\n  \"value\": 220,\r\n  \"tickDisabled\":true\r\n}, {\r\n  \"name\": \"Hm... I don't think so.\",\r\n  \"radius\":20,\r\n  \"value\": 300,\r\n  \"tickDisabled\":false\r\n}, {\r\n  \"name\": \"Yes, we are using amCharts\",\r\n  \"value\": 100,\r\n  \"labelDisabled\": true,\r\n  \"tickDisabled\":true\r\n}];<\/code><\/pre>\n

    Any property of a sprite can be customized like this. And even later, after the chart is initialized, we can change any property via the template, or if we need to access some individual object, we can get any value using something like series.slices.getIndex(3)<\/code> to isolate it.<\/p>\n

    To summarize: there isn’t a single object on the chart that can\u2019t be customized or accessed, changed, even after the chart is built. We\u2019re working with a lot of flexibility!<\/p>\n

    The pie chart morphs into a country<\/h3>\n

    I\u2019ll be blunt: There is no way to morph a whole pie chart or some other complex object to the shape of a country. In amCharts 4, one polygon can morph into another one. And there are prebuilt methods that simply morph a polygon to a circle or to a rectangle. Here\u2019s what we\u2019ll do:<\/p>\n