前回までで、Webページからデータを抽出して棒グラフの画像データを生成するPowerShellスクリプトを作成した。次は、このスクリプトをベースに、より汎用的に使用できるように書き換えていく。
→連載「PowerShell Core入門 - 基本コマンドの使い方」の過去回はこちらを参照。
CSVデータを活用した汎用的なグラフ作成
前回までに作成したPowerShellスクリプトは、そのままでもそれなりに使えるはずだ。ただし、もっと汎用的に使えるようにするには少し中身を整理して、整える必要がある。
まずはデータを用意する部分と、データをグラフに加工する部分を分ける。データについては、CSVで公開しているWebサイトも多いので、とりあえずCSVデータをグラフの元データとする。PowerShellにはCSVデータをインポート/エクスポートする機能が用意されているので、データ形式としてCSVデータを使うのはその意味でも理にかなっている。
csv2barchart.ps1:最初の一歩
まず、前回まではWebページから取得していたデータを、いったん次のようなCSVデータ「data.csv」としてファイルに保存しておく。
"場所","気温"
"小河内","17.6"
"青梅","20.8"
"練馬","21.4"
"八王子","20.2"
"府中","20.7"
"東京","21.3"
"江戸川臨海","19.6"
"羽田","18.7"
"大島","19.8"
"大島北ノ山","19.2"
"新島","18.8"
"神津島","17.9"
"三宅島","19.0"
"三宅坪田","20.6"
"八重見ヶ原","21.2"
"八丈島","20.5"
"父島","24.2"
そして前回のPowerShellスクリプトを次のように書き換える(csv2barchart.ps1)。
#!/usr/bin/env pwsh
#========================================================================
# 利用するファイルやURLなど
#========================================================================
$CSVFile = $Args[0]
$OutFile = $env:HOMEDRIVE + $env:HOMEPATH + '\out.html'
$PNGFile = $env:HOMEDRIVE + $env:HOMEPATH + '\out.png'
#========================================================================
# 気温データを取得
#========================================================================
$CsvData = Import-Csv $CSVFile -Header 1,2
# ヘッダを変数に格納
foreach ($Row in $CsvData) {
$CsvHeader1 = $Row.1
$CsvHeader2 = $Row.2
break
}
#========================================================================
# Google Charts用HTMLの用意
#========================================================================
$GraphTitle = '東京都の現在の気温'
$GoogleChartsHTML1 = @"
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// Google Visualization APIおよびコアチャートパッケージを読み込み
google.charts.load('current', {'packages':['corechart']});
// Google Visualization API読み込み完了後に実行
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
// データテーブルを作成
var data = new google.visualization.DataTable();
data.addColumn('string', '');
data.addColumn('number', '$CsvHeader2');
data.addRows([
"@
$GoogleChartsHTML2 = @"
]);
// チャートオプションを設定
var options = {'title':'$GraphTitle',
'width':2000,
'height':1200};
// 初期化およびチャートの生成
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
// チャートイメージをbase64エンコードされたPNG画像データとして出力
google.visualization.events.addListener(chart, 'ready', function () {
document.getElementById('chart_base64').innerHTML = chart.getImageURI();
});
// チャートを描画
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div"></div>
<div id="chart_base64"></div>
</body>
</html>
"@
#========================================================================
# CSVデータをGoogle Chartsで使える形式へ加工
#========================================================================
$GraphData = ""
$FirstLineIs = $true
foreach ($Row in $CsvData) {
if ($FirstLineIs) {
$FirstLineIs = $false
continue
}
$GraphData = $GraphData + "['" + $Row.1 + "'," + $Row.2 + "],"
}
$GraphData = $GraphData.trim(",")
#========================================================================
# Google Charts用のHTMLを出力
#========================================================================
$GoogleChartsHTML1 > $OutFile
$GraphData >>$OutFile
$GoogleChartsHTML2 >>$OutFile
#========================================================================
# WebDriver起動
#========================================================================
webdriver_edge_start.ps1
#========================================================================
# Microsoft EdgeでGoogle Charts用のHTMLをオープン
#========================================================================
$FileURL = "file:///" + $OutFile.Replace('\','/')
'Microsoft Edgeでグラフを描画します。'
Set-SeUrl -Url $FileURL
#========================================================================
# 描画されたグラフをBase64エンコードされたPNGデータとして取得
#========================================================================
'描画したグラフをBase64エンコードされたPNGデータとして取得します。'
$Element = Get-SeElement -By XPath -Value '//*[@id="chart_base64"]'
$Base64 = $Element.Text -replace 'data:image/png;base64,',''
#========================================================================
# Base64エンコードデータをデコードしてファイルへ保存
#========================================================================
'Base64エンコードされたPNGデータをデコードして保存します。'
$Bytes = [Convert]::FromBase64String($Base64)
[IO.File]::WriteAllBytes($PNGFile, $Bytes)
#========================================================================
# WebDriverを終了
#========================================================================
webdriver_edge_stop.ps1
#========================================================================
# 作業用の一時ファイルを削除
#========================================================================
Remove-Item $OutFile
このスクリプトを「.\csv2barchart.ps1 .\data.csv」のように実行すれば前回と同じような結果を得ることができる。