{"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 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 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 amCharts calls the lines on this chart a line series. A line series has a variable called Initially, all the values of the series are the same: a flat line. Then, we set 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 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 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 See the Pen deconstructing amCharts movie, understanding states<\/a> by amCharts team (@amcharts<\/a>) on CodePen<\/a>.<\/p>\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 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 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 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 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 Here is a simplified demo where we zoom in to the country, morph it to a circle, then morph it back to its default state:<\/p>\n See the Pen deconstructing amCharts movie, morphing<\/a> by amCharts team (@amcharts<\/a>) on CodePen<\/a>.<\/p>\n Inspect that code. Note that all the methods we call, like At one point, an airplane surfaces at London on a map chart and travels all the way to Silicon Valley.<\/p>\nFirst, let\u2019s outline the stages of the movie<\/h3>\n
\n
The initial animations and states<\/h3>\n
Setting up the line and pie chart animations<\/h4>\n
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
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
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
A brief overview of amChart states<\/h4>\n
innerRadius<\/code>,
radius<\/code> and
fill<\/code> animating on hover:<\/p>\n
The pie chart pops up<\/h3>\n
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
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
series.slices.getIndex(3)<\/code> to isolate it.<\/p>\n
The pie chart morphs into a country<\/h3>\n
\n
innerRadius<\/code> property to 0, and the slice becomes a true circle.<\/li>\n
zoomToMapObject<\/code>,
morphToCircle<\/code> or
morphBack<\/code>, return an Animation object. An animation object dispatches events like
animationstarted<\/code>,
animationprogress<\/code> or
animationended<\/code> and we can attach listeners to them. This ensures that one animation is triggered only after another one is finished. And, if we change the duration of an animation, we won’t need to adjust timers accordingly, because events will handle it. In amCharts 4, Sprites, Components, DataItems, Animations, and other objects have an event dispatcher object which regulate any events. You can add listeners for these events and use them to make your applications super interactive.<\/p>\n
The plane flies from one country to another<\/h3>\n