以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  双图表只有一行数据时显示不正确  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=121767)

--  作者:happyft
--  发布时间:2018/7/12 18:06:00
--  双图表只有一行数据时显示不正确

图片点击可在新窗口打开查看此主题相关图片如下:图表5.jpg
图片点击可在新窗口打开查看

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:图表.foxdb


如图,生成图表的代码在表事件的currentchanged中,
当点击节点3数据筛选只有一条时条形图填满了整个图表,什么原因?

谢谢!

--  作者:有点甜
--  发布时间:2018/7/12 20:34:00
--  

\'---生成图表

Dim Chart As WinForm.Chart \'定义一个图表变量
Dim Series As WinForm.ChartSeries \'定义一个图系变量
Dim tbn As String = "发货产品统计"
Dim t As Table = Tables(tbn) \'定义一个变量t引用数据表
Chart = Forms(tbn).Controls("Chart1") \' 引用窗口中的图表
Chart.ChartType = ChartTypeEnum.Bar \'图表类型
Chart.ChartType2 = ChartTypeEnum.Bar \'图表2类型
\'Chart.DataSource = tbn  \'设置绑定表

Dim Xi As Integer
Dim dts As List(Of String)  \'数组集合
dts = DataTables(tbn).GetValues("年",t.Filter)

Xi = dts.Count
\'A---根据表中的分组行数计算图表的X轴点数及图表长度-----
Chart.AxisX.Min = 0 \'指定坐标轴的最大最小值
If Xi < 20 Then
    Chart.AxisX.Max = 40 + 1 \'指定X轴的最大值
    Chart.Width = 600 \'图表默认宽度
Else  \'上面默认宽度/点数600/40=15
    Chart.AxisX.Max = Xi*2 + 1 \'指定X轴的最大值
    If Xi * 25 < 600 Then
        Chart.Width = 600  \'图表默认宽度
    Else
        Chart.Width = Xi*25
    End If
End If
\'A-----------------------------------------------------
\'---根据条件计算数量及金额最大值
Dim flt As String
Dim max1,max2 As Double
flt = "序号 = \'" & Tables(tbn).Current("序号") & "\'"

max1 = Tables(tbn).Compute("Max(数量)",flt)
max1 = math.Ceiling(max1*1.1)
max2 = Tables(tbn).Compute("Max(金额)",flt)
max2 = math.Ceiling(max2*1.1)

Chart.SeriesList.Clear() \'清除图表原来的图系
Chart.Axisx.ClearValueLabel  \'清除设置的数值字符标示
Series = Chart.SeriesList.Add() \'增加第一个图系
Series.Length = Xi*2 + 1  \'图系点数(*2是为了错开显示,即1,3显示数量,2,4显示金额)
Series.Text = "数量"  \'指定图例名称
\'Series.Y.DataField = "数量"
Series.FillColor = Color.SkyBlue

Chart.AxisY.Text = "数量"
Chart.AxisY.Min = 0 \'指定Y轴的最小值
Chart.AxisY.Max = max1 \'指定Y轴的最大值
\'Chart.AxisX.Major = 1 \'主刻度间隔值为5000
\'Chart.BarClusterWidth = 40
Chart.AxisX.MinorTick = False  \'不显示副刻度

\'2---根据是否有筛选条件生成图表-------------------------
If flt > "" Then
    Series.X(0) = 0     \'指定水平坐标
    Series.y(0) = 0     \'指定水平坐标
    For i As Integer = 1 To Xi*2 - 1 Step 2  \'逐个序号设置坐标
        Series.X(i) = i     \'指定水平坐标
        \'---查找表中当前行的Y轴对应值
        Dim r As DataRow = DataTables(tbn).Find(flt & " And 年 = " & dts((i-1)/2)) \'找出对应周期的行
        If r IsNot Nothing Then \'如果找到对应年月的行
            Series.Y(i) = r("数量") \'指定数量作为垂直坐标
            Chart.AxisX.SetValueLabel(i,dts((i-1)/2)) \'指定字符表示
        Else
            Series.Y(i) = 0
        End If
    Next
End If
\'2-----------------------------------------------------------------

Chart.SeriesList2.Clear() \'清除图表原来的图系
Series = Chart.SeriesList2.Add() \'增加第二个图系
Series.Length = Xi*2 + 1  \'图系点数(*2是为了错开显示,即1,3显示数量,2,4显示金额)
Series.Text = "金额"  \'指定图例名称
\'Series.Y.DataField = "金额"
Series.FillColor = Color.Orange
Chart.AxisY2.Text = "金额"
Chart.AxisY2.Min = 0 \'指定Y轴的最小值
Chart.AxisY2.Max = max2 \'指定Y轴的最大值

