Elmメモ ドラッグ移動の実現(1)

ElmでSVGの要素をドラッグ移動したいと思った。ドラッグ操作を実現するパッケージにelm-draggableがある。今回は勉強として、それに頼らず実装することを試みる。elm-draggableを用いた方法については次回やる。 初期状態 詳細は省略するが、Elmプロジェクトを作成してelm/svgとelm/jsonをインストールしておく。 src/Main.elmは以下のようにしておく。elm reactorで動くことを確認する。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 module Main exposing (..) import Browser import Browser.Events as BE import Html exposing (..) import Html.Attributes exposing (..) import Json.Decode as JD import Svg as S exposing (Svg) import Svg.Attributes as SA import Svg.Events as SE main = Browser.element { init = init , update = update , view = view , subscriptions = subscriptions } type alias Model = {} type Msg = Dummy init : () -> ( Model, Cmd Msg ) init _ = ( {}, Cmd.none ) update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = ( model, Cmd.none ) view : Model -> Html Msg view model = div [] [] subscriptions : Model -> Sub Msg subscriptions model = Sub.none 目標 SVGの領域に円が複数存在する 円をドラッグ移動できるようにしたい。 円のドラッグ中はその色を橙色にし、それ以外のときは白にする 方針 ドラッグ処理については次の処理で実現することになる。 ...

2020-02-25 · (updated 2020-03-04) · 8 min · 1588 words

Vue.js勉強メモ(1) - 簡易Todoリストの作成

公式ガイドの、コンポーネントの詳細の手前まで読み終えたので、この時点でTodoリストっぽいものを作ってみる。データベースを用意しないため、厳密にはTodoリストではない。 コンポーネントについてはまだ学んでいないため、これから書くコードにはまだ改善の余地があるだろう。 準備 index.htmlを用意する。 1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html> <html lang="ja"> <head> <meta charet="utf-8"> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <h1>Todo List</h1> <script src="script.js"></script> </body> </html> 以下の部分でVue.jsを読み込んでいる。 1 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> script.jsを作成しておく。中身はまだ空。 実装する機能 初めにも述べたが、データベースは用意しない。以下の簡単な機能だけ実装する。 入力エリア Todoリスト表示エリア 各要素に削除ボタンをつける。 勉強を兼ねて、いくらか遠回りしながら作っていく。 配列の要素をli要素として表示 index.htmlに追記する。 1 2 3 4 5 <div id="app"> <ul> <li v-for="todo in todos">{{ todo }}</li> </ul> </div> Vue.jsが用意したテンプレート構文をHTMLに埋め込むことによって、データとDOMを結びつけることができる。v-という接頭辞がついた属性はディレクティブと呼ばれる。今回のv-forディレクティブは、その名の通りfor文を実現する。構文から分かると思うが、JSとかPythonで使われているfor-in文と同じ文法。 式の埋め込みは{{ 式 }}で行う。ガイドではMustache(口髭)構文と呼んでいる。良いネーミングだなと思ったけど、{{ }}の書式をそう呼ぶのはわりと一般的みたい? ...

2020-02-16 · (updated 2020-02-16) · 2 min · 306 words

GraphvizでTeXの数式を表示する(2) - PDFにしたい場合

