(ConTeXt MkIV)PiechartMP 中的文本

(ConTeXt MkIV)PiechartMP 中的文本

因此我需要在文档中包含一些饼图。由于我使用 Metapost 制作所有图形,因此我尝试使用PiechartMPMetapost 包。但出于某种奇怪的原因,没有显示任何文本,只有一个非常小的方块。

最小的例子:

\startMPinitializations
input piechartmp ;
\stopMPinitializations

\startreusableMPgraphic{pie}
u := 5mm;
r := 3u;
SetupPercent(this, "x") ;

Segment(32.5,"first",auto);
Segment(12.8,"second",auto);
Segment(22.4,"third",auto);
Segment(18.2,"fourth",auto);

beginfig(1);
PieChart(r, 0, 0, 0, 0);
SetupValue("{\tfd ", "}");
label (btex textext(Text) etex,origin);
endfig;
\stopreusableMPgraphic

\starttext
\reuseMPgraphic{pie}
\stoptext

我尝试过使用TEX(加载 MetapostTEX模块)、使用\sometxttextext命令,但都没有成功。在 Metapost 中设置更大或不同的字体只会使该方块变大,但不显示任何文本。我做错了什么吗?提前感谢您的帮助。

答案1

修复方法(简短版本)

您缺少简单的兼容模式:

\starttext
  \startMPcode
    useplainlabels ;
    input piechartmp;
    Segment(30, "first");
    Segment(70, "second");
    PieChart(1cm, 0, 0, 0, 0);
    Label.auto(0)(name)(outwards,0);
    ResetSegments;
  \stopMPcode
\stoptext

截图1

失败原因

与传统的 MetaPost 不同,MkIV 使用 LuaTeX 内置的 MetaPost 库 mplib。在 mplib 中,许多 MetaPost 变量被放入 namespace 分离内部代码并减少名称冲突的可能性。通常这没有问题,用户很少直接更改它们。然而,一些 MetaPost 模块(其中包括 PiechartMP 模块)依赖于原始名称,因此与 LuaTeX 不兼容。较新的模块应使用 MetaPost installlabel 宏以可移植的方式定义标签方向。

这里的关键问题是 PiechartMPauto使用传统名称定义自定义标签方向,然后 mplib 尝试使用函数的偏移量来排版这些标签 thelabel计算,其假设命名空间的新名称。

要使 PiechartMP 模块与 mplib 一起工作,您需要普通兼容模式。此模式包含在 ConTeXt 中,因为 2013.08.25 14:06。要切换到兼容模式,请使用宏 useplainlabels或者对应的环境版本:

startplaincompatibility ;
  … some MetaPost code …
stoplaincompatibility ;

针对旧 ConTeXt 版本的解决方案

由于最近才添加了普通兼容模式,并且由于某种原因您无法更新安装,因此您可能需要一种解决方法。最简单的方法是覆盖标签打印功能以使用 PiechartMP 使用的传统名称。缺点是您可以预料到手动排版的标签会损坏。

\startMPinclusions
    input piechartmp;

    vardef thelabel@#(expr p,z) =
        if string p :
          thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p)
            scaled defaultscale,z)
        else :
          p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))
    enddef;
\stopMPinclusions

\starttext
  \startMPcode
    Segment(30, "first");
    Segment(70, "second");
    PieChart(1cm, 0, 0, 0, 0);
    Label.auto(0)(name)(outwards,0);
    ResetSegments;
  \stopMPcode
\stoptext

改善标签排版

您尝试调整饼图中的字体。最好在 MetaPost 实例中进行此类调整,该实例应为这些图表创建。优点是代码是分开的,不会干扰其他 MetaPost 代码。此外,可以使用以下方式自定义 MetaPost 实例 \defineMPinstance

另一个改进是将 MetaPost 标签与 ConTeXt 结合起来,使它们适应正文字体。默认情况下,MetaPost 使用 绘制标签defaultfont。这是通过将宏挂接 textext到打印标签的路由中来完成的:

vardef _makeText primary s =
  textext(s)
enddef;

下面是一个例子:

\defineMPinstance
  [piechartmp] [metafun]
  [textstyle=bigbodyfont]

\setupbodyfont [pagella]

\startMPinclusions{piechartmp}
  useplainlabels;
  input piechartmp;

  vardef _makeText primary s =
    textext(s)
  enddef;
\stopMPinclusions

\starttext

  \startMPcode{piechartmp}
    SetupPercent(this, "\%");

    Segment(38, "first",  auto);
    Segment(22, "second", auto);
    Segment(22, "third" , auto);
    Segment(18, "fourth", auto);

    PieChart(3cm, 1, 0, 0, .05);
    Label.auto(0)(percent)(inwards,(1,1)) withcolor white;
    Label.auto(0)(name)(outwards,0);
    ResetSegments;
  \stopMPcode

\stoptext

截图2

由于此实例中使用了较大的字体,因此标签以较大的字体打印 bigbodyfont,并且它们以 TeXGyre Pagella 打印并适应正文字体。

