mermaid-cliで出力したsvgファイルにテキストが表示されない場合の対応
問題
ローカルにインストールしたmermaid-cliで出力するsvgファイルでテキストが表示されない問題があった。
graph TD; A-->B; B-->C; C-->A;
対応
config.json
を以下のように作成してそれを引き渡すと解決した。
{ "flowchart": { "htmlLabels": false } }
./node_modules/.bin/mmdc -c ~/.config/mermaid/config.json -i a.md && eog a-1.md.svg
参考
mermaid missing text in svg · Issue #112 · mermaid-js/mermaid-cli · GitHub
JetpackComposeで状態変化が画面に反映されない書き方
JetpackComposeに触れる中でViewModelに保持させた状態の変化が画面に即時で反映されない場合があったのでそのコードを記します。
package jp.kawagh.learn_recompose import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel data class UiState(val a: Int, var b: Int) class MyViewModel : ViewModel() { var uiState by mutableStateOf(UiState(0, 0)) private set fun incA() { // recompose uiState = uiState.copy(a = uiState.a + 1) } fun incB() { // not recompose uiState.b += 1 } }
上記コードのコメントにも書かれていますがincBメソッドを呼んだ場合には(状態の更新は起こるが)画面に状態の更新は反映されません。
状態が画面に即時で反映されて欲しいケースがほとんどだと思うので、incBのような書き方はそもそもコンパイルの段階でエラーで弾けるように data classのメンバの定義は以下のようにvarではなくvalを使おうと思っています。
- data class UiState(val a: Int, var b: Int) + data class UiState(val a: Int, val b: Int)
そもそもdata classの定義としてvarを使うことになっていたのはUiStateといったdata classでまとめる前に下のように書いていた名残でした。
var b by mutableStateOf(0) private set
リファクタリングしたつもりで画面と状態更新のズレを生じさせてしまっていました。 UIテストでないと検知出来ない部分で再びハマりそうなので書き残しておきます。
JetpackComposeでアナログ時計の作成
drawCanvasのシンプルなお題としてアナログ時計の作成に取り組みました。
@Composable fun Clock() { val hour = LocalTime.now().hour val minute = LocalTime.now().minute val shortDegree = minute * 6f val longDegree = (hour % 12 + minute / 60) * 30f Column { Canvas(modifier = Modifier.fillMaxSize()) { drawCircle(Color.Gray) rotate(longDegree) { val longEnd = this.center + Offset(0f, -size.minDimension / 3) drawLine(Color.Cyan, start = this.center, end = longEnd, strokeWidth = 10f) } rotate(shortDegree) { val shortEnd = this.center + Offset(0f, -size.minDimension / 2) drawLine(Color.Yellow, start = this.center, end = shortEnd, strokeWidth = 5f) } } } }
CanvasによるdrawScopeではrotateメソッドが使えて描画するパーツを回転させられます。 以下に示すのはrotateの定義で時計のコードには現れていませんが回転の中心を変更することもできます。
inline fun DrawScope.rotate( degrees: Float, pivot: Offset = center, block: DrawScope.() -> Unit ) = withTransform({ rotate(degrees, pivot) }, block)
opencvの型スタブファイル(.pyi)を取得する
関数の定義などをエディタが提供する補完で参照しながらコーディングをしていますが、opencvなどの元々pythonで書かれていないライブラリだったりはその情報が得られず苦労していました。 その折に、以下のissueを見つけました。
このissueが紐づくリポジトリは人気のあるpythonパッケージの型スタブファイルの作成を進めているようです。
下記スクリプトでimportされるopencvのディレクトリに.pyiファイルを追加することが出来ます。
CV2_PATH=`python -c 'import cv2, os; print(os.path.dirname(cv2.__file__))'` URL='https://raw.githubusercontent.com/bschnurr/python-type-stubs/add-opencv/cv2/__init__.pyi' curl -sSL $URL -o ${CV2_PATH}/__init__.pyi
参考
JetpackComposeで上下左右のドラッグ、スワイプ操作の検知
コード(成功例)
下記コードでドラッグ操作のx軸y軸の距離で大きい方向にテキストを書き換えられます。
@Composable fun Drag() { var state by remember { mutableStateOf("-") } Box( modifier = Modifier .fillMaxSize() .pointerInput(Unit) { detectDragGestures( onDrag = { change: PointerInputChange, dragAmount: Offset -> change.consumeAllChanges() val (x, y) = dragAmount if (abs(x) > abs(y)) { state = if (x > 0) ">" else "<" } else { state = if (y > 0) "v" else "^" } }, ) } ) { Column(modifier = Modifier.align(Alignment.Center)) { Text(state, fontSize = MaterialTheme.typography.h1.fontSize) } } }
コード(失敗例)
こちらは読む必要はないです。
@OptIn(ExperimentalMaterialApi::class) @Composable fun NotWorkSwipe() { val squareSize = 48.dp val swipeableState = rememberSwipeableState("-") val sizePx = with(LocalDensity.current) { squareSize.toPx() } val horizontalAnchors = mapOf(0f to "<", sizePx to ">", 100f to "-") // Maps anchor points (in px) to states val verticalAnchors = mapOf(0f to "^", sizePx to "v", 100f to "-") // Maps anchor points (in px) to states Box( modifier = Modifier .fillMaxSize() .swipeable( state = swipeableState, anchors = verticalAnchors, orientation = Orientation.Vertical ) .swipeable( state = swipeableState, anchors = horizontalAnchors, orientation = Orientation.Horizontal ) ) { Column(modifier = Modifier.align(Alignment.Center)) { Text(swipeableState.currentValue, fontSize = MaterialTheme.typography.h1.fontSize) } } }
swipeableという修飾子をはじめに見つけたのですがこれは水平か鉛直かの方向を指定する必要がありました。 swipeable修飾子を重ねがけしたら出来るのではと思いましたが後ろのswipeable のみ適用される結果となりました。