TeXのレポートに貼り付けたいが、TeXではSVG形式は扱えないのでPDFにしたくなった。やってみたら思ったより面倒だったので備忘録として残す。 dotファイルの用意 前回と同じにする。ファイル名はgraph.dotとする。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 digraph { graph [ rankdir="LR" ]; node [ shape="circle", fixedsize=true, height=0.6 ]; Q0 [texlbl="$q_0$"]; Q1 [texlbl="$q_1$"]; Q2 [texlbl="$q_2$"]; Q3 [texlbl="$q_3$"]; Q4 [texlbl="$q_4$"]; Q5 [texlbl="$q_5$"]; Q6 [texlbl="$q_6$"]; Q7 [texlbl="$q_7$"]; Q8 [texlbl="$q_8$"]; Q9 [texlbl="$q_9$"]; Q10 [texlbl="$q_{10}$"]; Q11 [texlbl="$q_{11}$"]; Q12 [texlbl="$q_{12}$"]; Q13 [texlbl="$q_{13}$"]; Q0 -> Q1 [label=" ", texlbl="$\varepsilon$"]; Q0 -> Q4 [label=" ", texlbl="$\varepsilon$"]; Q0 -> Q7 [label=" ", texlbl="$\varepsilon$"]; Q1 -> Q2 [label=" ", texlbl="$a$"]; Q2 -> Q3 [label=" ", texlbl="$b$"]; Q3 -> Q7 [label=" ", texlbl="$\varepsilon$"]; Q4 -> Q5 [label=" ", texlbl="$b$"]; Q5 -> Q6 [label=" ", texlbl="$b$"]; Q6 -> Q7 [label=" ", texlbl="$\varepsilon$"]; Q7 -> Q8 [label=" ", texlbl="$a$"]; Q7 -> Q0 [label=" ", texlbl="$\varepsilon$"]; Q8 -> Q9 [label=" ", texlbl="$\varepsilon$"]; Q8 -> Q11 [label=" ", texlbl="$\varepsilon$"]; Q9 -> Q10 [label=" ", texlbl="$b$"]; Q10 -> Q13 [label=" ", texlbl="$\varepsilon$"]; Q11 -> Q12 [label=" ", texlbl="$c$"]; Q12 -> Q13 [label=" ", texlbl="$\varepsilon$"]; } dot → tex $ dot2tex graph.dot > graph.tex tex → pdf 駄目なパターン $ platex graph.tex $ dvipdf graph.dvi これをやると、一部が画面からはみ出したグラフが作成されてしまう。 ...

2020-02-11 · (updated 2020-02-11) · 2 min · 290 words

GraphvizでTeXの数式を表示する(1)

Graphvizはグラフを描画してくれる素晴らしいソフトなのだが、単体では数式を表示することができない。 dot2tex dot2texを利用すると、グラフのラベルに数式が使えるようになる。 次の手順でグラフを作る。 dot言語でグラフを書く dot2texでdotファイルをtexファイルに変換 texを使ってpdfなりsvgなりを作る。 pdfならplatex + dvipdfを使う(詳細は別記事にて) svgならplatex + dvisvgmを使う。 いやGraphviz使ってないじゃないか、と思うかもしれない。しかしDependensiesにGraphvizが含まれているから、おそらくGraphvizの描画エンジンを利用してノードの位置を決定しているのだと思う。 インストール Python製のソフトウェアみたいで、pip経由でインストールする。 $ pip3 install dot2tex 利用の手順 dot言語でグラフを書く 今回は次のようにする。ファイル名は適当にgraph.dotとする。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 digraph { graph [ rankdir="LR" ] node [ shape="circle", fixedsize=true, height=0.6 ] Q0 [texlbl="$q_0$"]; Q1 [texlbl="$q_1$"]; Q2 [texlbl="$q_2$"]; Q3 [texlbl="$q_3$"]; Q4 [texlbl="$q_4$"]; Q5 [texlbl="$q_5$"]; Q6 [texlbl="$q_6$"]; Q7 [texlbl="$q_7$"]; Q8 [texlbl="$q_8$"]; Q9 [texlbl="$q_9$"]; Q10 [texlbl="$q_{10}$"]; Q11 [texlbl="$q_{11}$"]; Q12 [texlbl="$q_{12}$"]; Q13 [texlbl="$q_{13}$"]; Q0 -> Q1 [label=" ", texlbl="$\varepsilon$"]; Q0 -> Q4 [label=" ", texlbl="$\varepsilon$"]; Q0 -> Q7 [label=" ", texlbl="$\varepsilon$"]; Q1 -> Q2 [label=" ", texlbl="$a$"]; Q2 -> Q3 [label=" ", texlbl="$b$"]; Q3 -> Q7 [label=" ", texlbl="$\varepsilon$"]; Q4 -> Q5 [label=" ", texlbl="$b$"]; Q5 -> Q6 [label=" ", texlbl="$b$"]; Q6 -> Q7 [label=" ", texlbl="$\varepsilon$"]; Q7 -> Q8 [label=" ", texlbl="$a$"]; Q7 -> Q0 [label=" ", texlbl="$\varepsilon$"]; Q8 -> Q9 [label=" ", texlbl="$\varepsilon$"]; Q8 -> Q11 [label=" ", texlbl="$\varepsilon$"]; Q9 -> Q10 [label=" ", texlbl="$b$"]; Q10 -> Q13 [label=" ", texlbl="$\varepsilon$"]; Q11 -> Q12 [label=" ", texlbl="$c$"]; Q12 -> Q13 [label=" ", texlbl="$\varepsilon$"]; } texlblとはdot2texが読むための属性。おそらくtex labelの略で、これがnodeまたはedgeのラベルとして、texファイルに直接展開される。そのため、数式を描きたいなら$で囲む。もしdotファイル上にlabel属性が定義されていたら、texlblの内容に上書きされる。 ...

