Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

アラートダイアログ上にWkWebViewでGoogle Chartsを表示 v2

Posted on 4月 29, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを配置し、Google Chartsを用いてPie Chartを表示するAppleScriptです。

自分の開発環境(MacBook Pro Retina 2012, Core i7 2.6GHz)で10日間のアクセス履歴を処理して1.38秒程度でダイアログ表示してグラフ描画に入ります。3秒強ぐらいで描画が終了します。

WkWebViewに対して、文字列で組み立てたHTMLを読み込んでグラフ表示しています。Pie Chart上にマウスカーソルを乗せると反応します。一応表示できているぐらいで、デザイン的には余計な余白ができたままで、いまひとつな感じです。せめて、WkWebViewの背景を透明化できると大味な表示をいくらか緩和できるかと思っているのですが、WkWebViewの透明背景にはNSColorではなく(AppleScriptから作成できない)CGColorでclearColor(透明色)を指定する必要があるようで、、、、

サンプル表示データは、Safariの10日間のアクセス履歴からドメイン単位で計算したヒストグラムを、その場で計算したものを使っています。

本Scriptは、①NSAlertのダイアログ表示の経験 ②WkWebView上へのコンテンツ表示の経験 ③グラフ表示用FrameworkやSVGベースのグラフ作成の経験 を経て、2・3年越しで完成したものです。とくに、WkWebViewについてはサンプル数がそれほど多くなく、用途の方向性がObjective-CやSwiftと若干異なるために、参考にできるサンプルの数が多くない状況。必然的に、いろいろ試しては失敗を重ねてきました。急に出来上がってきたものではありません。

Safariの履歴集計ScriptをScriptオブジェクトの中に放り込んだら、scripting additionsの用語をusing terms from句で囲っておく必要がありました。何回か経験していますが、知らないと対処に困る現象です。

現状(macOS 10.14以降)では、Scripting AdditionはmacOS標準搭載のStandard Additionsしか存在していないし認識も行われないため、エラー内容がいまひとつわかりにくく、不正確であるように思えます。Apple純正のStandard Additionsしか存在していないんだから自分で判断しろやコラ、と言いたくなります。

AppleScript名:アラートダイアログ上にWebViewでGoogle Chartを表示 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/03/02
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property NSAlert : a reference to current application’s NSAlert
property NSString : a reference to current application’s NSString
property NSButton : a reference to current application’s NSButton
property WKWebView : a reference to current application’s WKWebView
property WKUserScript : a reference to current application’s WKUserScript
property NSURLRequest : a reference to current application’s NSURLRequest
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property WKUserContentController : a reference to current application’s WKUserContentController
property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration
property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd

property returnCode : 0

–Calc Safari access domain from history
set aRes to calcSafariHistoryBest10Domain(10) of safariHistoryLib

set aList to {{"Domain", "Access"}}
repeat with i in aRes
  set aDom to theName of i
  
set accessNum to numberOfTimes of i
  
set the end of aList to {aDom, accessNum}
end repeat

–set aList to {{"Task", "Hours per Day"}, {"Work", 8}, {"Eat", 2}, {"TV", 4}, {"Gym", 2}, {"Sleep", 8}}

set aJsonArrayStr to array2DToJSONArray(aList) of me

–Pie Chart Template HTML
set myStr to "<!DOCTYPE html>
<html lang=\"UTF-8\">
<body>
<div id=\"piechart\"></div>

<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>

<script type=\"text/javascript\">
// Load google charts
google.charts.load(’current’, {’packages’:[’corechart’]});
google.charts.setOnLoadCallback(drawChart);

// Draw the chart and set the chart values
function drawChart() {
var data = google.visualization.arrayToDataTable(%@);

// Optional; add a title and set the width and height of the chart
var options = {’title’:’’, ’width’:600, ’height’:400};

// Display the chart inside the <div> element with id=\"piechart\"
var chart = new google.visualization.PieChart(document.getElementById(’piechart’));
chart.draw(data, options);
}
</script>

</body>
</html>"

set aString to current application’s NSString’s stringWithFormat_(myStr, aJsonArrayStr) as string

set paramObj to {myMessage:"Pie Chart Test", mySubMessage:"This is a simple pie chart using google charts", htmlStr:aString}
–my browseStrWebContents:paramObj–for debug
my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true

on browseStrWebContents:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set htmlString to (htmlStr of paramObj)
  
  
set aWidth to 600
  
set aHeight to 450
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定HTML内のJavaScriptをFetch
  
set jsSource to pickUpFromToStr(htmlString, "<script type=\"text/javascript\">", "</script>") of me
  
  
set userScript to WKUserScript’s alloc()’s initWithSource:jsSource injectionTime:(WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true
  
set userContentController to WKUserContentController’s alloc()’s init()
  
userContentController’s addUserScript:(userScript)
  
aConf’s setUserContentController:userContentController
  
  
set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight – 100)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
  