我替换MPinitializationsMPinclusions原因是 MetaPost 初始化是全球的而不是特定 MetaPost 实例的本地实例。此外,MetaPost 初始化是每张图形都触发,这将比必要的更频繁地执行定义。

重置片段

在每个图表之前或之后,需要使用 重置段 ResetSegments。如果不重置段,它们会干扰下一个图形,并且会绘制过多的段。这可以手动完成,但重复且容易出错,因此最好将其自动化。如上一节所述,我们认为 MetaPost 初始化是在每个图形。这正是我们想要的。因此让我们自动重置段:

\startMPinitializations
  ResetSegments;
\stopMPinitializations

三维图形

默认情况下,PiechartMP 使用统一颜色来绘制三维图表。MetaFun 支持使用linear_shade 宏进行着色。幸运的是,PiechartMP 支持此功能,并且可以在 MetaFun 可用时绘制更逼真的图表。不幸的是,PiechartMP 从特殊扩展代码中检查旧 MkII 变量是否存在,context_spec 而最近的 MkIV 中没有该变量,因此失败了。正确的方法是检查 metafunversion。认为这是 PiechartMP 中的一个错误。要修复此问题,请定义context_spec 加载piechartmp.mp或设置pc_Metafuntrue,其工作于任何点。这里有两个三维图形,一个使用默认渲染,另一个使用 MetaPost 的线性阴影。

\setupbodyfont [pagella, 16pt]

\startuseMPgraphic{pie-default}
  input piechartmp;
  Segment(28); Segment(28);
  Segment(32); Segment(12);
  PieChart(3cm, 1, 65, 0, .0);
  ResetSegments;
\stopuseMPgraphic

\startuseMPgraphic{pie-metafun}
  pc_Metafun := true;
  \includeMPgraphic{pie-default}
\stopuseMPgraphic

\starttext

  \startcombination
    \startcontent \useMPgraphic{pie-default} \stopcontent
    \startcaption Default shading            \stopcaption
    \startcontent \useMPgraphic{pie-metafun} \stopcontent
    \startcaption MetaFun shading            \stopcaption
  \stopcombination
\stoptext

截屏

补充笔记

开始图(1);…结束图;

不要beginfig(1) … endfig在 MPgraphic 中使用。该图形已定义为 \startuseMPgraphic 或者 \startreusableMPgraphic

设置值(“{\tfd”,“}”);

textstyle使用MetaPost 实例的键设置文本,defaultfont如果不想使用专用实例,则重新定义:

defaultfont := "Sans sa 1.2";

标签(btex textext(文本)etex,来源);

不要放在textext(…)两者之间btex…etex。选择其中一个

draw textext("Foo");  %% draws using the body font
label("Foo", origin); %% draws using defaultfont

例子

现在让我们把所有这些放在一起,并创建一个具有所有提到的功能的完整示例。

\defineMPinstance
  [piechartmp] [metafun]
  [textstyle=bigbodyfont]

\setupbodyfont [pagella]

\startMPinclusions{piechartmp}
  useplainlabels;
  input piechartmp;
  pc_Metafun := true;

  vardef _makeText primary s =
    textext(s)
  enddef;

  SetupPercent(this, "\%");
\stopMPinclusions

\startMPinitializations
  ResetSegments;
\stopMPinitializations

\startuseMPgraphic{piechartmp::pie-segments}
  Segment(28, "first"); Segment(28, "second");
  Segment(32, "third"); Segment(12, "fourth");
\stopuseMPgraphic

\startuseMPgraphic{piechartmp::pie-one}
  \includeMPgraphic{piechartmp::pie-segments}
  PieChart(3cm, 1, 70, 0, 0);
\stopuseMPgraphic

\startuseMPgraphic{piechartmp::pie-two}
  \includeMPgraphic{piechartmp::pie-segments}
  PieChart(3cm, 1, 50, 0, .2);
  Label.auto(0)(percent)(inwards,(1,1)) withcolor white;
\stopuseMPgraphic

\startuseMPgraphic{piechartmp::pie-three}
  \includeMPgraphic{piechartmp::pie-segments}
  PieChart(3cm, 1, 0, 0, .1);
  Label.auto(0)(percent)(inwards,(0,1)) withcolor white;
  Label.auto(0)(name)(outwards,0);
\stopuseMPgraphic

\startuseMPgraphic{piechartmp::pie-four}
  \includeMPgraphic{piechartmp::pie-segments}
  PieChart(3cm, 1, 60, 0, .2);
\stopuseMPgraphic

\starttext
  \startcombination
    {\useMPgraphic{piechartmp::pie-one}}   {\useMPgraphic{piechartmp::pie-two}}
    {\useMPgraphic{piechartmp::pie-three}} {\useMPgraphic{piechartmp::pie-four}}
  \stopcombination
\stoptext

截图4

最后的想法

请考虑一下,饼图是一种非常糟糕的数据可视化方式,如果可能的话,你应该避免使用它们,尤其是三维饼图。我在这里只提供一些链接。

相关内容