如何检查在 Jetpack Compose 中单击了哪个弧形图或饼图分段?

2024-04-16

这是一个分享你的知识,问题的启发这个问题 https://stackoverflow.com/questions/75903172/draw-legend-of-pie-chart-donut-chart-in-center-of-segment检测圆或半圆内的圆弧段或接触程度,如 gif 和下图所示。另外,默认情况下,使用绘制修改器向画布或可组合项向内或向外设置笔划宽度的变化方式。


默认情况下,笔划的一半绘制在选定位置内,而另一半则绘制出。

@Composable
private fun CanvasDefaultStroke() {

    var target by remember {
        mutableStateOf(1f)
    }
    val scale by animateFloatAsState(targetValue = target)

    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                detectTapGestures {
                    target = if (target == 1f) 1.3f else 1f
                }
            }
            .padding(40.dp),
        contentAlignment = Alignment.Center
    ) {
        Canvas(
            modifier = Modifier
                .fillMaxWidth()
                .aspectRatio(1f)
                .border(2.dp, Color.Red),
        ) {

            val radius = size.width / 2f * .8f
            val strokeWidth = (size.width - 2 * radius) / 2
            val newStrokeWidth = strokeWidth * scale
            drawRect(
                color = Color.Green,
                style = Stroke(width = newStrokeWidth)
            )
        }
    }
}

通过更改绘制的矩形弧的左上角和大小,可以创建在单击时向外生长的弧,或者可以通过操作进行动画处理。在下图中,圆弧内部部分的半径不会改变,在下面的示例中,绿色矩形永远不会接触蓝色圆圈。

@Composable
private fun CanvasStrokeOutside() {

    var target by remember {
        mutableStateOf(1f)
    }
    val scale by animateFloatAsState(targetValue = target)

    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                detectTapGestures {
                    target = if (target == 1f) 1.3f else 1f
                }
            }
            .padding(40.dp),
        contentAlignment = Alignment.Center
    ) {
        Canvas(
            modifier = Modifier
                .fillMaxWidth()
                .aspectRatio(1f)
                .border(2.dp, Color.Red),
        ) {

            val radius = size.width / 2f * .8f
            val strokeWidth = (size.width - 2 * radius) / 2
            val newStrokeWidth = strokeWidth * scale
            drawRect(
                color = Color.Green,
                style = Stroke(width = newStrokeWidth),
                topLeft = Offset(
                    (size.width - 2 * radius - newStrokeWidth) / 2,
                    (size.width - 2 * radius - newStrokeWidth) / 2
                ),
                size = Size(2 * radius + newStrokeWidth, 2 * radius + newStrokeWidth)
            )

            drawCircle(color = Color.Blue, radius = radius)
        }
    }
}

绘制圆环图时,我们需要有一个用红色圆圈表示的外半径、用蓝色圆圈表示的笔画宽度和内半径。我还使用内部笔划宽度为圆环图提供一些深度。

为了计算我们首先触摸图表或圆的哪个部分,我们需要通过测量从圆弧/圆的中心到触摸位置的距离来确定我们是否触摸圆弧内的部分,因为距离应该在内半径和外半径之间才能知道我们触摸了所需的区域。

val xPos = size.center.x - position.x
val yPos = size.center.y - position.y
val length = sqrt(xPos * xPos + yPos * yPos)
val isTouched = length in innerRadius - innerStrokeWidthPx..radius

如果触摸位置位于所需区域内,我们可以使用反正切函数获得角度,该函数给出以弧度为单位的角度。

https://en.wikipedia.org/wiki/Inverse_trigonometric_functions https://en.wikipedia.org/wiki/Inverse_trigonometric_functions

