サンプル・プログラムの実行例
目次
サンプル・プログラム
| Moore.php | サンプル・プログラム本体。 |
| pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 1.5.0 | 2023/06/06 | PHP8.5対応, pahooInputData.php導入 |
| 1.4.1 | 2023/06/06 | Apple M2 Ultra追加 |
| 1.4.0 | 2023/05/05 | グラフにフッタを追加 |
| 1.3.1 | 2023/01/20 | Z80, MOS 6502, MC68000 など追加 |
| 1.3.0 | 2023/01/20 | 同じ年のCPUがあったら,トランジスタ数が多い方を採用する. |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.0.1 | 2025/08/11 | getParam() bug-fix |
| 2.0.0 | 2025/08/11 | pahooLoadEnv() 追加 |
| 1.9.0 | 2025/07/26 | getParam() 引数に$trim追加 |
| 1.8.1 | 2025/03/15 | validRegexPattern() debug |
| 1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
準備:pahooInputData 関数群
また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
準備:JpGraphライブラリ
Moore.php
53: // JpGraph:include_pathが通ったディレクトリに配置すること
54: require_once('jpgraph/jpgraph.php');
55: require_once('jpgraph/jpgraph_line.php');
56: require_once('jpgraph/jpgraph_log.php');
57:
JpGraph は、サーバ側(PHP側)でグラフを画像データとして生成し、クライアントへ配信する。このため、GDライブラリが有効化されていることが前提である。
また、使用する機能によってインクルードする PHPファイルの種類が異なることに留意してほしい。
公式サイトからダウンロードしたファイルを解凍したら、include_path が通ったディレクトリに配置してほしい。
凡例やラベルに日本語を使う場合は、日本語フォント(TrueTypeファイル)を用意しておく。これについても、アシアル社のサイトに詳しい説明がある。
具体的には、フォント・ファイルを格納したフォルダを "jpg-config.inc.php" の定数 TTF_DIR および MBTTF_DIR に設定してやる。
実際に使うフォントは "jpgraph_ttf.inc.php" の定数 MINCHO_TTF_FONT、PMINCHO_TTF_FONT、GOTHIC_TTF_FONT、PGOTHIC_TTF_FONT に設定されている。デフォルトで設定されているのは IPA の無償フォントで、文字情報技術促進協議会の IPAフォントから入手できる。
準備:各種定数など
Moore.php
58: // 各種定数(START) ===========================================================
59:
60: // 表示幅(ピクセル)
61: define('WIDTH', 500);
62:
63: // エラー表示用フォント・ファイル名;各自の環境に合わせて
64: define('FONT', '../../../../common/font/ipagp.ttf');
65:
66: // 各種定数(END) ===============================================================
解説:マイクロプロセッサ情報
Moore.php
68: // マイクロプロセッサの情報
69: // 年 マイクロプロセッサ クロック(Hz) プロセス(m) トランジスタ数
70: // *印のマイクロプロセッサはグラフ上に名称表示
71: $DataCPU =<<< EOT
72: 1971 *4004 7.40E+05 1.00E-05 2.30E+03
73: 1972 8008 5.00E+05 1.00E-05 3.50E+03
74: 1974 *8080 2.00E+06 6.00E-06 4.50E+03
75: 1975 MOS 6502 3.00E+06 8.00E-06 3.51E+03
76: 1976 *Z80 6.00E+06 4.00E-06 8.50E+03
77: 1979 *8086 5.00E+06 3.00E-06 2.90E+04
78: 1980 MC68000 2.00E+07 3.50E-06 6.80E+04
79: 1982 *80286 1.20E+07 1.50E-06 1.34E+05
80: 1985 *80386 1.60E+07 1.50E-06 2.75E+05
81: 1986 R2000 1.50E+07 2.00E-06 1.10E+05
82: 1987 MC68030 5.00E+07 8.00E-07 3.00E+05
83: 1989 *80486 1.60E+08 1.00E-06 1.19E+06
84: 1991 R4000 1.50E+08 1.00E-06 1.20E+06
85: 1993 *Pentium 6.00E+07 8.00E-07 3.10E+06
86: 1994 PowerPC 603 3.00E+08 2.90E-07 2.60E+06
87: 1995 PentiumPro 1.50E+08 6.00E-07 5.50E+06
88: 1997 *PentiumII 2.33E+08 3.50E-07 7.50E+06
89: 1999 PentiumIII 4.50E+08 2.50E-07 9.50E+06
90: 2000 *Pentium4 1.30E+09 1.80E-07 4.20E+07
91: 2005 *PentiumM 9.00E+08 1.30E-07 7.70E+07
92: 2006 CoreDuo 1.07E+09 6.50E-08 1.51E+08
93: 2006 Core2 Duo 1.60E+09 6.50E-08 1.67E+08
94: 2009 *Core i7-860 2.80E+09 4.50E-08 7.74E+08
95: 2011 Core i7-2700K 3.50E+09 3.20E-08 1.16E+09
96: 2012 Core i7-3770K 3.50E+09 2.20E-08 1.40E+09
97: 2014 Core i7-5960X 3.00E+09 2.20E-08 2.60E+09
98: 2016 *Core i7-6950X 3.00E+09 1.40E-08 3.20E+09
99: 2017 Ryzen 7 1800X 4.00E+09 1.40E-08 4.80E+09
100: 2018 A12 Bionic 2.49E+09 7.00E-09 6.90E+09
101: 2020 *Apple M1 3.20E+09 5.00E-09 1.60E+10
102: 2021 Apple M1 Max 3.20E+09 5.00E-09 5.70E+10
103: 2022 Ryzen 9 7950X 5.70E+09 5.00E-09 1.31E+10
104: 2022 Apple M1 Ultra 3.20E+09 5.00E-09 1.14E+11
105: 2022 Apple M2 3.49E+09 5.00E-09 2.00E+10
106: 2023 Apple M2 Max 3.49E+09 5.00E-09 6.70E+10
107: 2023 *Apple M2 Ultra 3.49E+09 5.00E-09 13.40E+10
108:
109: EOT;
Moore.php
139: /**
140: * 指定したCPUデータ文字列を分解し,配列に格納する.
141: * 文字列の行区切りは改行,列区切りはタブ(複数可).
142: * @param string $sour 入力文字列
143: * @param array $dest 結果を格納する2次元配列
144: * @return int 分解した行数
145: */
146: function str2matrix($sour, &$dest) {
147: $arr1 = preg_split("/\n/ui", $sour);
148: $cnt1 = 0;
149: foreach ($arr1 as $val1) {
150: $str = preg_replace("/\n/ui", '', $val1);
151: if (mb_strlen($str) < 1) continue;
152: $arr2 = preg_split("/[\t]+/ui", $str);
153: $cnt2 = 0;
154: foreach ($arr2 as $val2) {
155: $dest[$cnt1][$cnt2] = $val2;
156: $cnt2++;
157: }
158: $cnt1++;
159: }
160:
161: return $cnt1;
162: }
グラフ描画の前に、これを行×列の2次元配列に展開する目的で、ユーザー関数 str2matrix を用意した。他の用途でも使えるだろう。
解説:描画用配列に変換
Moore.php
164: /**
165: * CPUデータ配列をJpGraph描画用配列に変換する.
166: * 同じ年のCPUがあったら,トランジスタ数が多い方を採用する.
167: * @param array $matrix CPUデータ配列
168: * @param array $items 描画用配列
169: * @return array(最小年,最大年) 描画用配列
170: */
171: function matrix2items($matrix, &$items) {
172: // データの分解
173: $year_min = 99999;
174: $year_max = 0;
175: foreach ($matrix as $val) {
176: $year = (int)$val[0];
177: if ($year < $year_min) $year_min = $year;
178: if ($year > $year_max) $year_max = $year;
179: // 同じ年のCPUがあったら,トランジスタ数が多い方を採用する.
180: if (isset($items[$year])) {
181: if ((float)$val[4] > $items[$year]['transistors']) {
182: $items[$year]['CPU'] = (string)$val[1];
183: $items[$year]['clock'] = (float)$val[2];
184: $items[$year]['process'] = (float)$val[3];
185: $items[$year]['transistors'] = (float)$val[4];
186: }
187: // 同じ年のCPUがなければ,そのまま採用する.
188: } else {
189: $items[$year]['CPU'] = (string)$val[1];
190: $items[$year]['clock'] = (float)$val[2];
191: $items[$year]['process'] = (float)$val[3];
192: $items[$year]['transistors'] = (float)$val[4];
193: }
194: }
195:
196: return array($year_min, $year_max);
197: }
そこで、ユーザー関数 str2matrix で変換したデータを、さらに、西暦年×列名という2次元配列に変換するためのユーザー関数 matrix2items を用意した。
解説:グラフを描く
Moore.php
219: /**
220: * 指定した描画用データ配列によりJpGraphに対数グラフを描画する.
221: * @param array $items 描画用データ配列
222: * @param int $year_min 最小年
223: * @param int $year_max 最大年
224: * @return object graphオブジェクト
225: */
226: function drawGraph($items, $year_min, $year_max) {
227: $plotdata = array();
228:
229: // 横軸(西暦年)の作成
230: $x0 = floor($year_min / 5) * 5;
231: $x1 = ceil($year_max / 5) * 5;
232: $i = 1;
233: for ($year = $x0; $year <= $x1; $year++) {
234: $data_x[$year - $x0] = $year;
235: }
236:
237: // グラフ描画処理開始
238: $graph = new Graph(600, 500, 'auto');
239: $graph->SetScale('linlog'); // X軸:整数,Y軸:対数
240: $graph->SetBackgroundGradient('#FFFFCC','#FFFFCC', GRAD_HOR, BGRAD_MARGIN);
241:
242: // タイトル、凡例などの設定
243: $graph->img->SetImgFormat('png');
244: $graph->img->SetMargin(60, 60, 20, 40);
245: $graph->title->SetFont(FF_PGOTHIC, FS_NORMAL, 16);
246: $graph->title->Set('ムーアの法則');
247: $graph->xaxis->title->SetFont(FF_PGOTHIC);
248: $graph->xaxis->SetTitle('年','center');
249: $graph->xaxis->SetTickLabels($data_x);
250: $graph->xaxis->SetTextTickInterval(5);
251: $graph->xaxis->SetTextLabelInterval(2);
252: $graph->yaxis->title->SetFont(FF_PGOTHIC);
253: $graph->yaxis->title->Set('トランジスタ数');
254: $graph->yaxis->SetTitleMargin(40);
255: // フッタを設定する.
256: $graph->footer->right->SetFont(FF_PGOTHIC, FS_NORMAL, 10);
257: $graph->footer->right->Set('produced by JpGraph');
258:
259: // プロット配列を作成
260: for ($year = $x0; $year <= $x1; $year++) {
261: $data_y1[$year - $x0] = isset($items[$year]) ? (float)$items[$year]['transistors'] : '-';
262: $data_y2[$year - $x0] = 2.30E+03 * pow(2, ($year - $year_min) / (float)(18 / 12));
263: $data_y3[$year - $x0] = 2.30E+03 * pow(2, ($year - $year_min) / (float)(24 / 12));
264: }
265:
266: // ムーアの法則:18ヶ月ごとに2倍
267: $plotdata = new LinePlot($data_y2);
268: $graph->Add($plotdata);
269: $plotdata->SetWeight(2); // 太さ
270: $plotdata->SetColor('royalblue'); // 色
271: $plotdata->SetLegend('18ヶ月ごとに2倍'); // 凡例
272:
273: // ムーアの法則:24ヶ月ごとに2倍
274: $plotdata = new LinePlot($data_y3);
275: $graph->Add($plotdata);
276: $plotdata->SetWeight(2); // 太さ
277: $plotdata->SetColor('green'); // 色
278: $plotdata->SetLegend('24ヶ月ごとに2倍'); // 凡例
279:
280: // マイクロプロセッサ
281: $plotdata = new LinePlot($data_y1);
282: $graph->Add($plotdata);
283: $plotdata->SetColor('deeppink'); // 色
284: $plotdata->SetWeight(2); // 太さ
285: $plotdata->mark->SetTYPE(MARK_DIAMOND); // プロット記号
286: $plotdata->value->SetFormatCallback('CPUname');
287: $plotdata->value->show();
288: $plotdata->SetLegend('マイクロプロセッサ'); // 凡例
289:
290: // 凡例
291: $graph->legend->SetFont(FF_PGOTHIC); // フォント
292: $graph->legend->SetColumns(1); // 表示列数
293: $graph->legend->SetPos(0.12, 0.9, 'right', 'bottom'); // 位置
294:
295: return $graph;
296: }
まず、X軸を用意する。西暦年を5年刻みで、最小年と最大年を設定する。
次に、グラフ描画処理の開始とタイトル、凡例などの設定を行う。このあたりは「インフルエンザ患者数のグラフを作る」とほぼ同じである。
続けて、プロット用の配列を3つ $data_y1, $data_y2, $data_y3 作る。
配列 $data_y1 には、マイクロプロセッサのトランジスタ数を代入する。最初に与えられたデータにない年は、'-' を代入することで、折れ線グラフを自動的に繋げてくれる。ここで空文字 '' を代入すると、グラフは途切れる。
1971年(昭和46年)に発売された4004のトランジスタ数を基準に、18ヶ月ごとに2倍にした値は配列 $data_y2 に、24ヶ月ごとに2倍にした値は配列 $data_y3 に、それぞれ代入する。2のべき乗を計算するために組み込み関数 pow を用いている。
ちなみに、当初のムーアの法則では「18ヶ月ごと」だったが、その後のトランジスタ数の増加が減速し、「24ヶ月」に訂正したという経緯がある。
最後に、プロット用の配列を描画していく。
配列 $data_y1 を描く際に、$plotdata->value->SetFormatCallback を使ってデータポイントにマイクロプロセッサ名を表示させている。本来、データポイントにはY値(ここではトランジスタ数)が表示されるのだが、コールバックされるユーザー関数 CPUname において受け取ったトランジスタとデータ表を照合し、マイクロプロセッサ名を返すようにしていることで、グラフ上にマイクロプロセッサ名が表示されるという仕組みである。
すべてのマイクロプロセッサ名が表示されると重なって見にくくなるので、冒頭にアスタリスクが付いているマイクロプロセッサ名だけを表示するようにしている。
解説:画面出力
コマンドライン・オプション img が指定された場合は、出力データをimgタグの中に画像データを埋め込むための文字列を生成する。詳しくは、「PHPでTrueTypeフォントを利用する(その2)」-「解説:画像をHTMLコンテンツに埋め込む」を参照のこと。
参考サイト
- JpGraph公式サイト
- アシアル株式会社
- PHPとJpGraphで人口ピラミッドを表示する:ぱふぅ家のホームページ
- インフルエンザ患者数のグラフを作る:ぱふぅ家のホームページ
- Transistor count:Wikipedia
- 2021年、ムーアの法則が崩れる?:ITmedia
- ムーアの法則の終焉:bibble-babble
- 「ムーアの法則」と「パラダイス鎖国」:地図屋の視点
- ソフトウェアもムーアの法則で巨大化する:プログラマの思索
- ムーアの法則は2014年で終焉を迎える …らしい。:ひでのブログ

(2026年3月15日)PHP8.5対応, pahooInputData.php導入