add bar race example
diff --git a/public/data/bar-race-country.js b/public/data/bar-race-country.js
new file mode 100644
index 0000000..0a86ded
--- /dev/null
+++ b/public/data/bar-race-country.js
@@ -0,0 +1,138 @@
+/*
+title: Bar Race
+titleCN: 动态排序柱状图 - 各国收入变化
+category: bar
+difficulty: 6
+*/
+
+
+var updateFrequency = 5000;
+var dimension = 0;
+
+var countryColors = {"Australia":"#00008b","Canada":"#f00","China":"#ffde00","Cuba":"#002a8f","Finland":"#003580","France":"#ed2939","Germany":"#000","Iceland":"#003897","India":"#f93","Japan":"#bc002d","North Korea":"#024fa2","South Korea":"#000","New Zealand":"#00247d","Norway":"#ef2b2d","Poland":"#dc143c","Russia":"#d52b1e","Turkey":"#e30a17","United Kingdom":"#00247d","United States":"#b22234"};
+
+$.when(
+    $.getJSON('https://cdn.jsdelivr.net/npm/emoji-flags@1.3.0/data.json'),
+    $.getJSON(ROOT_PATH + '/data/asset/data/life-expectancy-table.json')
+).done(function (res0, res1) {
+    var flags = res0[0];
+    var data = res1[0];
+    var years = [];
+    for (var i = 0; i < data.length; ++i) {
+        if (years.length === 0 || years[years.length - 1] !== data[i][4]) {
+            years.push(data[i][4]);
+        }
+    }
+
+    function getFlag(countryName) {
+        if (!countryName) {
+            return '';
+        }
+        return (flags.find(function (item) {
+            return item.name === countryName;
+        }) || {}).emoji;
+    }
+    var startIndex = 4;
+    var startYear = years[startIndex];
+
+    var option = {
+        grid: {
+            left: 150,
+            right: 150
+        },
+        xAxis: {
+            max: 'dataMax',
+            label: {
+                formatter: function (n) {
+                    return Math.round(n);
+                }
+            }
+        },
+        dataset: {
+            source: data.slice(1).filter(function (d) {
+                return d[4] === startYear;
+            })
+        },
+        yAxis: {
+            type: 'category',
+            inverse: true,
+            max: 10,
+            axisLabel: {
+                show: true,
+                textStyle: {
+                    fontSize: 14
+                },
+                formatter: function (value) {
+                    return value + '{flag|' + getFlag(value) + '}';
+                },
+                rich: {
+                    flag: {
+                        fontSize: 25,
+                        padding: 5
+                    }
+                }
+            },
+            animationDuration: 300,
+            animationDurationUpdate: 300
+        },
+        series: [{
+            realtimeSort: true,
+            seriesLayoutBy: 'column',
+            type: 'bar',
+            itemStyle: {
+                color: function (param) {
+                    return countryColors[param.value[3]] || '#5470c6';
+                }
+            },
+            encode: {
+                x: dimension,
+                y: 3
+            },
+            label: {
+                show: true,
+                precision: 1,
+                position: 'right',
+                valueAnimation: true,
+                fontFamily: 'monospace'
+            }
+        }],
+        // Disable init animation.
+        animationDuration: 0,
+        animationDurationUpdate: updateFrequency,
+        animationEasing: 'linear',
+        animationEasingUpdate: 'linear',
+        graphic: {
+            elements: [{
+                type: 'text',
+                right: 160,
+                bottom: 60,
+                style: {
+                    text: startYear,
+                    font: 'bolder 80px monospace',
+                    fill: 'rgba(100, 100, 100, 0.25)'
+                },
+                z: 100
+            }]
+        }
+    };
+
+    // console.log(option);
+    myChart.setOption(option);
+
+    for (var i = startIndex; i < years.length; ++i) {
+        (function (i) {
+            setTimeout(function () {
+                updateYear(years[i + 1]);
+            }, (i - startIndex) * updateFrequency);
+        })(i);
+    }
+
+    function updateYear(year) {
+        var source = data.slice(1).filter(function (d) {
+            return d[4] === year;
+        });
+        option.series[0].data = source;
+        option.graphic.elements[0].style.text = year;
+        myChart.setOption(option);
+    }
+})
\ No newline at end of file
diff --git a/public/data/thumb-dark/bar-race-country.png b/public/data/thumb-dark/bar-race-country.png
new file mode 100644
index 0000000..0fab93c
--- /dev/null
+++ b/public/data/thumb-dark/bar-race-country.png
Binary files differ
diff --git a/public/data/thumb-dark/bar-race-country.webp b/public/data/thumb-dark/bar-race-country.webp
new file mode 100644
index 0000000..2e0883a
--- /dev/null
+++ b/public/data/thumb-dark/bar-race-country.webp
Binary files differ
diff --git a/src/data/chart-list-data.js b/src/data/chart-list-data.js
index 124e39a..b096fa3 100644
--- a/src/data/chart-list-data.js
+++ b/src/data/chart-list-data.js
@@ -1468,6 +1468,16 @@
   },
   {
     "category": [
+      "bar"
+    ],
+    "id": "bar-race-country",
+    "tags": [],
+    "title": "Bar Race",
+    "titleCN": "动态排序柱状图 - 各国收入变化",
+    "difficulty": 6
+  },
+  {
+    "category": [
       "bar",
       "rich"
     ],