if (isTouched) {
    var touchAngle =
        (-chartStartAngle + 180f + atan2(
            yPos,
            xPos
        ) * 180 / Math.PI) % 360f

    if (touchAngle < 0) {
        touchAngle += 360f
    }

获得中心和触摸位置之间的角度后,需要检查该角度位于哪个段。我将图像中的角度映射到数据作为开始和结束角度

    chartDataList.forEachIndexed { index, chartData ->
        val range = chartData.range

        val isTouchInArcSegment = touchAngle in range
        if (chartData.isSelected) {
            chartData.isSelected = false
        } else {
            chartData.isSelected = isTouchInArcSegment
            if (isTouchInArcSegment) {
                onClick?.invoke(
                    ChartData(
                        color = chartData.color,
                        data = chartData.data
                    ), index
                )
            }
        }
    }
}

映射是使用绘制坐标系中的起始角度顶部起始位置为 -90 度来完成的

// Start angle of chart. Top center is -90, right center 0,
// bottom center 90, left center 180
val chartStartAngle = startAngle

val chartEndAngle = 360f + chartStartAngle

val sum = data.sumOf {
    it.data.toDouble()
}.toFloat()

val coEfficient = 360f / sum
var currentAngle = 0f
val currentSweepAngle = animatableInitialSweepAngle.value

val chartDataList = remember(data) {
    data.map {

        val chartData = it.data
        val range = currentAngle..currentAngle + chartData * coEfficient
        currentAngle += chartData * coEfficient

        AnimatedChartData(
            color = it.color,
            data = it.data,
            selected = false,
            range = range
        )
    }
}

还可以根据我使用的颜色加深颜色

val colorInner =
   Color(
       ColorUtils
           .blendARGB(animatedColor.toArgb(), Color.Black.toArgb(), 0.1f)
   )

并在未选定的颜色和选定的颜色之间设置动画颜色lerp函数是在一种颜色之间进行动画处理的最方便的方法

val animatedColor = androidx.compose.ui.graphics.lerp(
    color,
    color.copy(alpha = .8f),
    fraction
)

全面实施

@Preview
@Composable
private fun PieChartPreview() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState())
    ) {
        val data = remember {
            listOf(
                ChartData(Pink400, 10f),
                ChartData(Orange400, 20f),
                ChartData(Yellow400, 15f),
                ChartData(Green400, 5f),
                ChartData(Red400, 35f),
                ChartData(Blue400, 15f)
            )
        }

        PieChart(
            modifier = Modifier.fillMaxSize(),
            data = data,
            outerRingPercent = 35,
            innerRingPercent = 10,
            dividerStrokeWidth = 3.dp
        )

        PieChart(
            modifier = Modifier.fillMaxSize(),
            data = data,
            outerRingPercent = 100,
            innerRingPercent = 0,
            startAngle = -90f,
            drawText = false,
            dividerStrokeWidth = 0.dp
        )

        PieChart(
            modifier = Modifier.fillMaxSize(),
            data = data,
            outerRingPercent = 25,
            innerRingPercent = 0,
            dividerStrokeWidth = 2.dp
        )
    }
}

