Error in Graph_4 Sample

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

User avatar
sudip
Posts: 1454
Joined: Sat Mar 07, 2009 11:52 am
Location: Kolkata, WB, India

Error in Graph_4 Sample

Post by sudip »

Hi,

I don't know whether it is an error or normal behavior, in pie chart when one of the value become 0 pie chart shows wrong result. Please note following code. I changed graph_4 sample to show the problem. Please compile and run and see what happens ;) Please check pie chart with data values!!!

Code: Select all

#include "minigui.ch"
function main

	define window m at 0,0 width 800 height 600 main On Init ShowPie() backcolor { 255,255,255}

		define button x
			row 10
			col 10
			caption "Draw"
			action showpie()
		end button

		Define Button Button_1
			Row	10
			Col	150
			Caption	'Print'
			Action PRINT GRAPH OF m PREVIEW DIALOG
		End Button

	end window

	m.center

	m.activate

return nil


function showpie

ERASE WINDOW m

DRAW GRAPH IN WINDOW m AT 100,100;
      TO 500,500 ;
      TITLE "Sales" ;
      TYPE PIE;
      ; //SERIES {1500,1800,200,500,800};
      SERIES {1500,1800,0,500,800};
		DEPTH 25;
		SERIENAMES {"Product 1","Product 2","Product 3","Product 4","Product 5"};
		COLORS {{255,0,0},{0,0,255},{255,255,0},{0,255,0},{255,128,64},{128,0,128}};
		3DVIEW;
		SHOWXVALUES; 
		SHOWLEGENDS NOBORDER

return nil


I faced the problem in front of one of my very good clients!

Please check the problem.

With best regards.

Sudip
With best regards,
Sudip
User avatar
esgici
Posts: 4543
Joined: Wed Jul 30, 2008 9:17 pm
DBs Used: DBF
Location: iskenderun / Turkiye
Contact:

Re: Error in Graph_4 Sample

Post by esgici »

Hi Sudip
sudip wrote:
... in pie chart when one of the value become 0 pie chart shows wrong result.
Perhaps you are right, we have a problem in TYPE PIE GRAPH.

No when one of SERIES values become zero, but when its percentage become very little, close to zero. F.e in your example result is correct when the third value 7 ( %0.28), 6 (%0.00)is not.

