CFWebForge.com
 
 
   
 
Home      Service      Mijn boeken      My paintings      Artikelen      Contact     
  De praktijk  
     
   
     
  SharePoint 2010
Wijzigen van lijst- en bibliotheekitems in SharePoint 2010 ---

't Kan allemaal stukken handiger dan u denkt! Meer...
 
     
  Nieuws  
     
   
     
  (Just dropped this:) jQuiry + Sexy ColdFusion = Magnetic erotic poetry!  
     
  Artikel over SharePoint 2010 - Sitestatistieken gedropt op http://tinyurl.com/3d5f4gu  
     
  Handboek SharePoint 2010 op de 7e plaats in de * top 15 * best verkochte boeken 2011 bij Computerboek.nl  
 
     
  ColdFusion tutorial - Grafieken met CFCHART  
 
 
     
 

Bekend is dat CFCHART niet werkt met de punt als decimaal, maar weer wel met de komma als decimaal.

Bekend ook is dat je dat kunt afdwingen met de functie DecimalFormal().
Maar dat je toch nog voor raadsels kunt komen te staan, bewijst dit artikel.
Over: 'had ik dat maar eerder geweten'.

   
CFCHART is mooi om mee te werken, maar kan af en toe tot behoorlijk wat frustratie leiden (als je de weg niet weet).
Ik had de twijfelachtige eer dat de afgelopen week te mogen meemaken.

Mijn bedoeling was om uit onderstaande query gegevens in CFCHART te verwerken, zodanig dat in de grafiek - naast de decimale(!) scores en een beschrijving in de popup - een omschrijving van de items op de Y-as getoond zou worden.

Om het simpel te houden: de query, gebaseerd op twee tabellen (Table_KVA_AfnameScores en Table_EVC_moduul_input) haalt in principe items (vragen) en bijbehorende scores uit de database, waarbij de scores met de functie AVG gemiddeld worden:

 

<cfquery name="RSgetAspectScore" datasource="#dsn#">
  SELECT
     A.Aspect, A.Moduul_code, E.Moduul_code, E.Moduul_omschrijving,
     AVG (KVAItemScore) AS GemAspectScore
  FROM
     Table_KVA_AfnameScores AS A, Table_EVC_moduul_input AS E
  WHERE
     KVAAfnameID = #URL.KVAAfnameID# AND
     A.Moduul_code = E.Moduul_code
     <cfif #URL.Selection# EQ "Spe">
          AND XtraSubAspect = '1'
     </cfif>
     <cfif #URL.Selection# EQ "Reg">
          AND XtraSubAspect = '0'
     </cfif>
  GROUP BY Aspect, A.Moduul_code, E.Moduul_code, E.Moduul_omschrijving
  ORDER BY Aspect ASC
</cfquery>

 

Dit leek me voldoende om gegevens uit de database en in de CFCHART te kunnen trekken...
Wat in eerste instantie niet zondermeer bleek te gaan.

1. Dat ik uit de query consequent MEER items tevoorschijn kreeg, dan dat ik in de CFCHART terug zag, was op zich al wonderlijk genoeg. Terwijl toch het resultaat van de query correct was (en dus als leidend beschouwd moest worden).

Tot je bemerkt dat het resultaat uit het veld Moduul_omschrijving voor twee verschillende GemAspectScores exact dezelfde inhoud hebben hebben! En CFCHART maakt - als je een staafdiagram als voorbeeld neemt - daar één staaf van in plaats van twee (wat eigenlijk de bedoeling is).

De oplossing: aan iedere Moduul_omschrijving een uniek kenmerk toevoegen, zodat het door CFCHART als verschillende elementen 'gezien' zou worden.
Om dat mogelijk te maken was het makkelijk genoeg om met een CFLOOP-query de gegevens in een array zetten. Waarbij en-pasant aan iedere Moduul_omschrijving een uniek nummer wordt toegekend:


