#include "hbclass.ch" CREATE CLASS TChart FROM TObjectBase DATA cChartKind INIT "chart" DATA hChartSpec INIT { => } DATA cLl12SourceJson INIT "" METHOD New( oParent ) CONSTRUCTOR METHOD Init( oParent ) METHOD Create() METHOD End() METHOD Save() METHOD Load( hData ) METHOD GenerarRenderizable( oContextoEjecucion ) HIDDEN: METHOD DetailRecords( hData ) METHOD BuildChart( oContexto, aRecords ) METHOD BuildCrosstab( oContexto, aRecords ) METHOD StringValue( uValue ) METHOD NumberValue( uValue ) ENDCLASS METHOD New( oParent ) CLASS TChart ::Init( oParent ) RETURN Self METHOD Init( oParent ) CLASS TChart ::oParent := oParent ::cName := "Grafico" ::cType := "TChart" ::cChartKind := "chart" ::hChartSpec := { => } ::cLl12SourceJson := "" RETURN Self METHOD Create() CLASS TChart RETURN Self METHOD End() CLASS TChart ::hChartSpec := { => } ::oParent := NIL RETURN NIL METHOD Save() CLASS TChart LOCAL hData := ::Super:Save() hData[ "cChartKind" ] := ::cChartKind hData[ "hChartSpec" ] := ::hChartSpec hData[ "cLl12SourceJson" ] := ::cLl12SourceJson RETURN hData METHOD Load( hData ) CLASS TChart ::Super:Load( hData ) IF HB_ISHASH( hData ) ::cChartKind := iif( hb_HHasKey( hData, "cChartKind" ), ::StringValue( hData[ "cChartKind" ] ), "chart" ) ::hChartSpec := iif( hb_HHasKey( hData, "hChartSpec" ) .AND. HB_ISHASH( hData[ "hChartSpec" ] ), hData[ "hChartSpec" ], { => } ) ::cLl12SourceJson := iif( hb_HHasKey( hData, "cLl12SourceJson" ), ::StringValue( hData[ "cLl12SourceJson" ] ), "" ) ENDIF RETURN Self METHOD GenerarRenderizable( oContextoEjecucion ) CLASS TChart LOCAL hRender LOCAL aRecords IF ! ::EsVisibleEnEjecucion( oContextoEjecucion ) RETURN NIL ENDIF aRecords := ::DetailRecords( oContextoEjecucion:GetData() ) hRender := iif( ::cChartKind == "crosstab", ::BuildCrosstab( oContextoEjecucion, aRecords ), ::BuildChart( oContextoEjecucion, aRecords ) ) hRender[ "id" ] := ::cId hRender[ "tipo" ] := ::cChartKind hRender[ "x" ] := ::nLeft hRender[ "y" ] := ::nTop hRender[ "ancho" ] := ::nWidth hRender[ "alto" ] := ::nHeight hRender[ "zIndex" ] := ::nZIndex hRender[ "opacidad" ] := ::nOpacity hRender[ "rotacion" ] := ::nRotation hRender[ "spec" ] := ::hChartSpec RETURN hRender METHOD DetailRecords( hData ) CLASS TChart LOCAL hDetail LOCAL aKeys IF HB_ISHASH( hData ) .AND. hb_HHasKey( hData, "DetalleVar" ) .AND. HB_ISHASH( hData[ "DetalleVar" ] ) hDetail := hData[ "DetalleVar" ] aKeys := hb_HKeys( hDetail ) IF Len( aKeys ) > 0 .AND. HB_ISARRAY( hDetail[ aKeys[ 1 ] ] ) RETURN hDetail[ aKeys[ 1 ] ] ENDIF ENDIF RETURN {} METHOD BuildChart( oContexto, aRecords ) CLASS TChart LOCAL nRecordsLen := Len( aRecords ) LOCAL aPoints := Array( nRecordsLen ) LOCAL nIndex LOCAL hRecord LOCAL cCategory := iif( hb_HHasKey( ::hChartSpec, "cCategoryFormula" ), ::StringValue( ::hChartSpec[ "cCategoryFormula" ] ), Chr( 34 ) + Chr( 34 ) ) LOCAL cValue := iif( hb_HHasKey( ::hChartSpec, "cValueFormula" ), ::StringValue( ::hChartSpec[ "cValueFormula" ] ), "0" ) FOR EACH hRecord IN aRecords nIndex := hRecord:__enumIndex() oContexto:PushRegistroDetalle( hRecord, nIndex - 1, nRecordsLen, iif( nIndex > 1, aRecords[ nIndex - 1 ], { => } ), iif( nIndex < nRecordsLen, aRecords[ nIndex + 1 ], { => } ) ) aPoints[ nIndex ] := { "label" => ::StringValue( oContexto:EvaluarFormula( cCategory ) ), "value" => ::NumberValue( oContexto:EvaluarFormula( cValue ) ) } oContexto:PopRegistroDetalle() NEXT RETURN { "puntos" => aPoints } METHOD BuildCrosstab( oContexto, aRecords ) CLASS TChart LOCAL hRows := { => } LOCAL hCols := { => } LOCAL hCells := { => } LOCAL hRowStyles := { => } LOCAL hColStyles := { => } LOCAL hCellStyles := { => } LOCAL aDefinitions := iif( hb_HHasKey( ::hChartSpec, "aDefinitions" ) .AND. HB_ISARRAY( ::hChartSpec[ "aDefinitions" ] ), ::hChartSpec[ "aDefinitions" ], { ::hChartSpec } ) LOCAL hDefinition LOCAL nIndex LOCAL nDefinition LOCAL nRowLevel LOCAL nColLevel LOCAL cRow LOCAL cCol LOCAL nValue LOCAL cRowFormula LOCAL cColFormula LOCAL cValueFormula LOCAL cRowLabelFormula LOCAL cColLabelFormula LOCAL cRowLabel LOCAL cColLabel FOR nDefinition := 1 TO Len( aDefinitions ) hDefinition := aDefinitions[ nDefinition ] IF ! HB_ISHASH( hDefinition ) LOOP ENDIF nRowLevel := ::NumberValue( iif( hb_HHasKey( hDefinition, "nRowLevel" ), hDefinition[ "nRowLevel" ], 0 ) ) nColLevel := ::NumberValue( iif( hb_HHasKey( hDefinition, "nColumnLevel" ), hDefinition[ "nColumnLevel" ], 0 ) ) IF ( nRowLevel > 0 .AND. hb_HHasKey( hDefinition, "lShowRowSummary" ) .AND. ! hDefinition[ "lShowRowSummary" ] ) .OR. ; ( nColLevel > 0 .AND. hb_HHasKey( hDefinition, "lShowColumnSummary" ) .AND. ! hDefinition[ "lShowColumnSummary" ] ) LOOP ENDIF cRowFormula := iif( hb_HHasKey( hDefinition, "cRowFormula" ), ::StringValue( hDefinition[ "cRowFormula" ] ), Chr( 34 ) + Chr( 34 ) ) cColFormula := iif( hb_HHasKey( hDefinition, "cColumnFormula" ), ::StringValue( hDefinition[ "cColumnFormula" ] ), Chr( 34 ) + Chr( 34 ) ) cValueFormula := iif( hb_HHasKey( hDefinition, "cCellFormula" ), ::StringValue( hDefinition[ "cCellFormula" ] ), "" ) cRowLabelFormula := iif( hb_HHasKey( hDefinition, "cRowLabelFormula" ), ::StringValue( hDefinition[ "cRowLabelFormula" ] ), "" ) cColLabelFormula := iif( hb_HHasKey( hDefinition, "cColumnLabelFormula" ), ::StringValue( hDefinition[ "cColumnLabelFormula" ] ), "" ) IF Empty( cValueFormula ) LOOP ENDIF FOR nIndex := 1 TO Len( aRecords ) oContexto:PushRegistroDetalle( aRecords[ nIndex ], nIndex - 1, Len( aRecords ), iif( nIndex > 1, aRecords[ nIndex - 1 ], { => } ), iif( nIndex < Len( aRecords ), aRecords[ nIndex + 1 ], { => } ) ) cRow := iif( nRowLevel > 0, "__summary_row_" + hb_NToS( nRowLevel ), ::StringValue( oContexto:EvaluarFormula( cRowFormula ) ) ) cCol := iif( nColLevel > 0, "__summary_col_" + hb_NToS( nColLevel ), ::StringValue( oContexto:EvaluarFormula( cColFormula ) ) ) nValue := ::NumberValue( oContexto:EvaluarFormula( cValueFormula ) ) cRowLabel := iif( Empty( cRowLabelFormula ), "", ::StringValue( oContexto:EvaluarFormula( cRowLabelFormula ) ) ) cColLabel := iif( Empty( cColLabelFormula ), "", ::StringValue( oContexto:EvaluarFormula( cColLabelFormula ) ) ) oContexto:PopRegistroDetalle() hRows[ cRow ] := iif( Empty( cRowLabel ), iif( nRowLevel > 0, "Total", cRow ), cRowLabel ) hCols[ cCol ] := iif( Empty( cColLabel ), iif( nColLevel > 0, "Total", cCol ), cColLabel ) hRowStyles[ cRow ] := iif( hb_HHasKey( hDefinition, "hRowStyle" ) .AND. HB_ISHASH( hDefinition[ "hRowStyle" ] ), hDefinition[ "hRowStyle" ], { => } ) hColStyles[ cCol ] := iif( hb_HHasKey( hDefinition, "hColumnStyle" ) .AND. HB_ISHASH( hDefinition[ "hColumnStyle" ] ), hDefinition[ "hColumnStyle" ], { => } ) IF ! hb_HHasKey( hCells, cRow ) hCells[ cRow ] := { => } hCellStyles[ cRow ] := { => } ENDIF hCells[ cRow ][ cCol ] := iif( hb_HHasKey( hCells[ cRow ], cCol ), hCells[ cRow ][ cCol ], 0 ) + nValue hCellStyles[ cRow ][ cCol ] := iif( hb_HHasKey( hDefinition, "hCellStyle" ) .AND. HB_ISHASH( hDefinition[ "hCellStyle" ] ), hDefinition[ "hCellStyle" ], { => } ) NEXT NEXT RETURN { ; "filas" => hRows, ; "columnas" => hCols, ; "celdas" => hCells, ; "estilos" => { "filas" => hRowStyles, "columnas" => hColStyles, "celdas" => hCellStyles } } METHOD StringValue( uValue ) CLASS TChart RETURN ::ValorAString( uValue ) METHOD NumberValue( uValue ) CLASS TChart RETURN ::ValorANumero( uValue )