If you are sure that this is a bug please write to Sourceorge HMG bug tracker.
I faced the problem in front of one of my very good clients!
Very bad :( That means before deeply tested we have don't give anything to client !

Regards

--

Esgici
Viva INTERNATIONAL HMG :D
User avatar
esgici
Posts: 4543
Joined: Wed Jul 30, 2008 9:17 pm
DBs Used: DBF
Location: iskenderun / Turkiye
Contact:

Re: Error in Graph_4 Sample

Post by esgici »

Hi Sudip

I guess you need an urgent solution though temporary.

First, a question : What we want see in a graph when some values are very close to zero ?

My answer is "simply nothing".

If you too would agree, my suggestion is :

Here modified version of function showpie and added a little one.

Code: Select all

function showpie

aValues := { 1500, 1800, 0, 500, 800 }
aPNames := {"Product 1","Product 2","Product 3","Product 4","Product 5"}
aColors := { BLUE, RED, FUCHSIA, BROWN, GREEN } 
  
PGNormlz( aValues, aPNames, aColors )

ERASE WINDOW m
DRAW GRAPH IN WINDOW m AT 100,100;
      TO 500,500 ;
      TITLE "Sales" ;
      TYPE PIE;                     
      SERIES aValues ;
      DEPTH 25;
      SERIENAMES aPNames ;
      COLORS aColors ;
      3DVIEW;   
      SHOWXVALUES ; 
      SHOWLEGENDS NOBORDER

return nil

PROC PGNormlz( aValues, aNames, aColors )      // Normalizing Pie Graph values

   LOCAL nIndice := 0,;
         n1Value := 0,;
         nTotal  := 0
         
   AEVAL( aValues, { | n1Value | nTotal += n1Value } )
   
   FOR nIndice := 1 TO LEN( aValues )
      n1Value  := aValues[ nIndice ]
      nPercent := n1Value * 100 / nTotal
      IF nPercent < .016
         ADEL( aValues, nIndice )
         ASIZE( aValues, LEN( aValues ) - 1 )
         ADEL( aNames, nIndice )
         ASIZE( aNames, LEN( aNames ) - 1 )
         ADEL( aColors, nIndice ) 
         ASIZE( aColors, LEN( aColors ) - 1 )         
      ENDIF
   NEXT 
   
RETU // PGNormlz()
I hope this help you.

Regards

--

Esgici
Viva INTERNATIONAL HMG :D
User avatar
sudip
Posts: 1454
Joined: Sat Mar 07, 2009 11:52 am
Location: Kolkata, WB, India

Re: Error in Graph_4 Sample

Post by sudip »

Esgici,

Thanks a lot. It works! But I can surely tell you after several testing!

With best regards.

Sudip
With best regards,
Sudip
User avatar
sudip
Posts: 1454
Joined: Sat Mar 07, 2009 11:52 am
Location: Kolkata, WB, India

Re: Error in Graph_4 Sample

Post by sudip »

Hi Esgici,

Thanks for the very quick correction. I tested with the code. It is all right!! Yesterday I tried something similar in front of my client. But I checked with 0.00 not with 0.016 like you did in your sample.

Thank you very much.

With best regards.

Sudip
With best regards,
Sudip
User avatar
Roberto Lopez
HMG Founder
Posts: 4004
Joined: Wed Jul 30, 2008 6:43 pm

Re: Error in Graph_4 Sample

Post by Roberto Lopez »

esgici wrote:Hi Sudip

I guess you need an urgent solution though temporary.

First, a question : What we want see in a graph when some values are very close to zero ?

My answer is "simply nothing".

If you too would agree, my suggestion is :

Here modified version of function showpie and added a little one.

Code: Select all

function showpie

aValues := { 1500, 1800, 0, 500, 800 }
aPNames := {"Product 1","Product 2","Product 3","Product 4","Product 5"}
aColors := { BLUE, RED, FUCHSIA, BROWN, GREEN } 
  
PGNormlz( aValues, aPNames, aColors )

ERASE WINDOW m
DRAW GRAPH IN WINDOW m AT 100,100;
      TO 500,500 ;
      TITLE "Sales" ;
      TYPE PIE;                     
      SERIES aValues ;
      DEPTH 25;
      SERIENAMES aPNames ;
      COLORS aColors ;
      3DVIEW;   
      SHOWXVALUES ; 
      SHOWLEGENDS NOBORDER

return nil

PROC PGNormlz( aValues, aNames, aColors )      // Normalizing Pie Graph values

   LOCAL nIndice := 0,;
         n1Value := 0,;
         nTotal  := 0
         
   AEVAL( aValues, { | n1Value | nTotal += n1Value } )
   
   FOR nIndice := 1 TO LEN( aValues )
      n1Value  := aValues[ nIndice ]
      nPercent := n1Value * 100 / nTotal
      IF nPercent < .016
         ADEL( aValues, nIndice )
         ASIZE( aValues, LEN( aValues ) - 1 )
         ADEL( aNames, nIndice )
         ASIZE( aNames, LEN( aNames ) - 1 )
         ADEL( aColors, nIndice ) 
         ASIZE( aColors, LEN( aColors ) - 1 )         
      ENDIF
   NEXT 
   
RETU // PGNormlz()
I hope this help you.

Regards

--

Esgici

Very smart solution!

Thanks.

If you allow it, I'll include your code as part of DrawPieGraph() function as a permanent fix.

Regards,

Roberto.
Regards/Saludos,

Roberto


(Veritas Filia Temporis)
User avatar
esgici
Posts: 4543
Joined: Wed Jul 30, 2008 9:17 pm
DBs Used: DBF
Location: iskenderun / Turkiye
Contact:

Re: Error in Graph_4 Sample

Post by esgici »

Hello Roberto
If you allow it, ...
Please don't blush me :oops:

Everything is for community; Viva Clipper, Viva Harbour, Viva HMG :!: :!: :!:

It isn't ?

With Best Regards

--

Esgici
Viva INTERNATIONAL HMG :D
User avatar
Roberto Lopez
HMG Founder
Posts: 4004
Joined: Wed Jul 30, 2008 6:43 pm

Re: Error in Graph_4 Sample

Post by Roberto Lopez »

Roberto Lopez wrote:
If you allow it, I'll include your code as part of DrawPieGraph() function as a permanent fix.
Anyway, I'll review the code and if a more 'elegant' solution (showing the reference for 'zero' series) arises, I'll apply it.

Regards,

Roberto.
Regards/Saludos,

Roberto


(Veritas Filia Temporis)
User avatar
esgici
Posts: 4543
Joined: Wed Jul 30, 2008 9:17 pm
DBs Used: DBF
Location: iskenderun / Turkiye
Contact:

Re: Error in Graph_4 Sample

Post by esgici »

Roberto Lopez wrote: Anyway, I'll review the code and if a more 'elegant' solution ...
IMHO this will be better. Problem isn't only can't show serie value close to zero; when it is, this very little value cause a bigger problem : their "pie" overlay another pie.

Best regards

--

Esgici
Viva INTERNATIONAL HMG :D
User avatar
Roberto Lopez
HMG Founder
Posts: 4004
Joined: Wed Jul 30, 2008 6:43 pm

Re: Error in Graph_4 Sample

Post by Roberto Lopez »

esgici wrote:
Roberto Lopez wrote: Anyway, I'll review the code and if a more 'elegant' solution ...
IMHO this will be better. Problem isn't only can't show serie value close to zero; when it is, this very little value cause a bigger problem : their "pie" overlay another pie.

Best regards

--

Esgici
Well... I guess I've found the 'elegant' one.

Please, replace the function 'drawpiegraph' in \hmg\source\graph\h_graph.prg with this:

Code: Select all

function drawpiegraph(windowname,fromrow,fromcol,torow,tocol,series,aname,colors,ctitle,depth,l3d,lxval,lsleg,lnoborder)
local topleftrow := fromrow
local topleftcol := fromcol
local toprightrow := fromrow
local toprightcol := tocol
local bottomrightrow := torow
local bottomrightcol := tocol
local bottomleftrow := torow
local bottomleftcol := fromcol
local middletoprow := fromrow
local middletopcol := fromcol + int(tocol - fromcol) / 2
local middleleftrow := fromrow + int(torow - fromrow) / 2
local middleleftcol := fromcol
local middlebottomrow := torow
local middlebottomcol := fromcol + int(tocol - fromcol) / 2
local middlerightrow := fromrow + int(torow - fromrow) / 2
local middlerightcol := tocol
local fromradialrow := 0
local fromradialcol := 0
local toradialrow := 0
local toradialcol := 0
local degrees := {}
local cumulative := {}
local j,i,sum := 0
local cname := ""
local shadowcolor := {}
local previos_cumulative

_HMG_SYSDATA [ 108 ] [ GetFormIndex (windowname) ] := { fromrow , fromcol , tocol - fromcol , torow - fromrow }

if ! lnoborder

	DrawLine(windowname, torow  ,fromcol  ,torow  ,tocol  ,WHITE)
	DrawLine(windowname, torow-1,fromcol+1,torow-1,tocol-1,GRAY )
	DrawLine(windowname, torow-1,fromcol  ,fromrow  ,fromcol  ,GRAY )
	DrawLine(windowname, torow-2,fromcol+1,fromrow+1,fromcol+1,GRAY )
	DrawLine(windowname, fromrow  ,fromcol  ,fromrow  ,tocol-1,GRAY )
	DrawLine(windowname, fromrow+1,fromcol+1,fromrow+1,tocol-2,GRAY )
	DrawLine(windowname, fromrow  ,tocol  ,torow  ,tocol  ,WHITE)
	DrawLine(windowname, fromrow  ,tocol-1,torow-1,tocol-1,GRAY )
   
endif

if len(alltrim(ctitle)) > 0
   if _iscontroldefined("title_of_pie",windowname)
      _releasecontrol("title_of_pie",windowname)
   endif
   define label title_of_pie
      parent &windowname
      row fromrow + 10
      col iif(len(alltrim(ctitle)) * 12 > (tocol - fromcol),fromcol,int(((tocol - fromcol) - (len(alltrim(ctitle)) * 12))/2) + fromcol)
      autosize .t.
      fontcolor {0,0,255}
      fontbold .t.
      fontname "Arial"
      fontunderline .t.
      fontsize 12
      value alltrim(ctitle)
	transparent .t.
   end label
   fromrow := fromrow + 40
endif   

if lsleg
   if len(aname) * 20 > (torow - fromrow)
      msginfo("No space for showing legends")
   else
      torow := torow - (len(aname) * 20)
   endif
endif

drawrect(windowname,fromrow+10,fromcol+10,torow-10,tocol-10,{0,0,0},1,{255,255,255})

if l3d
   torow := torow - depth
endif

fromcol := fromcol + 25
tocol := tocol - 25
torow := torow - 25
fromrow := fromrow + 25


topleftrow := fromrow
topleftcol := fromcol
toprightrow := fromrow
toprightcol := tocol
bottomrightrow := torow
bottomrightcol := tocol
bottomleftrow := torow
bottomleftcol := fromcol
middletoprow := fromrow
middletopcol := fromcol + int(tocol - fromcol) / 2
middleleftrow := fromrow + int(torow - fromrow) / 2
middleleftcol := fromcol
middlebottomrow := torow
middlebottomcol := fromcol + int(tocol - fromcol) / 2
middlerightrow := fromrow + int(torow - fromrow) / 2
middlerightcol := tocol






torow := torow + 1
tocol := tocol + 1

for i := 1 to len(series)
   sum := sum + series[i]
next i
for i := 1 to len(series)
   aadd(degrees,round(series[i]/sum * 360,0))
next i
sum := 0
for i := 1 to len(degrees)
   sum := sum + degrees[i]
next i
if sum <> 360
   degrees[len(degrees)] := degrees[len(degrees)] + (360 - sum)
endif

sum := 0
for i := 1 to len(degrees)
   sum := sum + degrees[i]
   aadd(cumulative,sum)
next i

previos_cumulative := -1

fromradialrow := middlerightrow
fromradialcol := middlerightcol
for i := 1 to len(cumulative)
   shadowcolor := {iif(colors[i,1] > 50,colors[i,1] - 50,0),iif(colors[i,2] > 50,colors[i,2] - 50,0),iif(colors[i,3] > 50,colors[i,3] - 50,0)}

*	msginfo ( str(cumulative[i]) )

	if cumulative[i] == previos_cumulative
		loop
	endif

	previos_cumulative := cumulative[i]

   do case
      case cumulative[i] <= 45
         toradialcol := middlerightcol
         toradialrow := middlerightrow - round(cumulative[i] / 45 * (middlerightrow - toprightrow),0)
         drawpie(windowname,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
         fromradialrow := toradialrow
         fromradialcol := toradialcol
      case cumulative[i] <= 90 .and. cumulative[i] > 45
         toradialrow := toprightrow
         toradialcol := toprightcol - round((cumulative[i] - 45) / 45 * (toprightcol - middletopcol),0)
         drawpie(windowname,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
         fromradialrow := toradialrow
         fromradialcol := toradialcol
      case cumulative[i] <= 135 .and. cumulative[i] > 90          
         toradialrow := topleftrow
         toradialcol := middletopcol - round((cumulative[i] - 90) / 45 * (middletopcol - topleftcol),0)
         drawpie(windowname,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
         fromradialrow := toradialrow
         fromradialcol := toradialcol
      case cumulative[i] <= 180 .and. cumulative[i] > 135          
         toradialcol := topleftcol
         toradialrow := topleftrow + round((cumulative[i] - 135) / 45 * (middleleftrow - topleftrow),0)
         drawpie(windowname,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
         fromradialrow := toradialrow
         fromradialcol := toradialcol
      case cumulative[i] <= 225 .and. cumulative[i] > 180          
         toradialcol := topleftcol
         toradialrow := middleleftrow + round((cumulative[i] - 180) / 45 * (bottomleftrow - middleleftrow),0)
         if l3d
            for j := 1 to depth
               drawarc(windowname,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
            next j
         endif   
         drawpie(windowname,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
         fromradialrow := toradialrow
         fromradialcol := toradialcol
      case cumulative[i] <= 270 .and. cumulative[i] > 225          
         toradialrow := bottomleftrow
         toradialcol := bottomleftcol + round((cumulative[i] - 225) / 45 * (middlebottomcol - bottomleftcol),0)
         if l3d
            for j := 1 to depth
               drawarc(windowname,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
            next j
         endif   
         drawpie(windowname,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
         fromradialrow := toradialrow
         fromradialcol := toradialcol
      case cumulative[i] <= 315 .and. cumulative[i] > 270          
         toradialrow := bottomleftrow
         toradialcol := middlebottomcol + round((cumulative[i] - 270) / 45 * (bottomrightcol - middlebottomcol),0)
         if l3d
            for j := 1 to depth
               drawarc(windowname,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
            next j
         endif   
         drawpie(windowname,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
         fromradialrow := toradialrow
         fromradialcol := toradialcol
      case cumulative[i] <= 360 .and. cumulative[i] > 315
         toradialcol := bottomrightcol
         toradialrow := bottomrightrow - round((cumulative[i] - 315) / 45 * (bottomrightrow - middlerightrow),0)
         if l3d
            for j := 1 to depth
               drawarc(windowname,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
            next j
         endif
         drawpie(windowname,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
         fromradialrow := toradialrow
         fromradialcol := toradialcol
      endcase
   if l3d            
      drawline(windowname,middleleftrow,middleleftcol,middleleftrow+depth,middleleftcol)
      drawline(windowname,middlerightrow,middlerightcol,middlerightrow+depth,middlerightcol)
      drawarc(windowname,fromrow + depth,fromcol,torow + depth,tocol,middleleftrow+depth,middleleftcol,middlerightrow+depth,middlerightcol)
   endif
next i
if lsleg
   fromrow := torow + 20 + iif(l3d,depth,0)
   for i := 1 to len(aname)
      if _iscontroldefined("pielegend_"+alltrim(str(i,3,0)),windowname)
         _releasecontrol("pielegend_"+alltrim(str(i,3,0)),windowname)
      endif
      cname := "pielegend_"+alltrim(str(i,3,0))
      drawrect(windowname,fromrow,fromcol,fromrow + 15,fromcol + 15,{0,0,0},1,colors[i])
      define label &cname
         parent &windowname
         row fromrow
         col fromcol + 20
         fontname "Arial"
         fontsize 8
         autosize .t.
         value aname[i]+iif(lxval," - "+alltrim(str(series[i],10,2))+" ("+alltrim(str(degrees[i] / 360 * 100,6,2))+" %)","")
         fontcolor colors[i]
	transparent .t.
      end label
      fromrow := fromrow + 20
   next i
endif   
return nil

Since I'm not the original code author, I could be missing something important. Please Test.

Regards,

Roberto.
Regards/Saludos,

Roberto


(Veritas Filia Temporis)
Post Reply