<!---zet gegevens in een ARRAY--->
  <cfset GrafiekGegevens=ArrayNew(2)>
  <cfset AantRijen=0>
  <cfloop query="RSgetAspectScore">
        <cfset AantRijen=AantRijen+1>
        <cfset GrafiekGegevens[#currentRow#][1]=#RSgetAspectScore.GemAspectScore#>
        <cfset GrafiekGegevens[#currentRow#][2]=#RSgetAspectScore.Moduul_omschrijving#&" ["&#AantRijen#&"]">
  </cfloop>

Niks mis mee. Resultaat: het zelfde aantal items, dat feitelijk uit de query getrokken wordt, zie je nu ook weer terug in de grafiek van CFCHART.

Probleem opgelost (dacht ik).
Totdat...

 

2. Berucht is het feit dat CFCHART pertinent weigert te werken met decimale scores (7.1, 4.5, 5.8 etc.):

'This value cannot be converted to a number because it is not a simple value.
Simple values are booleans, numbers, strings en date-time values.'

krijg je dan voor je hoofd geslingerd.
Deze mededeling heeft al menig programmeur naar de afgrond van de wanhoop gebracht.
Maar, dit vooraf wetend (en wetend dat je dit probleem met DecimalFormat(waarde) kunt omzeilen - de punt als decimaal teken wordt daarmee omgezet naar een komma -) klopte ik fluitend de volgende code in.

"HA!, punten en komma's: wie kan mij wat?":


<cfset Grafiekhoogte = #RSgetAspectScore.RecordCount# * 20>
<cfchart
      format="flash"
      showborder="Yes"
      showlegend="Yes"
      chartheight="#Grafiekhoogte#"
      chartwidth="650"
      gridlines="5"
      rotated="yes"
      scalefrom="4"
      scaleto="8"
      xaxistitle="Module/SubDomein"
      yaxistitle="Score"
      show3d="yes"
      showygridlines="YES"
      xaxistype="score"
      yaxistype="score"
      xoffset="0.01"
      yoffset="0.01"
      labelformat="number">

<cfchartseries
      type="#URL.grafiek#"
      serieslabel="Gemiddelde score op..."
      seriescolor="#URL.Kleur#"
      paintstyle="shade">

      <cfloop from="1" to="#AantRijen#" index="i">
         <cfset varrealSc=#evaluate(GrafiekGegevens[i][1])#>
         <cfchartdata item="#GrafiekGegevens[i][2]#" value="#DecimalFormat(varrealSc)#">
      </cfloop>
</cfchartseries>

</cfchart>

F12.
Mis!

'This value cannot be converted to a number because it is not a simple value.
Simple values are booleans, numbers, strings en date-time values.'

Wat nou? 'This value cannot be converted to a number'? This value IS a number! Comma included!!

Maar CF denkt daar toch blijkbaar heel anders over.

Ik zal u maar de variaties en bedachte oplossingen van de daarop volgende twee volle(!) dagen (en avonden) besparen. Niks werkte. 'This value cannot be converted to a number...'
En wat bij dit soort problemen steekt en dan alsmaar in je achterhoofd door blijft sudderen is, dat de oplossing er is. Alleen: waar dan?

Surfend over de Macromedia Livedocs (http://livedocs.macromedia.com/coldfusion/6.1/htmldocs/tags-a11.htm), waar je nog veel meer CHART-ellende tegen komt, en bezoekjes aan verschillende forums ten spijt: niets mocht helpen. En niks gaf de oplossing.

WAT dan?
Opgeven?
Op je ogen!

Reduceren, reduceren!
Tenminste, zo luidt het credo wanneer iets niet lukt; terug tot de bron en stap voor stap het zaakje weer opbouwen. Probleemanalyse avant la lettre dus.

En zie, stond daar niet tussen al die scores een score: 0.0, 'n.v.t.'?
(Maar dat wordt in de code toch omgezet naar 0,0?)
(Maar stel dat het nu niet de code, maar een SCORE is, die de fout veroorzaakt?)

Test 1:

      <cfchartdata item="#test#" value="#0.0#">

'This value cannot be converted to...'
Ja ja dat weten we.

Test 2:

      <cfchartdata item="#test#" value="#0,0#">

'This value cannot be converted to...'
O? Kennelijk WERKT de waarde 0,0 niet in CFCHART.
Klopt dat?

Nog een test dan. 3:

      <cfchartdata item="#test#" value="#1,0#">

Werkt!

Een laatste check, voor de zekerheid. 4:

      <cfchartdata item="#test#" value="#DecimalFormat(0,0)#">

'This value cannot be converted to...'

 

Conclusie: niet de code, maar de waarde 0,0 wordt door CFCHART geweigerd en levert een foutmelding op.

 

En 0 dan?

      <cfchartdata item="#test#" value="#DecimalFormat(0)#">

Werkt!


En dat geeft meteen de oplossing voor het probleem: vang de 0,0 af met een CFIF en vervang hem door een 0 (what's in a name?) en je bent er.
De correcte uitwerking ziet u hieronder:

<cfset Grafiekhoogte = #RSgetAspectScore.RecordCount# * 20>
<cfchart
      format="flash"
      showborder="Yes"
      showlegend="Yes"
      chartheight="#Grafiekhoogte#"
      chartwidth="650"
      gridlines="5"
      rotated="yes"
      scalefrom="4"
      scaleto="8"
      xaxistitle="Module/SubDomein"
      yaxistitle="Score"
      show3d="yes"
      showygridlines="YES"
      xaxistype="score"
      yaxistype="score"
      xoffset="0.01"
      yoffset="0.01"
      labelformat="number">

<cfchartseries
      type="#URL.grafiek#"
      serieslabel="Gemiddelde score op..."
      seriescolor="#URL.Kleur#"
      paintstyle="shade">

      <cfloop from="1" to="#AantRijen#" index="i">

           <cfset varrealSc=#evaluate(GrafiekGegevens[i][1])#>
           <cfif varrealSc GT 0>
                 <cfchartdata item="#GrafiekGegevens[i][2]#" value="#DecimalFormat(varrealSc)#">
           <cfelse>
                 <cfchartdata item="#GrafiekGegevens[i][2]#" value="0">
           </cfif>

      </cfloop>
</cfchartseries>

</cfchart>

 

En uiteindelijk stelt 't op zich weer niet eens zo veel voor.

Wat u ziet:
Een normale CFChart zonder buitengewone dingen (of het moet zijn dat met de variabele 'GrafiekHoogte' dynamisch de hoogte van de grafiek wordt bepaald, omdat het aantal items uit de query (en het aantal staven in de staafdiagram) 4, maar makkelijk ook 40 kunnen zijn).

Hetzelfde geldt voor het CFChartSeries-gedeelte: geen toeters en bellen, gewoon recht door het midden.
En eigenlijk geldt dat ook voor het CFChartdata-gedeelte.
Maar dan moet je het wel even van te voren weten...

PS. Hieronder een paar delen uit de uitvoer van de pagina.
Boven de scores, onder de grafische weergave met CFCHART.

 


Gemiddelde Scores met AVG...(en de gewraakte 'n.v.t.': 0,0)

 


... en de uitvoer van dezelfde scores met behulp van CFCHART

 

Have fun!

 

 
   
  copyright © Peter van der Woude