2020-01-26 · (updated 2020-02-11) · 2 min · 224 words

Elmメモ - 画像のプレビュー機能を作る

Elmを利用して、画像を選択してそれを表示するアプリを作る。 ファイル読み込みの方法 Select.file関数を利用する。これはファイル選択用のエクスプローラを開くためのCmd Msgを作成してくれる。選択したファイルはMsgに載せられる。 適切なMIMEタイプを指定すると、エクスプローラ上にてそのタイプのファイルしか選択できなくなる。例えば、text/plainを選択しておけば、拡張子.txtのファイルしか選択できなくなる。 1 Select.file "MIMEタイプのリスト" "Msg" 画像ファイルへの変換 こうして得られたファイルはFileと呼ばれる型で保持される。 もしファイルを文字列として扱いたいなら、File.toStringを利用する。 もし画像として扱いたいなら、File.toUrlを利用する。これは画像をBase64符号化した文字列を作る。これをimgタグのsrc属性に指定すれば、画像が表示される。 画像を選択し、それを表示するアプリの作成 準備 プロジェクトを作成して、elm/fileをインストール。 $ elm init $ elm install elm/file src/Main.elmの雛形を作る。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 module Main exposing (..) import Browser import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) import File exposing (File) import File.Select as Select import Task main = Browser.element { init = init , update = update , view = view , subscriptions = subscriptions } type alias Model = { } init : () -> (Model, Cmd Msg) init _ = ( { } , Cmd.none ) type Msg = Msg update : Msg -> Model -> (Model, Cmd Msg) update msg model = ( model , Cmd.none ) view : Model -> Html Msg view model = div [] [ ] subscriptions : Model -> Sub Msg subscriptions model = Sub.none htmlファイルを自分で作りたいので、makeのときはjsファイルを単独で生成させる。 ...

2020-01-13 · (updated 2020-01-13) · 4 min · 699 words

Elmメモ - 文字列をIPアドレスに変換(2) Parserを用いる方法

準備 前回のsrc/IPAddr.elmを全て消し、内容を以下の通りにする。 1 2 3 4 5 module IPAddr exposing (..) import Parser type IPAddr = IPAddr Int Int Int Int $ elm repl > import Parser exposing (..) > import IPAddr exposing (..) Parserの基本 以下の2つのステップに分かれる。 Parserを作る Parserを実行する - Parser.runを用いる ライブラリでは、標準で用意されているParserと、それらを組み合わせて新たなParserを作るための関数が用意されている。 > run int "123" Ok 123 : Result (List Parser.DeadEnd) Int > run int "123abc" Ok 123 : Result (List Parser.DeadEnd) Int > run int "abc123abc" Err [{ col = 1, problem = ExpectingInt, row = 1 }] : Result (List Parser.DeadEnd) Int succeed 何もパースせず、決まった結果だけを返すパーサー。 > run (succeed "Hello") "123abcde" Ok "Hello" : Result (List Parser.DeadEnd) String パーサーを組み合わせるときの基本になる。 ...

