指定データをもとに縦棒グラフの画像をデスクトップフォルダ上に作成するAppleScriptです。
グラフの画像を作ろうとしたら、Keynote上で作成して画像書き出しするとかExcel上でグラフを作成して画像書き出しすることを考えますが、アプリケーションを利用しないでグラフ画像を作ってみました。
前バージョンがmacOS 10.13上で動作しなかったので、対処してみました。
▲macOS 10.13.5beta & macOS 10.12.6 (same result)
AppleScript名:画像の指定エリアを塗りつぶしで縦棒グラフを作成 v4 |
— 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 v2 to system attribute "sys2" if v2 ≤ 12 then –To macOS 10.12.x 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 theRect to {{x:origX, y:origY}, {width:sizeX, height:sizeY}} else –macOS 10.13 or later set origX to (item 1 of item 1 of i1) / retinaF set origY to (item 2 of item 1 of i1) / retinaF set sizeX to (item 1 of item 2 of i1) / retinaF set sizeY to (item 2 of item 2 of i1) / retinaF set theRect to {{origX, origY}, {sizeX, sizeY}} end if 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 v2 to system attribute "sys2" if v2 ≤ 12 then –To macOS 10.12.x 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}} else –macOS 10.13 or later set origX to (item 1 of item 1 of i) / retinaF set origY to (item 2 of item 1 of i) / retinaF set sizeX to (item 1 of item 2 of i) / retinaF set sizeY to (item 2 of item 2 of i) / retinaF set theRect to {{origX, origY}, {sizeX, sizeY}} end if 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 |