set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
  
aWebView’s loadHTMLString:htmlString baseURL:(bURL)
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
–its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aWebView
    
    
set myWindow to its |window|
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
  
–Stop Web View Action
  
set bURL to |NSURL|’s URLWithString:"about:blank"
  
set bReq to NSURLRequest’s requestWithURL:bURL
  
aWebView’s loadRequest:bReq
  
  
if (my returnCode as number) = 1001 then error number -128
end browseStrWebContents:

on doModal:aParam
  set (my returnCode) to (aParam’s runModal()) as number
end doModal:

on viewDidLoad:aNotification
  return true
end viewDidLoad:

on fetchJSSourceString(aURL)
  set jsURL to |NSURL|’s URLWithString:aURL
  
set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value)
  
return jsSourceString
end fetchJSSourceString

on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string)
  set a1Offset to offset of s1Str in aStr
  
if a1Offset = 0 then return false
  
set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr
  
set a2Offset to offset of s2Str in bStr
  
if a2Offset = 0 then return false
  
set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr
  
return cStr as string
end pickUpFromToStr

–リストを任意のデリミタ付きでテキストに
on retArrowText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retArrowText

on array2DToJSONArray(aList)
  set anArray to current application’s NSMutableArray’s arrayWithArray:aList
  
set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value) –0 is
  
set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding)
  
return resString
end array2DToJSONArray

–Safariのn日前からの履歴をドメイン別に集計してソート
script safariHistoryLib
  use scripting additions
  
use framework "Foundation"
  
property parent : AppleScript
  
  
property |NSURL| : a reference to current application’s |NSURL|
  
  
script spd
    property sList : {}
    
property nList : {}
    
property sRes : {}
  end script
  
  
  
on calcSafariHistoryBest10Domain(daysBefore)
    –現在日時のn日前を求める
    
using terms from scripting additions
      set origDate to (current date) – (daysBefore * days)
    end using terms from
    
set dStr to convDateObjToStrWithFormat(origDate, "yyyy-MM-dd hh:mm:ss") of me
    
    
set aDBpath to "~/Library/Safari/History.db"
    
set pathString to current application’s NSString’s stringWithString:aDBpath
    
set newPath to pathString’s stringByExpandingTildeInPath()
    
    
set aText to "sqlite3 " & newPath & " ’SELECT datetime(history_visits.visit_time+978307200, \"unixepoch\", \"localtime\"), history_visits.title || \" @ \" || substr(history_items.URL,1,max(length(history_items.URL)*(instr(history_items.URL,\" & \")=0),instr(history_items.URL,\" & \"))) as Info FROM history_visits INNER JOIN history_items ON history_items.id = history_visits.history_item where history_visits.visit_time>(julianday(\"" & dStr & "\")*86400-211845068000) ORDER BY visit_time ASC LIMIT 999999;’"
    
    
using terms from scripting additions
      set (sRes of spd) to do shell script aText
    end using terms from
    
    
set (sList of spd) to (paragraphs of (sRes of spd))
    
    
set (nList of spd) to {}
    
    
repeat with i in (sList of spd)
      set j to contents of i
      
      
–Parse each field
      
set j2 to parseByDelim(j, {"|", "@ "}) of me
      
      
–Calculate URL’s domain only
      
set j3 to contents of last item of j2
      
set aURL to (|NSURL|’s URLWithString:j3)
      
      
if aURL = missing value then
        set j4 to ""
      else
        set j4 to (aURL’s |host|()) as string
      end if
      
      
set the end of (nList of spd) to j4
    end repeat
    
    
–登場頻度でURLを集計
    
set aList to countItemsByItsAppearance((nList of spd)) of me
    
    
    
–Best 10の計算のために10位以下をまとめる
    
set best9 to items 1 thru 9 of aList
    
set best10 to items 10 thru -1 of aList
    
    
set otherTimes to 0
    
repeat with i in best10
      set otherTimes to otherTimes + (numberOfTimes of i)
    end repeat
    
    
set the end of best9 to {theName:"Other", numberOfTimes:otherTimes}
    
return best9
  end calcSafariHistoryBest10Domain
  
  
  
  
on parseByDelim(aData, aDelim)
    set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to aDelim
    
set dList to text items of aData
    
set AppleScript’s text item delimiters to curDelim
    
return dList
  end parseByDelim
  
  
  
–出現回数で集計
  
on countItemsByItsAppearance(aList)
    set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
    
set bArray to current application’s NSMutableArray’s array()
    
set theEnumerator to aSet’s objectEnumerator()
    
    
repeat
      set aValue to theEnumerator’s nextObject()
      