2020-01-05 · (updated 2020-01-05) · 3 min · 549 words

Elmメモ - 文字列をIPアドレスに変換(1) splitを用いる方法

IPv4アドレスの文字列"192.168.1.1"をパースする方法を考える。IPAddrの内部表現は次のようにする。 1 type IPAddr = IPAddr Int Int Int Int 思いつくのは次の2通り。 ピリオドでsplitして、整数値に変換する。 パーサを利用する。 いずれにしても結構面倒。この記事では前者だけやる。 準備 適当なディレクトリで次のコマンドを実行。 $ elm init $ elm install elm/parser src/IPAddr.elmを作り、内容を以下の通りにする。 1 2 3 module IPAddr exposing (..) type IPAddr = IPAddr Int Int Int Int $ elm repl > import IPAddr exposing (..) 方針 次の処理を行う関数をfromStringとして定義する。 文字列を.でsplitする。 Listの要素数が4でなければ失敗。 Listの各要素にString.toIntを適用し、どれか一つでも失敗すれば全体としても失敗。 Listを[a,b,c,d]としたとき、IPAddr a b c dを返す。 traverseの実装 3の処理は、次の関数として抽象化できる: リストの各要素にfを適用し、その結果すべてがJustを返したときだけ、全体の結果を返す。 1 traverse : (a -> Maybe b) -> List a -> Maybe List b 原始的な実装 なるべくfoldrとかを使わずに書こうとするとこんな感じになる。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 traverse : (a -> Maybe b) -> List a -> Maybe (List b) traverse f list = case list of [] -> Just [] x::xs -> case traverse f xs of Nothing -> Nothing Just ys -> case f x of Nothing -> Nothing Just y -> Just (y::ys) case文を使ってネストが深くなってくると、Haskellみたいなパターンマッチが欲しくなってくる。 ...

2020-01-05 · (updated 2020-01-05) · 3 min · 437 words

Elmメモ - ランダムな位置に円を描画する

乱数の練習に。 準備 プロジェクト用のディレクトリを適当に作り、そこで以下のコマンドを実行。 $ elm init 必要なモジュールを入れる。 $ elm install elm/svg $ elm install elm/random Main.elmを作成し、最低限の文を定義しておく。 1 2 3 4 5 6 7 module Main exposing (..) import Browser import Svg exposing (..) import Svg.Attributes as SA exposing (..) import Svg.Events as SE exposing (..) import Random 円の描画 こんな感じの円を描画する。 1 SVGでは次のように書く。 1 2 3 4 5 6 <svg width="100px" height="100px"> <g transform="translate(50, 50)"> <circle r="10" fill="white" stroke="black" /> <text text-anchor="middle" dominant-baseline="central">1</text> </g> </svg> 円の情報で必要なのは次の4つ: x座標 y座標 半径 text要素の文字列 そこで円は次のように定義する。 1 2 3 4 5 6 type alias Circle = { r: Float , x: Float , y: Float , text: String } Elmでは宣言的にSVGやHTMLを書けるので、SVGの文法とほとんど似た構造でかける。直感的で嬉しい。 ...

2020-01-01 · (updated 2020-01-05) · 5 min · 904 words

JavaScript/Elm ビット演算のときにはまったこと

