RMChart

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Lembrem-se que tem inconvenientes na criação de gráficos.
Convém testar mais de uma janela, ao mesmo tempo ou não, porque as funções parecem se lembrar de cada gráfico.

A solução deve variar conforme a LIB gráfica.

A minha dá pra ver acima, vinculei a DLL ao programa que chama os gráficos.
E cada gráfico recebe uma ID diferente.

Também lembro de ter visto em algum lugar sobre um limite de 20 gráficos ou algo assim.
Mas foi tanto lugar que olhei, que não lembro aonde foi... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Daniel
Usuário Nível 3
Usuário Nível 3
Mensagens: 373
Registrado em: 13 Ago 2003 22:42
Localização: Apucarana - PR

RMChart

Mensagem por Daniel »

Quintas falei errado e o sexto elemento rs
Eu vi isso mais se mandar deletar primeiro ai gera o novo gráfico sera que resolve??
Daniel

Harbour + Minigui + dbfcdx
Marinas-Gui Pena que parou o suporte
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Mesmo assim tive problemas, como se o ID ficasse vinculado à janela que nem existe mais.
A saída é sempre ir incrementando o ID.

Pensei em tratar isso na classe, somando sempre 1.
(Além de deletar o gráfico no final - DeleteChart( nId ).

Pensei em tratar mais coisas na classe:

- O ID, deixando na classe, eliminaria a necessidade desse parâmetro toda hora.
- O tamanho dos arrays, idem
- Um Begin() pra incrementar o Id, e um End() pra deletar o gráfico no final

Só que deixaria incompatível com os exemplos existentes, ou com o fonte gerado pelo RMDesigner.


Ou a saída mais simples: reservar uma janela pra gráficos, e usar sempre a mesma.
Apenas ocultar quando estiver fora de uso.
Aí dá pra usar sempre o mesmo Id.

Também pensei em usar a opção de gerar JPG/PNG/Bitmap, mas só dá pra fazer isso gravando em disco.
Deste jeito nem precisaria de janela pro RMChart, apenas de uma janela pra mostrar a imagem no final.

Vou começar a usar assim, e ver o que acontece.
Pode ser que assim já esteja resolvido pro uso normal.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Me lembrou disso, então fiz um teste.

Código: Selecionar todos

FUNCTION Main()

   hb_ThreadStart( { || Test() } )
   hb_ThreadWaitForAll()
   RETURN NIL
Executei a mesma rotina de gráfico em uma thread ok.
A mesma rotina em mais de uma thread... GPF.
Cada rotina com sua própria janela e seu própripo RMChart.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Idem alterando o número do gráfico.

Código: Selecionar todos

FUNCTION Main()

   hb_ThreadStart( { || Test( 0 ) } )
   hb_ThreadStart( { || Test( 10 ) } )
   hb_ThreadStart( { || Test( 20 ) } )
   hb_ThreadWaitForAll()
   RETURN NIL
Pelo que andei lendo de janela pra activex (atlaxwin), a janela anterior funciona como "container", guardando dados do activex.
Acho possível que o RMChart, mesmo usando DLL, acabe fazendo algo parecido.
Vou fazer mais testes, mas pelo jeito só dá pra carregar uma vez a DLL (ou não dá pra descarregar).
E por isso não pode repetir Id.

Isso é fácil de contornar, só criar uma variável estática com a classe do RMChart, e outra com a próxima Id, caso não seja feito isso na classe.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Daniel
Usuário Nível 3
Usuário Nível 3
Mensagens: 373
Registrado em: 13 Ago 2003 22:42
Localização: Apucarana - PR

RMChart

Mensagem por Daniel »

Pelo teste aqui com janelas o RMChart apaga a janelas anterior com a mesma ID sem eu mandar deletar e não da erro
com ID diferente cria sem erro o mesmo gráfico em varias janelas
só fechar as janelas que o RMChart delata automático e pode cria de novo sem erro
Daniel

Harbour + Minigui + dbfcdx
Marinas-Gui Pena que parou o suporte
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

RMChart

Mensagem por asimoes »

Olá Quintas,

Você já sabe pelo facebook que eu fiz uma cirurgìa dia 25/05 e graças a Deus já estou em casa.

Já estou acompanhando desde o meu último post aqui e já estou babando com as evoluções sobre Rm.

Temos uma versão vamos dizer assim:

beta 1.0 ou 1.x nas classes os um fonte demo para testar.

Parabéns!
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Faltou postar aqui o completo.

http://www.jpatecnologia.com.br/arquivo ... mchart.zip
testrmchart.png
Os #define de cores originais estão em Upper/Lower, por exemplo, Default, Red, Blue, DarkBlue, Goldenred, LightGreen, etc.
Melhor alterar pra RMC_DEFAULT, RMC_RED, RMC_BLUE, RMC_DARK_BLUE, RMC_GOLDENRED, RMC_LIGHT_GREEN.
Só que pode ser que sejam as cores do Windows, que poderíamos usar em qualquer tela, neste caso, melhor COLOR_BLUE, COLOR_RED, etc.
Deixei COLOR_* mas não testei se vale pras LIBs gráficas.
Essa idéia de cores é legal pra aproveitar nos fontes normais de trabalho.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Dica pra mais gráficos:

Carregue um gráfico pronto, ou crie o seu próprio no rmdesigner:
rmdesigner.png
Escolhe obter código fonte
rmdesigner2.png
escolha VB6 usando DLL, código compacto.
rmdesigner3.png
fonte obtido:

Código: Selecionar todos

    Dim i AS LONG
    Dim nC AS LONG
    Dim nDataCount AS LONG
    Dim nRetVal AS LONG
    Dim sTemp AS STRING
    ReDim aData(0) AS DOUBLE
    ReDim aData2(0) AS DOUBLE
    ReDim aPPC(0) AS LONG
    ReDim aColor(0) AS LONG
 
 
    '************** Create the chart ********************** 
    nRetVal = RMC_CreateChartOnDC(Me.hDC,ID_RMC1,10,10,600,450,MidnightBlue,RMC_CTRLSTYLEIMAGE,FALSE,"seasky.jpg","Tahoma", Default)
    IF nRetVal < 0 THEN GOTO IsError
    '************** Add Region 1 ***************************** 
    nRetVal = RMC_AddRegion(ID_RMC1,5,5,-5,-5,"",FALSE) 
    IF nRetVal < 0 THEN GOTO IsError
    '************** Add legend to region 1 ******************************* 
    sTemp = "Apples*Citrons*Bananas*Cherries"
    nRetVal = RMC_AddLegend(ID_RMC1,1,sTemp,RMC_LEGEND_CUSTOM_CENTER,Default,RMC_LEGENDNORECT,White,8,FALSE) 
    IF nRetVal < 0 THEN GOTO IsError
    '************** Add Series 1 to region 1 ******************************* 
    '****** Read color values ******
    Redim aColor(3)
    aColor(0) = LightGreen
    aColor(1) = Yellow
    aColor(2) = Goldenrod
    aColor(3) = Crimson
    '****** Read data values ******
    REDIM aData(3)
    aData(0) = 40 : aData(1) = 30 : aData(2) = 60 : aData(3) = 20
    nRetVal = RMC_AddGridlessSeries(ID_RMC1,1, aData(0), 4,aColor(0),4,RMC_DONUT_GRADIENT,RMC_FULL,0,FALSE,RMC_VLABEL_TWIN,RMC_HATCHBRUSH_OFF, 0) 
    IF nRetVal < 0 THEN GOTO IsError
 
    nRetVal = RMC_SetWatermark(RMC_USERWM,RMC_USERWMCOLOR,RMC_USERWMLUCENT,RMC_USERWMALIGN,RMC_USERFONTSIZE)
    nRetVal = RMC_Draw(ID_RMC1)
    IF nRetVal < 0 THEN GOTO IsError
    Exit SUB 
 
    IsError: 
fonte no Harbour

Código: Selecionar todos

   LOCAL aColors := { COLOR_LIGHT_GREEN, COLOR_YELLOW, COLOR_GOLDENROD, COLOR_CRIMSON }
   LOCAL aData   := { 40, 30, 60, 20 }

   oRmChart:CreateChart( oCrt:hWnd,ID_RMC1,0,0,MAX_SIZE_ONE,MAX_SIZE_TWO,COLOR_MIDNIGHT_BLUE,RMC_CTRLSTYLEIMAGE,.F.,"seasky.jpg","Tahoma", 0, COLOR_DEFAULT )
   oRMChart:AddRegion(ID_RMC1,5,5,-5,-5,"",.F.)
   oRMChart:AddLegend(ID_RMC1,1,"Apples*Citrons*Bananas*Cherries",RMC_LEGEND_CUSTOM_CENTER,COLOR_DEFAULT,RMC_LEGENDNORECT,COLOR_WHITE,8,.F.)
   oRmChart:AddGridlessSeries(ID_RMC1,1, aData, 4, aColors, 4,RMC_DONUT_GRADIENT,RMC_FULL,0,.F.,RMC_VLABEL_TWIN,RMC_HATCHBRUSH_OFF, 0)
   oRmChart:SetWatermark(RMC_USERWM,RMC_USERWMCOLOR,RMC_USERWMLUCENT,RMC_USERWMALIGN,RMC_USERFONTSIZE)
   oRmChart:Draw(ID_RMC1)
Basicamente o jeito de definir variáveis e arrays é que se altera.
Mas IMPORTANTE: o exemplo usa CreateChartOnDC() que tem um parâmetro a menos. Se não adicionar um zero antes do último parâmetro ao trocar pra CreateChart(), dá GPF.

Nota: comecei o print-screen usando o gráfico 4 em 1, mas depois achei melhor usar um exemplo mais simples pra mostrar o fonte, e alterei o gráfico no meio do caminho.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

RMChart

Mensagem por asimoes »

O FALSE e o TRUE poderia até ser um define

#define FALSE .F.
#define TRUE .T.

Já aproveita boa parte do código
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Sim.

Esta parte:

Código: Selecionar todos

nRetVal = RMC_AddRegion(ID_RMC1,5,5,-5,-5,"",FALSE)
Geralmente o pessoal copia desse jeito.
Mas se não vai usar o nRetVal, melhor nem colocar, senão o Harbour compilado com -w3 -es2 vai reclamar que não está usando isso pra nada.

Apenas pra curiosidade, no próprio VB6 ficaria diferente se não usa o retorno, porque não seria escrito como função:

Código: Selecionar todos

RMC_AddRegion ID_RMC1 5 5 -5 -5, "", FALSE
Talvez quem montou a rotina pra VB6 também tenha copiado de outra.... rs
Mas já mostrou como detectar se deu erro em cada comando...

IMPORTANTE também:
o RMChart é meio chatinho quanto a coisas erradas. É comum obter GPF dependendo do que estiver errado.
Por exemplo, só no último gráfico houve problema de converter outro parâmetro, e estava gerando GPF sem a conversão, enquanto nos demais funcionava perfeito. Foi o único que usou cores como array. Pode ser que ainda existam situações pela frente onde precise alguma conversão extra em determinados parâmetros.
Geralmente ocorre quando o parâmetro é um array, e até agora o ::ToDouble() resolveu.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Por último:
Até que o fonte da classe ficou interessante, pode servir de modelo pra usar outras DLLs.

Código: Selecionar todos

CREATE CLASS RmChart

   VAR    nHandle

   METHOD New()                            INLINE ::nHandle := hb_libLoad( "RMChart.dll" ), SELF
   METHOD Destroy()                        INLINE hb_libFree( ::nHandle )
   METHOD CreateChart( ... )               INLINE ::CallDllStd( "RMC_CREATECHART", ... )
   METHOD CreateChartOnDc( ... )           INLINE ::CallDllStd( "RMC_CREATECHARONDC", ... )
   METHOD AddBarSeries(a,b,c, ... )        INLINE ::CallDllStd( "RMC_ADDBARSERIES", a, b, ::ToDouble(c), ... )
   METHOD AddRegion( ... )                 INLINE ::CallDllStd( "RMC_ADDREGION", ... )
   METHOD AddCaption( ... )                INLINE ::CallDllStd( "RMC_ADDCAPTION", ... )
   METHOD AddDataAxis(a,b,c,d,e, ... )     INLINE ::CallDllStd( "RMC_ADDDATAAXIS", a, b, c, ::ToDecimal(d), ::ToDecimal(e), ... )
   METHOD AddGrid( ... )                   INLINE ::CallDllStd( "RMC_ADDGRID", ... )
   METHOD AddGridLessSeries(a,b,c,d,e,...) INLINE ::CallDllStd( "RMC_ADDGRIDLESSSERIES", a, b, ::ToDouble(c), d, ::ToDouble(e), ... )
   METHOD AddLabelAxis( ... )              INLINE ::CallDllStd( "RMC_ADDLABELAXIS", ... )
   METHOD AddLegend( ... )                 INLINE ::CallDllStd( "RMC_ADDLEGEND", ... )
   METHOD AddLineSeries( a,b,c, ... )      INLINE ::CallDllStd( "RMC_ADDLINESERIES", a, b, ::ToDouble(c), ... )
   METHOD DeleteChart( ... )               INLINE ::CallDllStd( "RMC_DELETECHART", ... )
   METHOD Draw( ... )                      INLINE ::CallDllStd( "RMC_DRAW", ... )
   METHOD Draw2Clipboard( ... )            INLINE ::CallDllStd( "RMC_DRAW2CLIPBOARD", ... )
   METHOD Draw2Printer( ... )              INLINE ::CallDllStd( "RMC_DRAW2PRINTER", ... )
   METHOD Draw2File( ... )                 INLINE ::CallDllStd( "RMC_DRAW2FILE", ... )
   METHOD Reset( ... )                     INLINE ::CallDllStd( "RMC_RESET", ... )
   METHOD SetWaterMark( ... )              INLINE ::CallDllStd( "RMC_SETWATERMARK", ... )
   METHOD WriteRMCFile( ... )              INLINE ::CallDllStd( "RMC_WRITERMCFILE", ... )
   METHOD CallDllStd( cName, ... )         INLINE hb_DynCall( { cName, ::nHandle, HB_DYN_CALLCONV_STDCALL }, ... )
   METHOD ToDecimal( xValue )              INLINE xValue + 1.01 - 1.01
   METHOD ToDouble( xValue )

   ENDCLASS

METHOD RMChart:ToDouble( xValue )

   LOCAL cDouble := "", oElement

   IF ValType( xValue ) == "N"
      RETURN xValue
   ENDIF
   FOR EACH oElement IN xValue
      cDouble += FToC( oElement )
   NEXT

   RETURN cDouble
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

RMChart

Mensagem por asimoes »

Acredito que com relação as cores seja a mesma situação do harupdf onde para produzir as cores precisa dividir por 255 (seria o ::todouble)

nRed := Round(212 / 255, 2),;
nGreen := Round(255 / 255, 2),;
nBlue := Round(255 / 255, 2)
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Não é isso.
A minha idéia era, por exemplo, ao criar um pushbutton azul, usar COLOR_BLUE, aproveitando o #define do RMChart.
Mas não deu certo.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

RMChart

Mensagem por JoséQuintas »

Se considerar estas cores:

Código: Selecionar todos

#define RMC_COLOR_WHITE                  -1
#define RMC_COLOR_YELLOW                 -256
Parece que o padrão é CMY e não RGB.
As três cores primárias são diferentes.
colors.png
colors.png (8.92 KiB) Exibido 11219 vezes
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder