1

I am trying to use cfchart to display numbers of messages and all works well but when I have a small amount of numbers it breaks it into decimals. Is there a way we can make it always set to whole numbers?

Here is the code:

<cfchart format="#display#" type="bar" show3d="no" showlegend="false" chartHeight="300" chartWidth="220">
       <cfchartseries  colorlist="##E18014,green,red" type="bar">
             <cfchartdata item="Calls Made" value="#voice_messages.TotalMessages#">

             <cfchartdata item="Successful" value="#voice_messages.ReceiptsReceived#">
             <cfif #voice_messages.DeliveryFailures# neq "0">
             <cfchartdata item="Bus/No Ans" value="#voice_messages.DeliveryFailures#">
             </cfif>
       </cfchartseries>
</cfchart>

And here is a pic of the graph

enter image description here

I looked all over on Stack and the web but didn't find anything. Any help would be greatly appreciated.

Thanks!!

rrk
  • 15,677
  • 4
  • 29
  • 45
Scott
  • 459
  • 2
  • 10
  • There is a mismatch between your code and your picture. In addition to the mismatched labels as pointed out by @BKBK, you are showing code for one graph and a picture of two. – Dan Bracuk Apr 19 '20 at 18:30
  • @Scott - Hard coding any sample values ensures everyone is using the exact same code, which cuts down on guesswork and confusion :-) Here's an example https://trycf.com/gist/78bdc843d1ad9ebccb5b3aad84d90e06/acf2018?theme=monokai – SOS Apr 20 '20 at 14:49

3 Answers3

1

<cfchart> has an attribute called yAxisValues. It accepts an array of values. For this situation, once I had my data, I would do something to produce a suitable array to use for this attribute.