結論 JavaScriptにおいて、>>>以外のビット演算は32ビット符号付き整数値として扱われる。 → 例えば&|^~の計算前に、オペランドに型変換が起こる(ソース)。 JSにおいて数字はNumberという型しかないが、ビット演算のときだけ32ビット整数値に変換されるっぽい JavaScriptにおいて、x >>> 0を使うと符号なし整数になる。 負数を2で割り続けても、コンピュータにおける2進表現にはならない。 これはすごく当たり前だった コンピュータにおける2進数表現にしたいなら,論理シフトを使うこと。 ElmはJavaScriptに変換されるので、上の事実はすべてElmでも当てはまる。 各種ビット演算は、JSの演算をそのまま使っているっぽい(ソース) 検証コード $ elm init src/MyBitwise.elmを作成し、内容を以下のようにする。 1 2 3 4 5 6 7 8 9 10 11 12 13 module MyBitwise exposing (..) import Bitwise toBinaryString : Int -> String toBinaryString x = let bit = Bitwise.and x 1 rem = Bitwise.shiftRightZfBy 1 x in if rem > 0 then (toBinaryString rem) ++ (String.fromInt bit) else String.fromInt bit elm replを起動し、試す。まず必要なモジュールをimportする。 $ elm repl > import Bitwise > import MyBitwise exposing (..) 232-1 = 4294967295を2進表示すると、1が32個並んだ数になる。32ビット整数の2の補数表現では、-1と4294967295は同じ表現方法になる。 > toBinaryString 4294967295 "11111111111111111111111111111111" : String > toBinaryString -1 "11111111111111111111111111111111" : String Bitwise.andの計算結果は符号付き整数値とみなされるので、以下では4294967295ではなく-1と出力される。 ...

2019-12-31 · (updated 2019-12-31) · 3 min · 440 words

iPhoneアプリ開発メモ - 棒グラフの作成(Chartsの利用)

今度は外部ライブラリChartsを利用して、棒グラフを作成してみる。 目標 値が最大のデータは色をオレンジにする アニメーションがある 棒グラフの上に値を表示する ページ切り替えができる棒グラフを作る タップしたらイベントを発生させる 1〜3、5は機能としてある。4だけ頑張って作る。思い通りのレイアウトにするためにはプロパティとかドキュメントとかを漁る必要があるが、どこにどのプロパティがあるのかは大体予想できる。 ChartDataSet.colorsで各棒の色を変更できる。 BarChartView.animate(yAxisDuration:)を利用。 BarChartView.drawValueAboveBarEnabled = trueとする。表示形式を変更するためにはChartDataSet.valueFormatterにフォーマット用のオブジェクトを指定する。 ScrollViewの中ににBarChartViewを複数配置。 ChartViewDelegateを利用。 その他デフォルトの設定だと表示する情報量が多すぎるので、いくつかのプロパティをいじる。 Chartsのインストール まず、CocoaPodsがインストールされていることが前提。 プロジェクトフォルダで以下のコマンドを実行。 1 $ pod init podfileが作成されるので、それを編集する。use_frameworks!の下に以下の記述を追加。 1 pod 'Charts' プロジェクトフォルダで以下のコマンドを実行。 1 $ pod install 以降、プロジェクトはプロジェクト名.xcodeprojではなくプロジェクト名.xcworkspaceから開く。 基本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 import UIKit import Charts struct BarChartModel { let value: Int let name: String } class ViewController: UIViewController { let barItems = [ (7, "太郎"), (1, "次郎"), (2, "三郎"), (6, "四郎"), (3, "五郎"), (9, "六郎"), (2, "七郎"), (3, "八郎"), (1, "九郎"), (5, "十郎"), (1, "十一郎"), (1, "十二郎"), (6, "十三郎") ] override func viewDidLoad() { super.viewDidLoad() let barChartView = createBarChartView() self.view.addSubview(barChartView) barChartView.translatesAutoresizingMaskIntoConstraints = false barChartView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 80).isActive = true barChartView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -80).isActive = true barChartView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true barChartView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true } private func createBarChartView() -> BarChartView { let barChartView = BarChartView() barChartView.data = createBarChartData(of: barItems.map({BarChartModel(value: $0.0, name: $0.1)})) return barChartView } private func createBarChartData(of items: [BarChartModel]) -> BarChartData { let entries: [BarChartDataEntry] = items.enumerated().map { let (i, item) = $0 return BarChartDataEntry(x: Double(i), y: Double(item.value)) } let barChartDataSet = BarChartDataSet(entries: entries, label: "Label") let barChartData = BarChartData(dataSet: barChartDataSet) return barChartData } } これだけの記述で以下の棒グラフが描ける。 ...

2019-12-29 · (updated 2019-12-29) · 4 min · 685 words