はじめに
対象読者
- Claris FileMaker ユーザ
- FileMaker に興味がある人
- BarChartRace を手軽に作りたい人
- 次の前置きを要参照
前置き
- 以下のイベントへの参加記事です
環境
what is amCharts
-
公式サイト
- 以下 OG title だと
amCharts 4
となっているけれど、現行の最新版はamCharts 5
がリリースされたところです ( 2022/07 時点 )
- 以下 OG title だと
- グラフ/チャート系が充実した JavaScript ライブラリ
- ロゴつきなら無料で使える
You can download and use all amCharts 5 products for free. The only limitation of the free version is that a small amCharts logo will be displayed in the corner of your charts.
what is BarChartRace
- Bar Chart Race / バーチャートレース
- 横棒グラフが時間軸に沿って動的に変化していくアニメーション
- amCharts 公式サイトにおけるデモ
- 次の項も参照
最終的に出来上がるモノ
- 以下のような感じ
下準備その1
ファイル作成
FileMaker-BarChartRace.fmp12
表示用テーブル作成
races
フィールド作成
-
id
: 数字 -
g_for_webview
: テキスト、グローバル
スクリプト作成
set_global_var.amcharts_tags
- 今回挿入する amCharts のタグをグローバル変数として定義しておく
"<script src=\"https://cdn.amcharts.com/lib/5/index.js\"></script>" & ¶ &
"<script src=\"https://cdn.amcharts.com/lib/5/xy.js\"></script>" & ¶ &
"<script src=\"https://cdn.amcharts.com/lib/5/themes/Animated.js\"></script>"
set_global_var.style_tags
- 今回挿入する CSS style のタグをグローバル変数として定義しておく
"<style>
#chartdiv {
height: 500px;
width: 100%;
}
</style>"
open
- スクリプトトリガで
OnLayoutEnter
レイアウト作成
レイアウト全体
- 最低限以下のように配置
WEB ビューア
- 以下のような計算式で
Let (
[
amcharts_tags = $$amcharts_tags;
style_tags = $$style_tags;
result = races::g_for_webview;
result = Substitute ( result ; "[[[amcharts_tags]]]" ; amcharts_tags );
result = Substitute ( result ; "[[[style_tags]]]" ; style_tags )
];
result
)
g_for_webview への入力
- HTML テンプレートを
g_for_webview
フィールドへ入力
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
</body>
</html>
デモからコードを転記して動作確認
転記
-
公式サイトのデモページ に書かれている以下のコードを
<body></body>
の間に挿入
- その際、以下の箇所は
[[[style_tags]]]
と[[[amcharts_tags]]]
とに書き換えておく- グローバル変数を呼び出すため
<!-- Styles -->
<style>
#chartdiv {
width: 100%;
height: 500px;
}
</style>
<!-- Resources -->
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
- 長いけれどひとまず全部載せておく……
[[[style_tags]]]
[[[amcharts_tags]]]
<!-- Chart code -->
<script>
am5.ready(function() {
// Data
var allData = {
"2002": {
"Friendster": 0,
"Facebook": 0,
"Flickr": 0,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 0,
"Instagram": 0,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 0
},
"2003": {
"Friendster": 4470000,
"Facebook": 0,
"Flickr": 0,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 0,
"Instagram": 0,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 0
},
"2004": {
"Friendster": 5970054,
"Facebook": 0,
"Flickr": 3675135,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 0,
"Instagram": 0,
"MySpace": 980036,
"Orkut": 4900180,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 0
},
"2005": {
"Friendster": 7459742,
"Facebook": 0,
"Flickr": 7399354,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 9731610,
"Instagram": 0,
"MySpace": 19490059,
"Orkut": 9865805,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 1946322
},
"2006": {
"Friendster": 8989854,
"Facebook": 0,
"Flickr": 14949270,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 19932360,
"Instagram": 0,
"MySpace": 54763260,
"Orkut": 14966180,
"Pinterest": 0,
"Reddit": 248309,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 19878248
},
"2007": {
"Friendster": 24253200,
"Facebook": 0,
"Flickr": 29299875,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 29533250,
"Instagram": 0,
"MySpace": 69299875,
"Orkut": 26916562,
"Pinterest": 0,
"Reddit": 488331,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 143932250
},
"2008": {
"Friendster": 51008911,
"Facebook": 100000000,
"Flickr": 30000000,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 55045618,
"Instagram": 0,
"MySpace": 72408233,
"Orkut": 44357628,
"Pinterest": 0,
"Reddit": 1944940,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 294493950
},
"2009": {
"Friendster": 28804331,
"Facebook": 276000000,
"Flickr": 41834525,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 57893524,
"Instagram": 0,
"MySpace": 70133095,
"Orkut": 47366905,
"Pinterest": 0,
"Reddit": 3893524,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 413611440
},
"2010": {
"Friendster": 0,
"Facebook": 517750000,
"Flickr": 54708063,
"Google Buzz": 166029650,
"Google+": 0,
"Hi5": 59953290,
"Instagram": 0,
"MySpace": 68046710,
"Orkut": 49941613,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 43250000,
"WeChat": 0,
"Weibo": 19532900,
"Whatsapp": 0,
"YouTube": 480551990
},
"2011": {
"Friendster": 0,
"Facebook": 766000000,
"Flickr": 66954600,
"Google Buzz": 170000000,
"Google+": 0,
"Hi5": 46610848,
"Instagram": 0,
"MySpace": 46003536,
"Orkut": 47609080,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 92750000,
"WeChat": 47818400,
"Weibo": 48691040,
"Whatsapp": 0,
"YouTube": 642669824
},
"2012": {
"Friendster": 0,
"Facebook": 979750000,
"Flickr": 79664888,
"Google Buzz": 170000000,
"Google+": 107319100,
"Hi5": 0,
"Instagram": 0,
"MySpace": 0,
"Orkut": 45067022,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 146890156,
"Twitter": 160250000,
"WeChat": 118123370,
"Weibo": 79195730,
"Whatsapp": 0,
"YouTube": 844638200
},
"2013": {
"Friendster": 0,
"Facebook": 1170500000,
"Flickr": 80000000,
"Google Buzz": 170000000,
"Google+": 205654700,
"Hi5": 0,
"Instagram": 117500000,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 293482050,
"Twitter": 223675000,
"WeChat": 196523760,
"Weibo": 118261880,
"Whatsapp": 300000000,
"YouTube": 1065223075
},
"2014": {
"Friendster": 0,
"Facebook": 1334000000,
"Flickr": 0,
"Google Buzz": 170000000,
"Google+": 254859015,
"Hi5": 0,
"Instagram": 250000000,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 0,
"Reddit": 135786956,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 388721163,
"Twitter": 223675000,
"WeChat": 444232415,
"Weibo": 154890345,
"Whatsapp": 498750000,
"YouTube": 1249451725
},
"2015": {
"Friendster": 0,
"Facebook": 1516750000,
"Flickr": 0,
"Google Buzz": 170000000,
"Google+": 298950015,
"Hi5": 0,
"Instagram": 400000000,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 0,
"Reddit": 163346676,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 475923363,
"Twitter": 304500000,
"WeChat": 660843407,
"Weibo": 208716685,
"Whatsapp": 800000000,
"YouTube": 1328133360
},
"2016": {
"Friendster": 0,
"Facebook": 1753500000,
"Flickr": 0,
"Google Buzz": 0,
"Google+": 398648000,
"Hi5": 0,
"Instagram": 550000000,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 143250000,
"Reddit": 238972480,
"Snapchat": 238648000,
"TikTok": 0,
"Tumblr": 565796720,
"Twitter": 314500000,
"WeChat": 847512320,
"Weibo": 281026560,
"Whatsapp": 1000000000,
"YouTube": 1399053600
},
"2017": {
"Friendster": 0,
"Facebook": 2035750000,
"Flickr": 0,
"Google Buzz": 0,
"Google+": 495657000,
"Hi5": 0,
"Instagram": 750000000,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 195000000,
"Reddit": 297394200,
"Snapchat": 0,
"TikTok": 239142500,
"Tumblr": 593783960,
"Twitter": 328250000,
"WeChat": 921742750,
"Weibo": 357569030,
"Whatsapp": 1333333333,
"YouTube": 1495657000
},
"2018": {
"Friendster": 0,
"Facebook": 2255250000,
"Flickr": 0,
"Google Buzz": 0,
"Google+": 430000000,
"Hi5": 0,
"Instagram": 1000000000,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 246500000,
"Reddit": 355000000,
"Snapchat": 0,
"TikTok": 500000000,
"Tumblr": 624000000,
"Twitter": 329500000,
"WeChat": 1000000000,
"Weibo": 431000000,
"Whatsapp": 1433333333,
"YouTube": 1900000000
}
};
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");
root.numberFormatter.setAll({
numberFormat: "#a",
// Group only into M (millions), and B (billions)
bigNumberPrefixes: [
{ number: 1e6, suffix: "M" },
{ number: 1e9, suffix: "B" }
],
// Do not use small number prefixes at all
smallNumberPrefixes: []
});
var stepDuration = 2000;
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([am5themes_Animated.new(root)]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: true,
panY: true,
wheelX: "none",
wheelY: "none"
}));
// We don't want zoom-out button to appear while animating, so we hide it at all
chart.zoomOutButton.set("forceHidden", true);
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var yRenderer = am5xy.AxisRendererY.new(root, {
minGridDistance: 20,
inversed: true
});
// hide grid
yRenderer.grid.template.set("visible", false);
var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
maxDeviation: 0,
categoryField: "network",
renderer: yRenderer
}));
var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
maxDeviation: 0,
min: 0,
strictMinMax: true,
extraMax: 0.1,
renderer: am5xy.AxisRendererX.new(root, {})
}));
xAxis.set("interpolationDuration", stepDuration / 10);
xAxis.set("interpolationEasing", am5.ease.linear);
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
xAxis: xAxis,
yAxis: yAxis,
valueXField: "value",
categoryYField: "network"
}));
// Rounded corners for columns
series.columns.template.setAll({ cornerRadiusBR: 5, cornerRadiusTR: 5 });
// Make each column to be of a different color
series.columns.template.adapters.add("fill", function (fill, target) {
return chart.get("colors").getIndex(series.columns.indexOf(target));
});
series.columns.template.adapters.add("stroke", function (stroke, target) {
return chart.get("colors").getIndex(series.columns.indexOf(target));
});
// Add label bullet
series.bullets.push(function () {
return am5.Bullet.new(root, {
locationX: 1,
sprite: am5.Label.new(root, {
text: "{valueXWorking.formatNumber('#.# a')}",
fill: root.interfaceColors.get("alternativeText"),
centerX: am5.p100,
centerY: am5.p50,
populateText: true
})
});
});
var label = chart.plotContainer.children.push(am5.Label.new(root, {
text: "2002",
fontSize: "8em",
opacity: 0.2,
x: am5.p100,
y: am5.p100,
centerY: am5.p100,
centerX: am5.p100
}));
// Get series item by category
function getSeriesItem(category) {
for (var i = 0; i < series.dataItems.length; i++) {
var dataItem = series.dataItems[i];
if (dataItem.get("categoryY") == category) {
return dataItem;
}
}
}
// Axis sorting
function sortCategoryAxis() {
// sort by value
series.dataItems.sort(function (x, y) {
return y.get("valueX") - x.get("valueX"); // descending
//return x.get("valueX") - y.get("valueX"); // ascending
});
// go through each axis item
am5.array.each(yAxis.dataItems, function (dataItem) {
// get corresponding series item
var seriesDataItem = getSeriesItem(dataItem.get("category"));
if (seriesDataItem) {
// get index of series data item
var index = series.dataItems.indexOf(seriesDataItem);
// calculate delta position
var deltaPosition =
(index - dataItem.get("index", 0)) / series.dataItems.length;
// set index to be the same as series data item index
if (dataItem.get("index") != index) {
dataItem.set("index", index);
// set deltaPosition instanlty
dataItem.set("deltaPosition", -deltaPosition);
// animate delta position to 0
dataItem.animate({
key: "deltaPosition",
to: 0,
duration: stepDuration / 2,
easing: am5.ease.out(am5.ease.cubic)
});
}
}
});
// sort axis items by index.
// This changes the order instantly, but as deltaPosition is set, they keep in the same places and then animate to true positions.
yAxis.dataItems.sort(function (x, y) {
return x.get("index") - y.get("index");
});
}
var year = 2002;
// update data with values each 1.5 sec
var interval = setInterval(function () {
year++;
if (year > 2018) {
clearInterval(interval);
clearInterval(sortInterval);
}
updateData();
}, stepDuration);
var sortInterval = setInterval(function () {
sortCategoryAxis();
}, 100);
function setInitialData() {
var d = allData[year];
for (var n in d) {
series.data.push({ network: n, value: d[n] });
yAxis.data.push({ network: n });
}
}
function updateData() {
var itemsWithNonZero = 0;
if (allData[year]) {
label.set("text", year.toString());
am5.array.each(series.dataItems, function (dataItem) {
var category = dataItem.get("categoryY");
var value = allData[year][category];
if (value > 0) {
itemsWithNonZero++;
}
dataItem.animate({
key: "valueX",
to: value,
duration: stepDuration,
easing: am5.ease.linear
});
dataItem.animate({
key: "valueXWorking",
to: value,
duration: stepDuration,
easing: am5.ease.linear
});
});
yAxis.zoom(0, itemsWithNonZero / yAxis.dataItems.length);
}
}
setInitialData();
setTimeout(function () {
year++;
updateData();
}, 50);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear(1000);
chart.appear(1000, 100);
}); // end am5.ready()
</script>
<!-- HTML -->
<div id="chartdiv"></div>
動作確認
- ここまでで、ひとまず以下のようなアニメーションがされればヨシ
- GIF アニメーションでちょっともっさりした見え方になってますが、実動はもっと高速です
下準備その2
表示したいデータを決める
- さて、ここまではデモ用のコード内に直書きされていたデータでの動作確認でした。次は、実際の FileMaker テーブル内にあるデータで動作させられるように進めます
- 表示させたいデータ用のテーブルを作りましょう。今回は既にクロス集計されたデータを使い、レコードの区分けは
年
によるものとして、それ以外はフィールドで区切るようにします - じゃあ何のデータを表示させようかということで、今回は、日本の五大商社の年末株価(終値)の推移でも見てみましょう
FileMaker データ用のテーブルを作成
- 今回は年毎に区切るということで
annal_reports
というテーブル名にしておきます
フィールド作成
-
id
: 数字 -
year
: 数字 - その他、乱暴にも各商社名をそのままフィールド名とします。全部数字で
- これができるのが FileMaker の驚きなところでもあり良いところでもあり
ダミーデータ準備
- ちょっと面倒なのですが、先ほど貼った以下の各ページから、各年の
終値(円)
の値を取ってきて csv データにします(手動でがんばる)- 何かもっと良いデータ提供サイトあったら教えてください……
"year", "伊藤忠商事", "丸紅", "三井物産", "住友商事", "三菱商事"
2013, 1299, 756, 1465, 1321, 2017
2014, 1292, 724.7, 1621.5, 1242, 2217
2015, 1442, 625.1, 1445.5, 1240.5, 2028
2016, 1552, 662.8, 1607, 1375.5, 2490
2017, 2103, 816.1, 1832, 1915, 3113
2018, 1867, 772.4, 1690.5, 1561.5, 3020
2019, 2534.5, 810.6, 1946, 1624, 2900
2020, 2964, 686.1, 1889.5, 1365.5, 2541
2021, 3518, 1119.5, 2723.5, 1700.5, 3652
ダミーデータ投下
- 上記 csv データをインポート
- 上記、見やすくするために半角スペースなど入れていますが、消してからインポートしないと半角スペースごと取り込まれてしまうという問題に遭遇します、FileMaker さん……
- csv でやるとヘッダ行までインポートされるので不要レコード削除……
- 以下のようにレコードが揃っていればヨシ
データ表示部分の形式を確認
- amCharts のデモから転記してきたコード内に、データ部分が含まれているので、そこでどのような形式を要求されているのか確認
- 以下のように
year
の中に各項目と値が記述されている
"2002": {
"Friendster": 0,
"Facebook": 0,
"Flickr": 0,
"Google Buzz": 0,
"Google+": 0,
"Hi5": 0,
"Instagram": 0,
"MySpace": 0,
"Orkut": 0,
"Pinterest": 0,
"Reddit": 0,
"Snapchat": 0,
"TikTok": 0,
"Tumblr": 0,
"Twitter": 0,
"WeChat": 0,
"Weibo": 0,
"Whatsapp": 0,
"YouTube": 0
},
"2003": {
// 以下略
- よって、以下のようなものが出力されるとヨシ
"2013": {
"伊藤忠商事": 1299,
"丸紅": 756,
"三井物産": 1465,
"住友商事": 1321,
"三菱商事": 2017
},
"2014": {
// 以下略
レイアウトと計算フィールド作成
レイアウト
-
for_json
という軽量簡潔なレイアウトを用意しておく
計算フィールド
-
c_json
という名の、以下のような計算フィールドを作成
While (
[
fileName = Get ( ファイル名 );
layoutName = "for_json";
fields = FieldNames ( fileName ; layoutName);
fields = Substitute ( fields ; "year" ; "" );
fields = Substitute ( fields ; "c_json" ; "" );
fieldsCount = ValueCount ( fields );
i = 0;
result = ""
];
i < fieldsCount;
[
i = i + 1;
name = GetValue ( fields ; i );
value = GetField ( name );
fieldType = FieldType ( fileName ; name );
jsonType = If (
PatternCount ( fieldType ; "Number");
JSONNumber;
JSONString
);
result = JSONSetElement ( result; name; value; jsonType )
];
"\"" & year & "\": " &
JSONFormatElements ( result ) & ","
)
単一レコードの JSON データ確認
-
annual_reports
レイアウトにc_json
フィールドを設置してみて出力結果を確認
対象レコードの JSON データ化
リレーション作成
-
races
テーブルを親にして any 条件でリレーションを作成- このあたり、
type
みたいなフィールドをraces
とannual_repots
両方に持たせてそれをキーにし、特定の条件のレポートだけに絞り込む、というやり方もアリ
- このあたり、
計算フィールド作成
-
races
テーブルにもc_json
計算フィールドを作成
List ( races⇔annual_reports◎any::c_json )
出力確認
-
races
レイアウトにc_json
フィールドを設置してみて出力結果を確認
締め作業
g_for_webview
の書き換え
- ここまで来れば、もうあと一歩……
データ部分の書き換え
-
g_for_webview
の以下箇所allData = {
より下の行からがデータにあたるので……
- 以下のように書き換える
// Data
var allData = {
[[[c_json]]]
};
年情報の書き換え
- サンプルコードの中では年情報が固定で直接書かれてしまっています
var label = chart.plotContainer.children.push(am5.Label.new(root, {
text: "2002",
fontSize: "8em",
opacity: 0.2,
x: am5.p100,
y: am5.p100,
centerY: am5.p100,
centerX: am5.p100
}));
// 中略
var year = 2002;
// update data with values each 1.5 sec
var interval = setInterval(function () {
year++;
if (year > 2018) {
clearInterval(interval);
clearInterval(sortInterval);
}
updateData();
}, stepDuration);
- 上記の
2002
と2018
は動的に変わって欲しいので[[[start_year]]]
[[[end_year]]]
として、以下のように書き換えておきます
var label = chart.plotContainer.children.push(am5.Label.new(root, {
text: "[[[start_year]]]",
fontSize: "8em",
opacity: 0.2,
x: am5.p100,
y: am5.p100,
centerY: am5.p100,
centerX: am5.p100
}));
// 中略
var year = [[[start_year]]];
// update data with values each 1.5 sec
var interval = setInterval(function () {
year++;
if (year > [[[end_year]]]) {
clearInterval(interval);
clearInterval(sortInterval);
}
updateData();
}, stepDuration);
前年データの投入
- amCharts できれいに描画開始したい場合、開始年より一年前のレコードですべての値が
0
になっているものが用意されている方がよい様子
WEB ビューアの書き換え
- 計算式を以下のように
Let (
[
amcharts_tags = $$amcharts_tags;
style_tags = $$style_tags;
json = races::c_json;
start_year = Min ( races⇔annual_reports◎any::year );
end_year = Max ( races⇔annual_reports◎any::year );
result = races::g_for_webview;
result = Substitute ( result ; "[[[amcharts_tags]]]" ; amcharts_tags );
result = Substitute ( result ; "[[[style_tags]]]" ; style_tags );
result = Substitute ( result ; "[[[json]]]" ; json );
result = Substitute ( result ; "[[[start_year]]]" ; start_year );
result = Substitute ( result ; "[[[end_year]]]" ; end_year )
];
result
)
動作確認
- 以下のようにアニメーションされればヨシ!
- 実際に FileMaker Pro 上で動作させている場合はもっと高速にぬるぬる動きますよ
おわりに
雑感
- 長かった! 書くのに時間がかかった! ここまでお読みいただきありがとうございました🙏
-
amCharts
については、この BarChartRace 以外にも色々なグラフ表現が充実しているので、便利に使えると思います。ただちょっと慣れないとサンプル読むのに時間がかかるかもしれません。他にもコレで実装例出してみて欲しい、など希望があればコメントください - FileMaker グラフとは
GitHub 公開リポジトリ
- .fmp12 ファイルのダウンロードや DDR ( Database Design Report ) の確認ができるようになっています。issue や Pull-req も歓迎