@Composable
fun PieChart(
    modifier: Modifier,
    data: List<ChartData>,
    startAngle: Float = 0f,
    outerRingPercent: Int = 35,
    innerRingPercent: Int = 10,
    dividerStrokeWidth: Dp = 0.dp,
    drawText: Boolean = true,
    onClick: ((data: ChartData, index: Int) -> Unit)? = null
) {

    BoxWithConstraints(
        modifier = modifier,
        contentAlignment = Alignment.Center
    ) {

        val density = LocalDensity.current

        val width = constraints.maxWidth.toFloat()

        // Outer radius of chart. This is edge of stroke width as
        val radius = (width / 2f) * .9f
        val outerStrokeWidthPx =
            (radius * outerRingPercent / 100f).coerceIn(0f, radius)

        // Inner radius of chart. Semi transparent inner ring
        val innerRadius = (radius - outerStrokeWidthPx).coerceIn(0f, radius)
        val innerStrokeWidthPx =
            (radius * innerRingPercent / 100f).coerceIn(0f, radius)

        val lineStrokeWidth = with(density) { dividerStrokeWidth.toPx() }

        // Start angle of chart. Top center is -90, right center 0,
        // bottom center 90, left center 180
        val chartStartAngle = startAngle
        val animatableInitialSweepAngle = remember {
            Animatable(chartStartAngle)
        }

        val chartEndAngle = 360f + chartStartAngle

        val sum = data.sumOf {
            it.data.toDouble()
        }.toFloat()

        val coEfficient = 360f / sum
        var currentAngle = 0f
        val currentSweepAngle = animatableInitialSweepAngle.value

        val chartDataList = remember(data) {
            data.map {

                val chartData = it.data
                val range = currentAngle..currentAngle + chartData * coEfficient
                currentAngle += chartData * coEfficient

                AnimatedChartData(
                    color = it.color,
                    data = it.data,
                    selected = false,
                    range = range
                )
            }
        }

        chartDataList.forEach {
            LaunchedEffect(key1 = it.isSelected) {
                // This is for scaling radius
                val targetValue = (if (it.isSelected) width / 2 else radius) / radius

                // This is for increasing outer ring
//                val targetValue = if (it.isSelected) outerStrokeWidthPx + width / 2 - radius
//                else outerStrokeWidthPx
                it.animatable.animateTo(targetValue, animationSpec = tween(500))
            }
        }

        LaunchedEffect(key1 = animatableInitialSweepAngle) {
            animatableInitialSweepAngle.animateTo(
                targetValue = chartEndAngle,
                animationSpec = tween(
                    delayMillis = 1000,
                    durationMillis = 1500
                )
            )
        }

        val textMeasurer = rememberTextMeasurer()
        val textMeasureResults: List<TextLayoutResult> = remember(chartDataList) {
            chartDataList.map {
                textMeasurer.measure(
                    text = "%${it.data.toInt()}",
                    style = TextStyle(
                        fontSize = 16.sp,
                        fontWeight = FontWeight.Bold
                    )
                )
            }
        }

        val chartModifier = Modifier
            .fillMaxWidth()
            .aspectRatio(1f)
            .pointerInput(Unit) {
                detectTapGestures(
                    onTap = { position: Offset ->
                        val xPos = size.center.x - position.x
                        val yPos = size.center.y - position.y
                        val length = sqrt(xPos * xPos + yPos * yPos)
                        val isTouched = length in innerRadius - innerStrokeWidthPx..radius

                        if (isTouched) {
                            var touchAngle =
                                (-chartStartAngle + 180f + atan2(
                                    yPos,
                                    xPos
                                ) * 180 / Math.PI) % 360f

                            if (touchAngle < 0) {
                                touchAngle += 360f
                            }


                            chartDataList.forEachIndexed { index, chartData ->
                                val range = chartData.range

                                val isTouchInArcSegment = touchAngle in range
                                if (chartData.isSelected) {
                                    chartData.isSelected = false
                                } else {
                                    chartData.isSelected = isTouchInArcSegment
                                    if (isTouchInArcSegment) {
                                        onClick?.invoke(
                                            ChartData(
                                                color = chartData.color,
                                                data = chartData.data
                                            ), index
                                        )
                                    }
                                }
                            }
                        }
                    }
                )
            }

        PieChartImpl(
            modifier = chartModifier,
            chartDataList = chartDataList,
            textMeasureResults = textMeasureResults,
            currentSweepAngle = currentSweepAngle,
            chartStartAngle = chartStartAngle,
            chartEndAngle = chartEndAngle,
            outerRadius = radius,
            outerStrokeWidth = outerStrokeWidthPx,
            innerRadius = innerRadius,
            innerStrokeWidth = innerStrokeWidthPx,
            lineStrokeWidth = lineStrokeWidth,
            drawText = drawText
        )

    }
}

