指定データをもとに縦棒グラフの画像をデスクトップフォルダ上に作成するAppleScriptです。
グラフの画像を作ろうとしたら、Keynote上で作成して画像書き出しするとかExcel上でグラフを作成して画像書き出しすることを考えますが、アプリケーションを利用しないでグラフ画像を作ってみました。
一応、Github上で探し回ってみるとObjective-Cで書かれたグラフ描画プログラムはいくつかあって、Xcode上のGUIアプリケーションであれば使えたりするものの、スクリプトエディタ上で実行するAppleScriptでは描画できていませんでした。
「このぐらいだったら、自分で描けばいいんじゃね?」
と、ありもののサブルーチンを組み合わせてみたら、割とさっくりできました。実行すると0.02秒ぐらいでグラフ画像を作成します(HDD環境だともう少し時間がかかるかも)。
自前グラフ作成Scriptといえば、Adobe Illustratorのグラフ機能で作成したグラフをグループ解除しまくって自動装飾するものを昔に作った覚えがあります。
AppleScript名:画像の指定エリアを塗りつぶしで縦棒グラフを作成 v3 |
— Created 2017-11-19 by Takaaki Naganoya — Modified 2018-04-01 by Takaaki Naganoya use AppleScript version "2.5" use scripting additions use framework "Foundation" use framework "AppKit" property NSUUID : a reference to current application’s NSUUID property NSColor : a reference to current application’s NSColor property NSString : a reference to current application’s NSString property NSImage : a reference to current application’s NSImage property NSScreen : a reference to current application’s NSScreen property NSBezierPath : a reference to current application’s NSBezierPath property NSPNGFileType : a reference to current application’s NSPNGFileType property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep set plotData to {20, 30, 100, 80, 150, 90} set plotArea to {300, 200} set innerGapL to 30 set innerGapU to 10 set innerGapR to 20 set innerGapD to 20 set barGap to 10 –パラメータから下地になる画像を作成する set aSize to current application’s NSMakeSize(first item of plotArea, second item of plotArea) set anImage to NSImage’s alloc()’s initWithSize:aSize –各種パラメータの計算 copy plotArea to {plotWidth, plotHeight} set itemNum to count every item of plotData set barThickness to (plotWidth – (itemNum * barGap * 2)) div itemNum –プロットデータの最大値 set anArray to current application’s NSArray’s arrayWithArray:plotData set aYmax to (anArray’s valueForKeyPath:"@max.self")’s intValue() set aMaxYVal to plotHeight – innerGapU – innerGapD set aYPlotArea to plotHeight – innerGapU – innerGapD – 20 set aYUnit to aYPlotArea / aYmax –数値データをもとに描画データを組み立てる set drawList to {} set startX to innerGapL copy startX to origX repeat with i in plotData set the end of drawList to current application’s NSMakeRect(startX, innerGapD, barThickness, innerGapD + (i * aYUnit)) set startX to startX + barThickness + barGap end repeat –グラフ塗りつぶし処理呼び出し set fillColor to (NSColor’s colorWithCalibratedRed:0.1 green:0.1 blue:0.1 alpha:0.3) set resImage to drawImageWithColorFill(anImage, drawList, fillColor) of me –数値データ(文字)をグラフィックに記入 set fillColor2 to NSColor’s blackColor() set resImage to drawImageWithString(resImage, drawList, fillColor2, plotData, "HiraginoSans-W1", 16.0) of me –補助線を引く set fillColor3 to (NSColor’s colorWithCalibratedRed:0.0 green:0.0 blue:0.0 alpha:0.8) set aVertical to current application’s NSMakeRect(origX, innerGapD, plotWidth – innerGapL – innerGapR, 1) set aHorizontal to current application’s NSMakeRect(origX, innerGapD, 1, plotHeight – innerGapU – innerGapD) set draw2List to {aVertical, aHorizontal} set resImage to drawImageWithColorFill(resImage, draw2List, fillColor3) of me –画像のファイル出力 set imgPath to POSIX path of (path to desktop folder) set aUUIDstr to (NSUUID’s UUID()’s UUIDString()) as string set aPath to ((NSString’s stringWithString:imgPath)’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:"png" set fRes to saveImageRepAtPathAsPNG(resImage, aPath) of me –NSImageに対して文字を描画する on drawImageWithString(anImage, drawList, fillColor, dataList, aPSFontName, aFontSize) set retinaF to (NSScreen’s mainScreen()’s backingScaleFactor()) as real –> 2.0 (Retina) / 1.0 (Non Retina) set aDict to (current application’s NSDictionary’s dictionaryWithObjects:{current application’s NSFont’s fontWithName:aPSFontName |size|:aFontSize, fillColor} forKeys:{current application’s NSFontAttributeName, current application’s NSForegroundColorAttributeName}) anImage’s lockFocus() –描画開始 set aLen to length of drawList repeat with i from 1 to aLen set i1 to contents of item i of drawList set origX to (x of origin of i1) / retinaF set origY to (y of origin of i1) / retinaF set sizeX to (width of |size| of i1) / retinaF set sizeY to (height of |size| of i1) / retinaF set aString to (current application’s NSString’s stringWithString:((contents of item i of dataList) as string)) (aString’s drawAtPoint:(current application’s NSMakePoint(origX + (sizeX / 2), sizeY)) withAttributes:aDict) end repeat anImage’s unlockFocus() –描画ここまで return anImage –returns NSImage end drawImageWithString –NSImageに対して矩形を塗りつぶす on drawImageWithColorFill(anImage, drawList, fillColor) set retinaF to (NSScreen’s mainScreen()’s backingScaleFactor()) as real –> 2.0 (Retina) / 1.0 (Non Retina) anImage’s lockFocus() –描画開始 repeat with i in drawList set origX to (x of origin of i) / retinaF set origY to (y of origin of i) / retinaF set sizeX to (width of |size| of i) / retinaF set sizeY to (height of |size| of i) / retinaF set theRect to {{x:origX, y:origY}, {width:sizeX, height:sizeY}} set theNSBezierPath to NSBezierPath’s bezierPath (theNSBezierPath’s appendBezierPathWithRect:theRect) fillColor’s |set|() –色設定 theNSBezierPath’s fill() –ぬりつぶし end repeat anImage’s unlockFocus() –描画ここまで return anImage –returns NSImage end drawImageWithColorFill –画像を指定パスにPNG形式で保存 on saveImageRepAtPathAsPNG(anImage, outPath) set imageRep to anImage’s TIFFRepresentation() set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep –パスのチルダ展開処理 set pathString to NSString’s stringWithString:outPath set newPath to pathString’s stringByExpandingTildeInPath() set myNewImageData to (aRawimg’s representationUsingType:(NSPNGFileType) |properties|:(missing value)) return (myNewImageData’s writeToFile:newPath atomically:true) as boolean end saveImageRepAtPathAsPNG |
More from my site
(Visited 55 times, 1 visits today)