【问题标题】:CategoryAxis - trim strings while keeping ToolTip data with full informationCategoryAxis - 修剪字符串,同时保留具有完整信息的工具提示数据
【发布时间】:2020-07-06 12:19:48
【问题描述】:

在分类轴中,每个数据都有标签。
字符串有时太长,因此会与其他字符串重叠。
oxyplot 中还有其他可以裁剪的元素,例如axisTitle、Title等
我想根据标签之间的可用空间剪裁轴标签。

这就是我想要实现的目标:

LabelFormatter = a => a.Length > 10 ? a.Substring(0,9) : a

但 LabelFormatter 仅适用于数字,不适用于字符串。

您是否有一种方法可以做到这一点,以便在轴上修剪标签,但它们在跟踪器工具提示中仍然显示完整?

如果你想复制我遇到的问题,你可以:

  1. 打开 Visual Studio
  2. 加载oxyplot.WPF.sln(之前从github,master分支下载)
  3. 找到示例\示例浏览器\CategoryAxisExamples.cs
  4. 修改第 34 行,将“A”替换为“Very long item A”等。
  5. 您现在可以运行示例浏览器应用程序并在 Category Axis -> ItemsSource - string[] example 中找到示例
public static PlotModel ItemsSourceStrings()
        {
            var model = new PlotModel { Title = "CategoryAxis with string[] as ItemsSource" };
            model.Axes.Add(new CategoryAxis
            {
                StringFormat = "Very long item {0}",
                ItemsSource = new[] { "A", "B", "C" }
            });
            var linearAxis = new LinearAxis { Position = AxisPosition.Left };
            model.Axes.Add(linearAxis);
            return model;
        }

【问题讨论】:

  • 看起来您已经创建了一个示例应用程序,该示例应用程序遇到了您遇到的问题。如果您包含该代码,那么任何回答此问题的人都可以更轻松地通过代码给出明确的答案。
  • 好的。我会去做。它是如此简单,我认为没有必要,但我将添加代码。感谢您的提示!

标签: c# wpf oxyplot


【解决方案1】:

我能够使用此代码使您的概念适用于LabelFormatter。传递给标签格式化程序的数字是类别索引。

var categoryAxis = new CategoryAxis
{
    StringFormat = "Very long item {0}",
    ItemsSource = new[] { "A", "B", "C" }
};
categoryAxis.LabelFormatter = categoryIndex =>
{
    var actualLabel = categoryAxis.ActualLabels[(int)categoryIndex];
    return actualLabel.Length > 10 ? $"{actualLabel.Substring(0, 9)}...{actualLabel.Last()}" : actualLabel;
};

但不幸的是,标签格式化程序似乎已合并到用于跟踪器文本的文本中

如果您可以在标签中添加额外的行,则可以使用标签格式化程序,根据行的当前长度在单词的末尾添加行。示例代码如下所示

var categoryAxis = new CategoryAxis
{
    StringFormat = "Very long item {0}",
    ItemsSource = new[] { "A", "B", "C" }
};
categoryAxis.LabelFormatter = categoryIndex =>
{
    var actualLabel = categoryAxis.ActualLabels[(int)categoryIndex];
    var spaceMatches = Regex.Matches(actualLabel, " ");
    var currentLineStartIndex = 0;
    var formattedLabel = actualLabel;
    foreach(Match space in spaceMatches)
    {
        //you can change the length of the current line allowed before inserting a new line.
        if (space.Index - currentLineStartIndex > 5)
        {
            //start counting the length of the next line starting from the current new line character
            currentLineStartIndex = space.Index;
            //replace the space with a new line character
            formattedLabel = formattedLabel.Remove(space.Index, 1);
            formattedLabel = formattedLabel.Insert(space.Index, "\n");
        }
    }
    return formattedLabel;
};

【讨论】:

  • 这是目前最好的方法!目前,我要求用户重命名他们的类别。此解决方案不适合我的用例:有时,字符串中间存在差异,其余部分相同。如果用户能在追踪器中找到差异,那就完美了! (就像图例一样,但不是类别)。
猜你喜欢
  • 2011-12-05
  • 1970-01-01
  • 2011-09-14
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多