Chart.LegendVisible = True \'显示图列
\'Chart.BarClusterWidth2 = 40

\'2---根据是否有筛选条件生成图表-------------------------
If flt > "" Then
    Series.X(0) = 0     \'指定水平坐标
    Series.y(0) = 0     \'指定水平坐标
    For i As Integer = 2 To Xi*2 Step 2  \'逐个序号设置坐标
        Series.X(i) = i     \'指定水平坐标
        \'---查找表中当前行的Y轴对应值
        Dim r As DataRow = DataTables(tbn).Find(flt & " And 年 = " & dts((i-1)/2-0.5)) \'找出对应周期的行
        If r IsNot Nothing Then \'如果找到对应年月的行
            Series.Y(i) = r("金额") \'指定数量作为垂直坐标
        Else
            Series.Y(i) = 0
        End If
    Next
End If
\'2---------------------------------------------------------

Chart.AxisX.AnnoWithLabels = True \'启用字符标示
Chart.AxisX.AnnoRotation = - 45
Chart.VisualEffect = True \'加上这一行,让你的图表更漂亮
Chart.LegendVisible = True \'显示图列
Chart.LegendCompass= CompassEnum.North \'图列显示在南方(底端)


--  作者:HappyFt
--  发布时间:2018/7/13 15:07:00
--  
请教一下,实际运用中有下面的代码:
Series.Length = Xi*2 + 1  \'图系点数(*2是为了错开显示,即1,3显示数量,2,4显示金额) 
 Series.X(0) = 0     \'指定水平坐标
 Series.y(0) = 0     \'指定垂直坐标
 For i As Integer = 1 To Xi*2 +1 Step 2  \'逐个序号设置坐标
    Series.X(i) = i     \'指定水平坐标
   Dim r As DataRow = DataTables(tbn).Find("年 = " & Ary(0) & " And " & glb.Substring(glb.LastIndexOf("|")+1) & " = " & Ary(1))  ‘对应周期的数量
   If r IsNot Nothing Then \'如果找到对应年月的行
   msgbox(r("数量"))
      Series.Y(i) = r("数量") \'指定数量作为垂直坐标
      Chart.AxisX.SetValueLabel(i,Ary(0) & "-" & Ary(1)) \'指定字符表示
   Else
      Series.Y(i) = 0
   End If
 Next
上面的代码,循环变量总数是61,循环到31时,红色那名执行就出错了,显示索引超出范围
想问一下:用Series.Length = Xi*2 + 1 这句指定了图系长度后,Series.X与Series.Y的个数应该相等,都是一样的吧,
Series.X(i) = i 没有错误,为什么Series.Y(i) = r("数量")会出错呢?


--  作者:有点甜
--  发布时间:2018/7/13 15:52:00
--  

Series.X(i) 只能赋值为 0、1、2、3、4、5 这样的数字。

 

如果你要修改x轴的值,需要设置 Chart.AxisX.SetValueLabel(i, r("数量")) \'指定字符表示


--  作者:HappyFt
--  发布时间:2018/7/13 16:51:00
--  
不是设置字符错误,而是为某个点赋Y轴的值时出错,还有下面这个例子中,用数组合集合时也有问题


图片点击可在新窗口打开查看此主题相关图片如下:图表6.jpg
图片点击可在新窗口打开查看

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:图表2.foxdb


点击显示所有节点时就对不上。代码也是在Currentchanged事件中。

谢谢!

--  作者:有点甜
--  发布时间:2018/7/13 17:08:00
--  
 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:图表2.foxdb


--  作者:HappyFt
--  发布时间:2018/7/13 17:51:00
--  
为什么要 -0.49,理解不了,遍历时
For i As Integer = 2 To Xi*2 Step 2  \'逐个序号设置坐标
    Series.X(i) = i     \'指定水平坐标
    \'---查找表2咱当前行的Y轴对应值
    Dim Ary As String() = Arys((i-2)/2-0.49)  \'拆分每一周期组合的字符串数组

i 是2,4,6等,2要对应从第一个数组中取值即arys(0),所以才用Arys((i-2)/2),但为什么减去0.5或者0.49?



--  作者:有点甜
--  发布时间:2018/7/13 18:17:00
--  

哦,不需要减去0.49那些的。

 

你把月份列改成整数类型即可。