Dan Bracuk
  • 20,699
  • 4
  • 26
  • 43
  • Do you have an example? I'm curious as I wouldn't have thought the results would be any different. – SOS Apr 18 '20 at 00:18
  • Ageax, we you asking me for an example? Thanks – Scott Apr 18 '20 at 20:53
  • 1
    @Scott - No. The question was directed to Dan. I believe you need to change the axis interval, not the values. So I'm not sure `yAxisValues` would make any difference. – SOS Apr 19 '20 at 04:47
  • A simple example is at https://trycf.com/gist/426061e794b317da2aa1faf4a1d83583/acf2018?theme=monokai. The first `cfchart` tag is copied from the question, and then changed to put hard coded values in the place of variables. The second is the same as the first, but with the `yAxisValues` attribute. Both charts have integers only on the y axis. The first chart has a maiximum y axis value of 2. The second has all the values in the array. – Dan Bracuk Apr 19 '20 at 15:32
  • 1
    Ah, so the attribute really represents a 'label'. Thanks. Learn something new every day... The [zingcharts documentation](https://www.zingchart.com/docs/api/json-configuration/graphset/scale-y) pointed to an even simpler method for forcing the interval size: `scale-y : {"values" : "min:max:step"}`. Unfortunately the CF version only supports an array for "values", but you can get around it by using `yAxis` with the `min-value`, `max-value` and `step` properties https://trycf.com/gist/be817ef18926dd537e0a3209b34e2615/acf2018?theme=monokai – SOS Apr 20 '20 at 14:16
-1

Verify whether the chartdata values voice_messages.TotalMessages, voice_messages.ReceiptsReceived and are infact integers. Use something like:

<cfset displayChart=false>

<cfif    (isNumeric(voice_messages.TotalMessages) and voice_messages.TotalMessages gte 0)
     and (isNumeric(voice_messages.ReceiptsReceived) and voice_messages.ReceiptsReceived gte 0)
     and (isNumeric(voice_messages.DeliveryFailures) and voice_messages.DeliveryFailures gte 0)>

    <cfset numberOfMessages=int(voice_messages.TotalMessages)>
    <cfset numberOfReceipts=int(voice_messages.ReceiptsReceived)>
    <cfset numberOfFailures=int(voice_messages.DeliveryFailures)>

    <cfset displayChart=true>
</cfif>

<cfif displayChart>
    <!--- You may have to increase the chartWidth to make room for all the labels--->
    <cfchart format="png" type="bar" show3d="no" showlegend="false" chartHeight="300" chartWidth="300">
       <cfchartseries  colorlist="##E18014,green,red" type="bar">
             <cfchartdata item="Calls Made" value="#numberOfMessages#">

             <cfchartdata item="Successful" value="#numberOfReceipts#">
             <cfif numberOfFailures neq 0>
                <cfchartdata item="Bus/No Ans" value="#numberOfFailures#">
             </cfif>
       </cfchartseries>
   </cfchart>
<cfelse>
    Sorry, chart cannot be displayed because chartdata are not all integers.
</cfif>

In any case, you should realize that the labels in the display you have shown do not correspond to those in the code.

BKBK
  • 484
  • 2
  • 9
  • One of us doesn't understand the question. – Dan Bracuk Apr 19 '20 at 18:22
  • The scale intervals aren't guaranteed to be whole numbers, if the integers are small enough. – SOS Apr 20 '20 at 14:51
  • You might have misunderstood my answer, Look a bit deeper. ColdFusion's underlying engine is Java. In Java, 1.0 (a float or double) has a completely different interpretation from 1 (an integer). – BKBK Apr 21 '20 at 08:20
  • Oh, please be reminded of one more reason why you need to validate numberOfMessages, numberOfReceipts and numberOfFailures as integers: ColdFusion is weakly typed. As such, it can accept all manner of chartdata as numeric values, for example, "001.0". Such values might be suggstive to the underlying chart engine. Just sayin. – BKBK Apr 21 '20 at 08:37
  • Seems like you've misunderstood the question about ZingCharts. – SOS Apr 21 '20 at 15:31
  • Those variables are most likely to be query results in which case validating them is a waste of processing. – Dan Bracuk Apr 21 '20 at 18:45
  • ZingChart calculates intervals dynamically based on the input. Validating the input is a whole number [doesn't change that behavior](https://trycf.com/gist/0f61654eb8e1f8acf2d24937c6f09a79/acf2018?theme=monokai). If you want a specific interval size or a specific set of labels, you must use [one of these methods](https://stackoverflow.com/a/61280155/8895292) . – SOS Apr 21 '20 at 20:46
  • The database and ColdFusion are 2 separate domains. Neither may make assumptions about the other ("Separation of concerns"). Validating results from a query is not a waste of processing. It is in fact best-practice, especially in a weakly typed language. – BKBK Apr 22 '20 at 08:10
  • It bears repeating: validating input before using it is general best-practice in every programming language. It is NOT about ZingChart or about ColdFusion. You are a service, and you require an integer input; I am your client, and it's best-practice for me to validate my input before calling your service. – BKBK Apr 22 '20 at 08:15
  • For the sake of discussion, whenever you say a contributor doesn't understand anything, please justify. – BKBK Apr 22 '20 at 08:22
  • Cfchart + yAxisValue might be a workaround, but it is not an answer. The question is about the cfchartseries and cfchartdata tags, not about the cfchart tag. From what I understand, Scott wishes to know why a cfchartseries of bar-type displays a decimal scale on the y-axis when the cfchartdata values are positive whole numbers. – BKBK Apr 22 '20 at 08:34
  • I think you're still misunderstanding the issue. They want the y-axis tick *increments* to be whole numbers. That's only happening when the input values are large enough. With small values, the increments "[break] ..into decimals". Validating the input is an integer or using `{"decimal" : 0}` doesn't fix that problem The correct way to control the behavior is by passing the appropriate properties to ZingChart via cfchart attributes. https://trycf.com/gist/5cb29e6b2dba962ad2ecee4debd0113e/acf2018?theme=monokai – SOS Apr 24 '20 at 19:03
  • I see your point. Given Scott's picture, I assumed the 3 bars have heights 1, 1, 2, not 1, 1, 1. In any case, neither is your suggestion the answer. For 2 reasons. Setting the attribute yAxis, as you have done (1) is undocumented; (2)says nothing about the "decimal" problem. To extend my solution, I edited the file C:\ColdFusion2018\cfusion\charting\styles\bar by adding the "values" attribute, like this: "scale-y" : { "decimals" : 0, "values" : "0:2:1", "format" : "%v", "font-size" : 16, ... . Here, "values" stands for: min:0, max:2, steps:1. – BKBK Apr 25 '20 at 15:25
  • I have submitted a ColdFusion Feature Request: https://tracker.adobe.com/#/view/CF-4208102 – BKBK Apr 25 '20 at 16:15
  • Sure it is documented. Have another look. The ZingCharts documentation is very complete, so you may have missed it. As I explained below, the example is just another way of using the shortcut `"values": "min:max:step"`. Obviously using whole numbers for all three takes care of the fractional increments. While my finding could be applied at a systems wide level, that is a rather rigid approach, as it changes *all* charts. Using cfchart level attributes allows far more flexibility. Sadly CF doesn't support the shortcut "values" syntax yet, so separate properties are neeeded for now. – SOS Apr 25 '20 at 17:25
  • You say, "Sure it is documented", then add later "Sadly CF doesn't support the shortcut "values" syntax yet, so separate properties are neeeded for now". That is precisely what I meant by undocumented - in ColdFusion, not in Zingcharts. Nevertheless, I agree with you that ColdFusion should enable the inclusion of complex attributes such as "values" in the chart tag. Hence my Feature Request to Adobe. – BKBK Apr 26 '20 at 18:39
  • You said also, "While my finding could be applied at a systems wide level, that is a rather rigid approach, as it changes all charts. Using cfchart level attributes allows far more flexibility.". A sentiment I share. I consider the decimal issue a shortcoming in ColdFusion. What we've been looking for are more workarounds than solutions. – BKBK Apr 26 '20 at 18:50
  • I disagree. Respectfully, calling a 3rd party component property 'undocumented' just because the CF docs don't duplicate the entire vendor list of features is taking things a bit too literally ;-) Adobe's own docs indicate the cfchart descriptions are only examples of supported properties. Probably because there are hundreds, if not thousands, of ZingChart properties. Duplicating the vendor's docs on all of them would be a waste of time. Bottom line, if you only use 3rdparty comp properties, etc.. explicitly listed in the Adobe docs, you'll be missing out on a lot of 'supported' features. – SOS Apr 26 '20 at 23:02
  • Though if you think min-value, max-value and step are all undocumented, not sure why you'd use "values" in your example. – SOS Apr 27 '20 at 02:17
  • We're apparently speaking at cross purposes. By undocumented, I mean something different from what you say. My meaning: you MAY in fact use a large number, if not all, of the ZingCharts attributes in ColdFusion (for example, through the charting-styles config files, as I myself have done!). However, ColdFusion has not yet reached a stage where you can pass every ZingCharts property (for example, "values") as an attribute in the cfchart tag. – BKBK Apr 29 '20 at 09:21
-1

I shall now give you another answer. It is an answer of last resort, because it involves a changing ColdFusion server settings. Perhaps the reason you cannot easily find it on the web. Again, please be warned beforehand: it is a change of server setting. So back up your files!

ColdFusion 2018 (my version) uses the settings for ZingCharts to configure style in cfcharts. You will find the relevant files at C:\ColdFusion2018\cfusion\charting\styles. You want to edit the style file for bar charts.

Open in a text editor the file C:\ColdFusion2018\cfusion\charting\styles\bar. It has JSON format.

Locate the element "scale-y". It begins with:

"scale-y" : { "format" : "%v", "font-size" : 16, ... and so on.

Prepend to it the key-value pair "decimals" : 0. The result should be:

"scale-y" : { "decimals" : 0, "format" : "%v", "font-size" : 16, ... and so on.

This will ensure that the y-axis will have 0 decimal places.

Save the file and restart ColdFusion for the changes to take effect.

You have now configured the y-axis in cfchart's bar charts to no longer have decimals.

You will have noticed that the element "scale-y" is a sub-element of "graphset". Should you be interested in knowing more about their settings, then go to https://www.zingchart.com/docs/api/json-configuration/graphset

BKBK
  • 484
  • 2
  • 9
  • What happens if there is code for a chart elsewhere on this server where decimal values are appropriate? Also, what happens when developers do not have permission to do stuff like this on production servers? – Dan Bracuk Apr 21 '20 at 18:48
  • Modifying system wide files isn't required. That setting could be applied through cfchart's YAxis attribute. That said, I don't think it's what the OP is after. As it results in displaying "1" ten times on the y axis ("1, 1, 1, 1, 1, 1, 1, 1, 1, 1") instead of the original decimals ("0.1, 0.2, 0.3, 0.4, ...., 1.0"). – SOS Apr 21 '20 at 22:53
  • Correction, repeated five times or ...something like that. – SOS Apr 21 '20 at 23:29