@Composable
private fun PieChartImpl(
    modifier: Modifier = Modifier,
    chartDataList: List<AnimatedChartData>,
    textMeasureResults: List<TextLayoutResult>,
    currentSweepAngle: Float,
    chartStartAngle: Float,
    chartEndAngle: Float,
    outerRadius: Float,
    outerStrokeWidth: Float,
    innerRadius: Float,
    innerStrokeWidth: Float,
    lineStrokeWidth: Float,
    drawText: Boolean
) {
    Canvas(modifier = modifier) {

        val width = size.width
        var startAngle = chartStartAngle

        for (index in 0..chartDataList.lastIndex) {

            val chartData = chartDataList[index]
            val range = chartData.range
            val sweepAngle = range.endInclusive - range.start
            val angleInRadians = (startAngle + sweepAngle / 2).degreeToRadian
            val textMeasureResult = textMeasureResults[index]
            val textSize = textMeasureResult.size

            val currentStrokeWidth = outerStrokeWidth
            // This is for increasing stroke width without scaling
//            val currentStrokeWidth = chartData.animatable.value

            withTransform(
                {
                    val scale = chartData.animatable.value
                    scale(
                        scaleX = scale,
                        scaleY = scale
                    )
                }
            ) {

                if (startAngle <= currentSweepAngle) {

                    val color = chartData.color
                    val diff = (width / 2 - outerRadius) / outerRadius
                    val fraction = (chartData.animatable.value - 1f) / diff

                    val animatedColor = androidx.compose.ui.graphics.lerp(
                        color,
                        color.copy(alpha = .8f),
                        fraction
                    )

                    val colorInner =
                        Color(
                            ColorUtils
                                .blendARGB(animatedColor.toArgb(), Color.Black.toArgb(), 0.1f)
                        )


                    // Outer Arc Segment
                    drawArc(
                        color = animatedColor,
                        startAngle = startAngle,
                        sweepAngle = sweepAngle.coerceAtMost(
                            currentSweepAngle - startAngle
                        ),
                        useCenter = false,
                        topLeft = Offset(
                            (width - 2 * innerRadius - currentStrokeWidth) / 2,
                            (width - 2 * innerRadius - currentStrokeWidth) / 2
                        ),
                        size = Size(
                            innerRadius * 2 + currentStrokeWidth,
                            innerRadius * 2 + currentStrokeWidth
                        ),
                        style = Stroke(currentStrokeWidth)
                    )


                    // Inner Arc Segment
                    drawArc(
                        color = colorInner,
                        startAngle = startAngle,
                        sweepAngle = sweepAngle.coerceAtMost(
                            currentSweepAngle - startAngle
                        ),
                        useCenter = false,
                        topLeft = Offset(
                            (width - 2 * innerRadius) / 2 + innerStrokeWidth / 2,
                            (width - 2 * innerRadius) / 2 + innerStrokeWidth / 2
                        ),
                        size = Size(
                            2 * innerRadius - innerStrokeWidth,
                            2 * innerRadius - innerStrokeWidth
                        ),
                        style = Stroke(innerStrokeWidth)
                    )
                }

                val textCenter = textSize.center

                if (drawText && currentSweepAngle == chartEndAngle) {
                    drawText(
                        textLayoutResult = textMeasureResult,
                        color = Color.Black,
                        topLeft = Offset(
                            -textCenter.x + center.x
                                    + (innerRadius + currentStrokeWidth / 2) * cos(angleInRadians),
                            -textCenter.y + center.y
                                    + (innerRadius + currentStrokeWidth / 2) * sin(angleInRadians)
                        )
                    )
                }
            }

            startAngle += sweepAngle
        }

        for (index in 0..chartDataList.lastIndex) {

            val chartData = chartDataList[index]
            val range = chartData.range
            val sweepAngle = range.endInclusive - range.start

            // Divider
            rotate(
                90f + startAngle
            ) {
                drawLine(
                    color = Color.White,
                    start = Offset(
                        center.x,
                        (width / 2 - innerRadius + innerStrokeWidth)
                            .coerceAtMost(width / 2)
                    ),
                    end = Offset(center.x, 0f),
                    strokeWidth = lineStrokeWidth
                )
            }

            startAngle += sweepAngle
        }

    }
}


@Immutable
data class ChartData(val color: Color, val data: Float)

@Immutable
internal class AnimatedChartData(
    val color: Color,
    val data: Float,
    selected: Boolean = false,
    val range: ClosedFloatingPointRange<Float>,
    val animatable: Animatable<Float, AnimationVector1D> = Animatable(1f)
) {
    var isSelected by mutableStateOf(selected)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何检查在 Jetpack Compose 中单击了哪个弧形图或饼图分段? 的相关文章

  • 使用迭代器时无限循环

    Set key1 map keySet Iterator it1 key1 iterator int cnt 0 while it1 hasNext cnt 这段代码导致无限循环的可能性有多大 实际上这会导致无限循环 我怀疑是因为我没有服用
  • 在php中获取二进制数据大小的正确方法是什么?

    我已阅读文件的一部分 现在想确保该部分的大小正确 我怎样才能在 php 中做到这一点 part fread file 1024 return some function part 1024 我已经阅读了这些示例 但我怀疑是否要使用 strl
  • Zeppelin:如何在 zeppelin 中重新启动 SparkContext

    我正在使用 zeppelins Spark 解释器的隔离模式 在这种模式下 它将为 Spark 集群中的每个笔记本启动一项新工作 我想在笔记本执行完成后通过 zeppelin 终止该作业 为此我做了sc stop这停止了 sparkCont
  • Pandas 如何删除包含所需字符串的行

    我想删除包含所需字符串的所有行 假设我有以下数据框 A B C 1 a x w g n 3 l p j p v 我想删除包含字符串的所有行p 我已经搜索过它 但大多数答案都是基于列名称 就我而言 我不会知道它可以出现在任何列中 输出数据帧应
  • Hibernate 对于 Android 应用程序来说是一种杀伤力吗? [复制]

    这个问题在这里已经有答案了 我正在为我的 Android 应用程序寻找一个好的 ORM 乍一看似乎对于移动设备我更喜欢使用更简单的东西 问题是我只是在这里假设 没有真正的证据 所以我想我应该询问社区的意见 也许有人有过这样的经历 它是一个相
  • 并行运行 Angular 和 AngularJS 框架

    我找到了描述如何将 Angular 2 组件集成到 AngularJS 中的资源 但所有这些都涉及像 Angular 项目一样设置 AngularJS 项目 需要 TypeScript 的转译器 需要 ES6 需要 import 语句 我想
  • Qt 按键事件 Enter

    void LoginModle keyPressEvent QKeyEvent event qDebug lt lt event gt key lt lt t lt lt Qt Key Enter lt lt t lt lt QKeyEve
  • 在 VBA 中调用批处理文件无法正常工作

    我正在尝试创建一个可供其他人使用的程序 目前 我的文件位于目录中C Documents and Settings jpmccros Desktop test 该目录包含我的macro xlsm names bat 还有另一个子目录名为Dat
  • QTextEdit:仅当滚动条位于底部时自动向下滚动

    有一个 QTextEdit 显示相当多的文本 它不可编辑 假设我想在开头阅读一些内容 向上滚动 但随后添加了一个新行 并且滚动条自动转到底部 我在使用各种程序时遇到类似的问题 无论它们是用什么语言编写的 如何处理这个问题 当向文本添加新行时
  • Vimscript:如何获取正在运行 Vim 的操作系统?

    我有一个 vim 插件 可以在不同的机器上运行 有时需要根据 Windows Linux Mac 执行不同的操作 测试操作系统最简单的方法是什么 我知道我可以解析 version 命令的输出 有没有更简单的东西可以揭示操作系统 来自谷歌 您
  • 哪种 LaTeX 包与 knit 一起使用以获得更多的表格控制?禁忌?

    我正在用 knitr 写一张更长的桌子xtable和tabular environment longtable 在 longtable 包中时print将它们纳入我的 Rnw file 问题是我对longtable环境控制不够 我有一些文本
  • MVC 4 Razor 如果拆分 div 标签

    我有以下 MVC 4 Razor 代码 for int i 1 i lt 100 i if currentCol 1 Html Raw div class row Need to do this because can t have a o
  • LISP - 破坏性和非破坏性构造

    正确的定义是什么破坏性的 and 非破坏性的在 LISP 或一般情况下 中构造 我试图寻找真正的含义 但我只发现了这些术语的很多用法 而没有真正解释它们 据我了解 通过破坏性的函数是指一个函数 它改变构造 或变量 的含义 所以当我将一个列表
  • 无法声明接口:资源繁忙

    我正在使用 USB4Java 低级版本 并且基本上是根据这段代码工作的here http www mets blog com java usb communication usb4java 我在 Ubuntu 中工作 遇到了有关权限的问题
  • 最大方法名称长度

    有谁知道您选择的编程语言中方法名称的最大长度是多少 我本来打算将此作为一个 C 特定问题 但我认为了解整个范围会很好 还涉及哪些因素 语言规范对此有限制吗 What does the compiler limit it to 32 位和 6
  • html 中的图像按钮

    我正在尝试获取一个带有图像的按钮 我见过类似下面的东西 但它们不会为您提供普通按钮所具有的按钮按下 释放效果
  • 使用 Jest 测试来自 React-router v4 的链接

    我在用着jest测试一个组件从反应路由器 v4 开始 我收到警告需要来自反应路由器的上下文
  • Angular2 中的 MVW 代表什么?

    我有很多介绍 MVC MVP MVVM 等的链接 但我没有得到一个可以说明 M 在 Angular2 中到底代表什么 V 在 Angular2 中到底代表什么以及 W 在 Angular2 中到底代表什么的信息 也许W有一个答案 那就是W代
  • 我可以更改 LongListMultiSelector 中的复选框颜色吗? WP8

    我需要更改 Windows Phone 8 中 LongListMultiSelector 复选框的颜色 因为我的背景是白色 这可能吗 Thanks 为此 您必须首先通过在 Visual Studio 中的文档大纲中右键单击长列表选择器来编
  • 从 C# 调用 C++ DLL

    我想使用 C 中的 C DLL C DLL 是win32 控制台应用程序 我已成功调用它 并希望在 C 中处理来自 C 的数据 然而 C 应用程序在执行 DLL 后退出 即这一行 GetArrayFromDLL 我是 C 和 Visual

随机推荐

  • RESTful 设计:分页集合

    我正在设计一个 REST api 需要从服务器端强制执行分页 每个 x 翻阅任何资源集合的正确方法是什么 选项1 GET resource page
  • Swift @escaping 和完成处理程序

    我试图更准确地理解 Swift 的 闭包 But escaping and Completion Handler太难理解了 我查了很多Swift的帖子和官方文档 但感觉还是不够 这是官方文档的代码示例 var completionHandl
  • 如何向 Google 地图上的信息窗口添加组合框和按钮?

    目前 我正在开发一个应用程序 其中我必须在地图本身的单击事件上显示一个信息窗口 我的问题是我想在此信息窗口上显示一个按钮和一个组合框 我怎样才能做到这一点 您需要添加自定义UIView给你的MK地图视图并抑制默认值MK注释标注视图 您的定制
  • 在 Chrome 中无需右键单击即可检查元素

    When I inspect html css on a website I usually open the chrome developers panel ctrl shift I right click context menu in
  • 如何通过着色器管道传递顶点颜色?

    我试图通过顶点 几何和片段着色器传递顶点颜色 glBegin GL POINTS glVertex3f 2 0f 0 0f 0 0 glColor3f 0 0 1 0 0 0 glVertex3f 2 0f 0 0f 0 0 glColor
  • jQuery while 循环不等待动画

    我有一个 jQuery 函数可以执行以下操作 clone 在一个物体上 然后 insertAfter and a slideDown 在克隆的对象上 整个函数被包装在一个while环形 我将尽可能简短并展示一个通用示例 while stat
  • 将函数应用于不包括按值嵌套的数据表子集

    我有一个与此相关的问题 我之前曾问过 从 foreach 循环赋值 https stackoverflow com questions 18767016 assignment of a value from a foreach loop 1
  • Laravel 5 调整图像大小

    我使用 Laravel 5 并有一个上传图像的表单 保存文件时 我在控制器方法中获取图像并将其放入目录中 if request gt hasFile picture destinationPath uploads filename imag
  • jQuery-tokeninput 失败:“term”未定义?

    在我的 Rails 应用程序中 我尝试使用 jquery tokeninput 我一切正常 json 响应和所有 但当在标记化字段中输入任何内容时 脚本会出错 并抱怨 TypeError term is undefined gt retur
  • 如何阻止 Maven 覆盖资源文件

    我有默认的 Maven 结构 main java resources webapp 我看到每个mvn compile复制资源 即使它们没有改变 我应该怎么做才能仅复制更改的文件
  • 无法以管理员身份运行

    我必须执行ewfmgr exe仅当以管理员身份打开命令窗口时才能执行 如果我去Start gt type cmd exe gt Right click gt Run as Administrator然后出现以下命令提示符窗口 在这个窗口中
  • SQL 查询查找具有最匹配关键字的行

    我真的不擅长 SQL 我想知道我可以运行什么 SQL 来解决下面的问题 我怀疑这是一个 NP 完全问题 但我可以接受查询需要很长时间才能在大型数据集上运行因为这将作为后台任务完成 首选标准 SQL 语句 但如果需要存储过程 那就这样吧 SQ
  • Ruby - 如何在 Prawn 中使用不同的字体?

    我有一个小型 Rub y 程序 我使用 Prawn 将一些文本打印到 PDF 中 但一小部分文本是非英语字符 其中一些文本是中文 一些是希腊文 等等 当我运行我的程序时 我当然会收到一条错误消息Your document includes
  • StructureMap通过注入解决依赖而不是服务定位

    在我的项目中我注册了很多ISerializers使用装配扫描仪的实现 FWIW这是注册我的代码ISerializers Scan scanner gt scanner AssemblyContainingType
  • 在箱线图中标记散点图点以及R中图形中箱线图的摘要

    祝大家好 我需要帮助找到在箱线图中标记散点图的解决方案 如下图所示 有两个数据 第一个是所有宏观宇宙的数据 第二个是每个宏观宇宙的平均值 Tab1 查询结果 1 2 3 4 5 6 1 13 2089 13 3161 13 2497 13
  • Tcl 脚本中错误的静态检测

    我已经开发了一些代码 并且在 Linux 机器上遇到了 Tcl 解释器错误标记的问题 usr bin tclsh if 1 puts abc1 elseif puts abc2 上面的代码没有标记错误 elseif 条件 直到进入elsei
  • 目前可用于 python3 上带有 Flask 的 websocket 的最佳选择[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 目前我看到以下库可用于将 websockets 与 Flask 一起使用 烧瓶插座 https gith
  • 将图像 ( png ) 转换为矩阵,然后转换为一维数组

    我有 5 张图片 我想将每个图像转换为一维数组 并将其作为向量放入矩阵中 我希望能够再次将每个矢量转换为图像 img Image open orig png convert RGBA a np array img 我不熟悉 numpy 的所
  • JSF 2 应用程序中默认的托管 Bean 范围是什么?

    通常 默认范围是请求范围 我尝试删除作用域注释并期望 bean 具有请求 bean 作用域行为 通过返回上一页上提交的值 我记得我过去已经尝试过此操作并且工作正常 但我没有得到任何结果与其相连的表达语言 那么默认范围是什么以及为什么它的行为
  • 如何检查在 Jetpack Compose 中单击了哪个弧形图或饼图分段?

    这是一个分享你的知识 问题的启发这个问题 https stackoverflow com questions 75903172 draw legend of pie chart donut chart in center of segmen