if aValue is missing value then exit repeat
      
bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"theName", "numberOfTimes"})
    end repeat
    
    
–出現回数(numberOfTimes)で降順ソート
    
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"numberOfTimes" ascending:false
    
bArray’s sortUsingDescriptors:{theDesc}
    
    
return bArray as list
  end countItemsByItsAppearance
  
  
  
on convDateObjToStrWithFormat(aDateO as date, aFormatStr as string)
    set aDF to current application’s NSDateFormatter’s alloc()’s init()
    
    
set aLoc to current application’s NSLocale’s currentLocale()
    
set aLocStr to (aLoc’s localeIdentifier()) as string
    
    
aDF’s setLocale:(current application’s NSLocale’s alloc()’s initWithLocaleIdentifier:aLocStr)
    
aDF’s setDateFormat:aFormatStr
    
set dRes to (aDF’s stringFromDate:aDateO) as string
    
return dRes
  end convDateObjToStrWithFormat
  
end script

★Click Here to Open This Script 

More from my site

  • アラートダイアログ上にWebViewでGoogle Chartsを表示(Calendar Chart)アラートダイアログ上にWebViewでGoogle Chartsを表示(Calendar Chart)
  • アラートダイアログ上にWebViewでCesiumを用いて地球儀上に地図を表示アラートダイアログ上にWebViewでCesiumを用いて地球儀上に地図を表示
  • アラートダイアログ上のWebViewでGio.jsを用いて地球儀+データアニメーション表示 v2aアラートダイアログ上のWebViewでGio.jsを用いて地球儀+データアニメーション表示 v2a
  • アラートダイアログ上にWebViewでChart.jsを表示(Pie Chart) v2アラートダイアログ上にWebViewでChart.jsを表示(Pie Chart) v2
  • アラートダイアログ上にd3-cloudを用いてワードクラウドを表示アラートダイアログ上にd3-cloudを用いてワードクラウドを表示
  • アラートダイアログ上にWebViewでGoogle Chartを表示(Column Chart)アラートダイアログ上にWebViewでGoogle Chartを表示(Column Chart)
(Visited 66 times, 1 visits today)
Posted in dialog Web Contents Control | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSButton NSRunningApplication NSString NSURL NSURLRequest NSUTF8StringEncoding Safari WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | 1 Comment

1 thoughts on “<span>アラートダイアログ上にWkWebViewでGoogle Chartsを表示 v2</span>”

  1. 12/10/21
    5:03 PM
    2021年12月10日
    5:03 PM

    Reply

    2020年に書いた価値あるAppleScript – AppleScriptの穴 says:

    […] アラートダイアログ上にWkWebViewでGoogle Chartsを表示 v2 […]

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • macOS 13, Ventura(継続更新)
  • アラートダイアログ上にWebViewで3Dコンテンツを表示(WebGL+three.js)v3
  • UI Browserがgithub上でソース公開され、オープンソースに
  • Xcode 14.2でAppleScript App Templateを復活させる
  • macOS 13 TTS Voice環境に変更
  • 2022年に書いた価値あるAppleScript
  • ChatGPTで文章のベクトル化(Embedding)
  • 新発売:AppleScriptからSiriを呼び出そう!
  • iWork 12.2がリリースされた
  • 従来と異なるmacOS 13の性格?
  • 新発売:CotEditor Scripting Book with AppleScript
  • macOS 13対応アップデート:AppleScript実践的テクニック集(1)GUI Scripting
  • AS関連データの取り扱いを容易にする(はずの)privateDataTypeLib
  • macOS 12.5.1、11.6.8でFinderのselectionでスクリーンショット画像をopenできない問題
  • macOS 13でNSNotFoundバグふたたび
  • ChatGPTでchatに対する応答文を取得
  • 新発売:iWork Scripting Book with AppleScript
  • Finderの隠し命令openVirtualLocationが発見される
  • macOS 13.1アップデートでスクリプトエディタの挙動がようやくまともに
  • あのコン過去ログビューワー(暫定版)

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1390) 10.14savvy (586) 10.15savvy (434) 11.0savvy (277) 12.0savvy (185) 13.0savvy (55) CotEditor (60) Finder (47) iTunes (19) Keynote (98) NSAlert (60) NSArray (51) NSBezierPath (18) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (51) NSDictionary (27) NSFileManager (23) NSFont (18) NSImage (41) NSJSONSerialization (21) NSMutableArray (62) NSMutableDictionary (21) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (117) NSURL (97) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (56) Pages (37) Safari (41) Script Editor (20) WKUserContentController (21) WKUserScript (20) WKUserScriptInjectionTimeAtDocumentEnd (18) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • Clipboard
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • drive
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC