我想要一个相当简单(且便宜)的解决方案,仅用于演示目的(并且只是为了显示任务持续时间栏 - 它们之间没有连接线)。因此,例如,我对购买一些像这样的高级自定义控件不感兴趣。你们有没有人用过这样的东西?是否有可用的代码示例?
2 回答
我会指向Buck Woolley 的 dwExtreme 站点,以获取有关如何在本机 DataWindow 中进行甘特图的示例。但是,如果您想自己动手,我认为“简单”不会出现在您的未来。事实上,如果有人写了一个包含完整描述的帖子,我会感到惊喜;我认为这需要页面。(如果有人证明我错了,我会很高兴。)同时,这里有一些我认为你需要的 DataWindow 基础知识:
- 您可以创建一个数据源未绑定到表的外部 DataWindow
- 数据集中的列不必显示在用户界面上
- 数据集中的列可用于表达式来评估属性,因此您可以为矩形的以下每个属性设置一列:
- X
- 宽度
- 颜色
我预计这需要大量的工作和时间,并且很可能值得购买该组件(除非您的时间几乎没有价值,这在某些 IT 商店中几乎是真实的)。
祝你好运,
特里
(来源:illudium.com)
您可以使用堆叠条形图(画家中的 BarStacked (5))制作简单的甘特图。诀窍是创建一个虚拟系列以将条与您想要的位置隔开,并使虚拟条与图形的背景颜色相同(BackColor)。事实证明,您还需要另一个具有较小值的虚拟系列来坐在轴上。否则,当您更改间距条的颜色时,轴线会被切断。我发现 .04 很适合这个值。
创建数据窗口
(假设您熟悉 DataWindow 向导。有关在 DataWindows 中创建图形的更多信息,请参阅 PowerBuilder 用户指南)
单击新对象向导的图标。使用外部数据源创建 Graph DataWindow。创建列任务类型字符串 (20)、服务类型字符串 (1) 和天数类型。将 Category 设置为 task 列,将 Values 设置为 days 列。单击系列按钮并为系列选择 ser。不要打扰标题,并选择堆叠条形图类型。当画家打开时,保存 DataWindow。在 Painter 的 General 选项卡上,将 Legend 更改为 None (0)。在 Axis 选项卡上,选择 Category 轴,然后将排序设置为 Unsorted (0)。选择值轴,然后将排序设置为未排序 (0)。选择系列轴并将排序设置为升序 (1)。保存数据窗口。
创建窗口
创建一个窗口并放置一个 DataWindow 控件 dw_1。将数据对象设置为图形 DataWindow。将以下内容放在 open 事件中(或 pfc_postopen 如果使用 PFC)。
try
dw_1.setRedraw(FALSE)
// LOAD DATA HERE
dw_1.object.gr_1.title = 'Project PBL Pusher'
dw_1.object.gr_1.category.label = 'Phase'
dw_1.object.gr_1.values.label = 'Project-Days'
catch (runtimeerror re)
if isvalid(gnv_app.inv_debug) then gnv_app.inv_debug.of_message(re.text) // could do better
finally
dw_1.setRedraw(TRUE)
end try
您将在评论说的地方加载图表的数据// LOAD DATA HERE
编写 graphcreate 事件脚本
将新事件添加到 dw_1。选择 pbm_dwngraphcreate 作为事件 ID。我喜欢通过删除 pbm_dwn 前缀来命名这些事件,因此我使用了 graphcreate。将以下代码添加到事件中。
string ls_series
long li_color
try
li_color=long(dw_1.object.gr_1.backcolor)
// note first series is a dummy with a small value (0.04 seems to work) to keep the line from being hidden
ls_series = dw_1.seriesName("gr_1", 2)
if 0 = len(ls_series) then return // maybe show error message
// will return -1 when you set color same as the graph's backcolor but it sets the color
dw_1.setSeriesStyle("gr_1", ls_series, BackGround!, li_color) // the box
dw_1.setSeriesStyle("gr_1", ls_series, ForeGround!, li_color) // the inside
catch (runtimeerror re)
if isvalid(gnv_app.inv_debug) then gnv_app.inv_debug.of_message(re.text) // could do better
end try
图表数据
以与您想要的相反顺序加载具有类别的数据。对于每个任务,插入 3 行并将系列分别设置为 a、b 和 c。对于每个任务中的系列 a,设置一个较小的值。我用的是 0.04。您可能需要进行实验。对于每个任务中的系列 b,设置开始前的天数。对于系列 c,设置天数。下面是示例 DataWindow 中的数据。
Task Ser Days
---- --- ----
Test a 0.04
Test b 24
Test c 10
Develop a 0.04
Develop b 10
Develop c 14
Design a 0.04
Design b 0
Design c 10
示例数据窗口
以下是导出格式的示例 DataWindow 的源代码。您应该能够导入任何版本 >= PB 10。复制代码并将其粘贴到具有 SRD 扩展名的文件中,然后将其导入。
HA$PBExportHeader$d_graph.srd
release 10;
datawindow(units=0 timer_interval=0 color=1073741824 processing=3 HTMLDW=no print.printername="" print.documentname="" print.orientation = 1 print.margin.left = 110 print.margin.right = 110 print.margin.top = 96 print.margin.bottom = 96 print.paper.source = 0 print.paper.size = 0 print.canusedefaultprinter=yes print.prompt=no print.buttons=no print.preview.buttons=no print.cliptext=no print.overrideprintjob=no print.collate=yes hidegrayline=no )
summary(height=0 color="536870912" )
footer(height=0 color="536870912" )
detail(height=0 color="536870912" )
table(column=(type=char(10) updatewhereclause=yes name=task dbname="task" )
column=(type=char(1) updatewhereclause=yes name=ser dbname="ser" )
column=(type=number updatewhereclause=yes name=days dbname="days" )
)
data("Test","a", 0.04,"Test","b", 24,"Test","c", 10,"Develop","a", 0.04,"Develop","b", 10,"Develop","c", 14,"Design","a", 0.04,"Design","b", 0,"Design","c", 10,)
graph(band=background height="1232" width="2798" graphtype="5" perspective="2" rotation="-20" color="0" backcolor="16777215" shadecolor="8355711" range= 0 border="3" overlappercent="0" spacing="100" plotnulldata="0" elevation="20" depth="100"x="0" y="0" height="1232" width="2798" name=gr_1 visible="1" sizetodisplay=1 series="ser" category="task" values="days" title="Title" title.dispattr.backcolor="553648127" title.dispattr.alignment="2" title.dispattr.autosize="1" title.dispattr.font.charset="0" title.dispattr.font.escapement="0" title.dispattr.font.face="Tahoma" title.dispattr.font.family="2" title.dispattr.font.height="0" title.dispattr.font.italic="0" title.dispattr.font.orientation="0" title.dispattr.font.pitch="2" title.dispattr.font.strikethrough="0" title.dispattr.font.underline="0" title.dispattr.font.weight="700" title.dispattr.format="[general]" title.dispattr.textcolor="0" title.dispattr.displayexpression="title" legend="0" legend.dispattr.backcolor="536870912" legend.dispattr.alignment="0" legend.dispattr.autosize="1" legend.dispattr.font.charset="0" legend.dispattr.font.escapement="0" legend.dispattr.font.face="Tahoma" legend.dispattr.font.family="2" legend.dispattr.font.height="0" legend.dispattr.font.italic="0" legend.dispattr.font.orientation="0" legend.dispattr.font.pitch="2" legend.dispattr.font.strikethrough="0" legend.dispattr.font.underline="0" legend.dispattr.font.weight="400" legend.dispattr.format="[general]" legend.dispattr.textcolor="553648127" legend.dispattr.displayexpression="' '"
series.autoscale="1"
series.displayeverynlabels="0" series.droplines="0" series.frame="1" series.label="(None)" series.majordivisions="0" series.majorgridline="0" series.majortic="3" series.maximumvalue="0" series.minimumvalue="0" series.minordivisions="0" series.minorgridline="0" series.minortic="1" series.originline="1" series.primaryline="1" series.roundto="0" series.roundtounit="0" series.scaletype="1" series.scalevalue="1" series.secondaryline="0" series.shadebackedge="0" series.dispattr.backcolor="536870912" series.dispattr.alignment="0" series.dispattr.autosize="1" series.dispattr.font.charset="0" series.dispattr.font.escapement="0" series.dispattr.font.face="Tahoma" series.dispattr.font.family="2" series.dispattr.font.height="0" series.dispattr.font.italic="0" series.dispattr.font.orientation="0" series.dispattr.font.pitch="2" series.dispattr.font.strikethrough="0" series.dispattr.font.underline="0" series.dispattr.font.weight="400" series.dispattr.format="[general]" series.dispattr.textcolor="0" series.dispattr.displayexpression="series" series.labeldispattr.backcolor="553648127" series.labeldispattr.alignment="2" series.labeldispattr.autosize="1" series.labeldispattr.font.charset="0" series.labeldispattr.font.escapement="0" series.labeldispattr.font.face="Tahoma" series.labeldispattr.font.family="2" series.labeldispattr.font.height="0" series.labeldispattr.font.italic="0" series.labeldispattr.font.orientation="0" series.labeldispattr.font.pitch="2" series.labeldispattr.font.strikethrough="0" series.labeldispattr.font.underline="0" series.labeldispattr.font.weight="400" series.labeldispattr.format="[general]" series.labeldispattr.textcolor="0" series.labeldispattr.displayexpression=" seriesaxislabel" series.sort="1"
category.autoscale="1"
category.displayeverynlabels="0" category.droplines="0" category.frame="1" category.label="(None)" category.majordivisions="0" category.majorgridline="0" category.majortic="3" category.maximumvalue="0" category.minimumvalue="0" category.minordivisions="0" category.minorgridline="0" category.minortic="1" category.originline="0" category.primaryline="1" category.roundto="0" category.roundtounit="0" category.scaletype="1" category.scalevalue="1" category.secondaryline="0" category.shadebackedge="1" category.dispattr.backcolor="556870912" category.dispattr.alignment="1" category.dispattr.autosize="1" category.dispattr.font.charset="0" category.dispattr.font.escapement="0" category.dispattr.font.face="Tahoma" category.dispattr.font.family="2" category.dispattr.font.height="0" category.dispattr.font.italic="0" category.dispattr.font.orientation="0" category.dispattr.font.pitch="2" category.dispattr.font.strikethrough="0" category.dispattr.font.underline="0" category.dispattr.font.weight="400" category.dispattr.format="[general]" category.dispattr.textcolor="0" category.dispattr.displayexpression="category" category.labeldispattr.backcolor="556870912" category.labeldispattr.alignment="2" category.labeldispattr.autosize="1" category.labeldispattr.font.charset="0" category.labeldispattr.font.escapement="900" category.labeldispattr.font.face="Tahoma" category.labeldispattr.font.family="2" category.labeldispattr.font.height="0" category.labeldispattr.font.italic="0" category.labeldispattr.font.orientation="900" category.labeldispattr.font.pitch="2" category.labeldispattr.font.strikethrough="0" category.labeldispattr.font.underline="0" category.labeldispattr.font.weight="400" category.labeldispattr.format="[general]" category.labeldispattr.textcolor="0" category.labeldispattr.displayexpression="categoryaxislabel" category.sort="0"
values.autoscale="1"
values.displayeverynlabels="0" values.droplines="0" values.frame="1" values.label="(None)" values.majordivisions="0" values.majorgridline="0" values.majortic="3" values.maximumvalue="1500" values.minimumvalue="0" values.minordivisions="0" values.minorgridline="0" values.minortic="1" values.originline="1" values.primaryline="1" values.roundto="0" values.roundtounit="0" values.scaletype="1" values.scalevalue="1" values.secondaryline="0" values.shadebackedge="0" values.dispattr.backcolor="556870912" values.dispattr.alignment="2" values.dispattr.autosize="1" values.dispattr.font.charset="0" values.dispattr.font.escapement="0" values.dispattr.font.face="Tahoma" values.dispattr.font.family="2" values.dispattr.font.height="0" values.dispattr.font.italic="0" values.dispattr.font.orientation="0" values.dispattr.font.pitch="2" values.dispattr.font.strikethrough="0" values.dispattr.font.underline="0" values.dispattr.font.weight="400" values.dispattr.format="[General]" values.dispattr.textcolor="0" values.dispattr.displayexpression="value" values.labeldispattr.backcolor="553648127" values.labeldispattr.alignment="2" values.labeldispattr.autosize="1" values.labeldispattr.font.charset="0" values.labeldispattr.font.escapement="0" values.labeldispattr.font.face="Tahoma" values.labeldispattr.font.family="2" values.labeldispattr.font.height="0" values.labeldispattr.font.italic="0" values.labeldispattr.font.orientation="0" values.labeldispattr.font.pitch="2" values.labeldispattr.font.strikethrough="0" values.labeldispattr.font.underline="0" values.labeldispattr.font.weight="700" values.labeldispattr.format="[general]" values.labeldispattr.textcolor="0" values.labeldispattr.displayexpression="valuesaxislabel" )
htmltable(border="1" )
htmlgen(clientevents="1" clientvalidation="1" clientcomputedfields="1" clientformatting="0" clientscriptable="0" generatejavascript="1" encodeselflinkargs="1" netscapelayers="0" )
xhtmlgen() cssgen(sessionspecific="0" )
xmlgen(inline="0" )
xsltgen()
jsgen()
export.xml(headgroups="1" includewhitespace="0" metadatatype=0 savemetadata=0 )
import.xml()
export.pdf(method=0 distill.custompostscript="0" xslfop.print="0" )
export.xhtml()