How to pass query results into Amchart? - coldfusion

Please consider the following code:
Following tag inside header of my file
<script>
var chart;
var chartData = [{
ConnectionType: "First",
NumberPercentage: 1194,
{
ConnectionType: "Second",
NumberPercentage: 1882},
{
ConnectionType: "Third",
NumberPercentage: 1809},
{
ConnectionType: "Fourth",
NumberPercentage: 1322},
{
ConnectionType: "Fifth",
NumberPercentage: 1122},
{
ConnectionType: "Sixth",
NumberPercentage: 1114},
{
ConnectionType: "Seventh",
NumberPercentage: 984}
];
AmCharts.ready(function() {
// PIE CHART
chart = new AmCharts.AmPieChart();
// title of the chart
chart.addTitle("3D Donut Charts", 16);
chart.dataProvider = chartData;
chart.titleField = "ConnectionType";
chart.valueField = "NumberPercentage";
chart.sequencedAnimation = true;
chart.startEffect = "elastic";
chart.innerRadius = "30%";
chart.startDuration = 2;
chart.labelRadius = 15;
// the following two lines makes the chart 3D
chart.depth3D = 10;
chart.angle = 15;
// WRITE
chart.write("chartdiv");
});
</script>
Following tag inside body tag of my profile:
<div id="chartdiv" style="width: 100%; height: 362px;"></div>
I want to return the data from the following cfquery in my ColdFusion file. For the sake of simplicity I'm only mentioning cfquery for First connection. Rest cfqueries till seventh are same except the names.
<cfquery datasource = "XX.XX.X.XX" name="qCFCHART">
SELECT
Count(*) AS TOTAL_CONNECTION
, Sum(CASE WHEN 'FIRST' = EVENTS THEN 100 END) / Count(*) AS FIRST
, Sum(CASE WHEN 'SECOND' = EVENTS THEN 100 END) / Count(*) AS SECOND
, Sum(CASE WHEN 'THIRD' = EVENTS THEN 100 END) / Count(*) AS THIRD
, Sum(CASE WHEN 'FOURTH' = EVENTS THEN 100 END) / Count(*) AS FOURTH
, Sum(CASE WHEN 'FIFTH' = EVENTS THEN 100 END) / Count(*) AS FIFTH
, Sum(CASE WHEN 'SIXTH' = EVENTS THEN 100 END) / Count(*) AS SIXTH
, Sum(CASE WHEN 'SEVENTH' = EVENTS THEN 100 END) / Count(*) AS SEVENTH
FROM MyDatabase;
</cfquery>
Considering the code from above script:
ConnectionType: "First",
NumberPercentage: 1194,
I want to display the result returned by "FIRST" from the above query into my Pie Chart and writing cfdump or anything ColdFusion related doesn't work there.
For example:
ConnectionType: "First",
NumberPercentage: <cfdump var="#qCFCHART.FIRST#>",
The above throws an error and I see an obvious reason because I'm inside script tag and I'm wondering how to proceed? Any suggestions?
Here is my attempt after following some comments:
<cfoutput query="qCFCHART">
#currentrow#)
<cfloop index="col" list="#columnlist#">
#col#=#qCFCHART[col][currentRow]#
</cfloop>
<p/>
</cfoutput>
<cfset cols = getMetadata(qCFCHART)>
<cfdump var="#cols#">

You will need to loop over the query and create a data structure similar to what the chart is expecting - which appears to be an array of structures.
I am not going to give you the code to do this as it is a fairly simple operation, and one you could easily find information on if you choose to look for it.
You can then use serialzeJSON( data ) to get the JSON version of your data - which should have the same structure as chartData in your sample code.

What you need to do is output values from your server-side coldfusion query into your client-side javascript. e.g
<cfoutput>
var chartData = [{
ConnectionType: "First",
NumberPercentage: #qCFCHART.FIRST#},
{
ConnectionType: "Second",
NumberPercentage: #qCFCHART.Second#},
{
ConnectionType: "Third",
NumberPercentage: #qCFCHART.Third#},
{
ConnectionType: "Fourth",
NumberPercentage: #qCFCHART.Fourth#},
{
ConnectionType: "Fifth",
NumberPercentage: #qCFCHART.Fifth#},
{
ConnectionType: "Sixth",
NumberPercentage: #qCFCHART.Sixth#},
{
ConnectionType: "Seventh",
NumberPercentage: #qCFCHART.Seventh#}
];
</cfoutput>
The main reason your cfdump approach might not have worked is because you have a syntax error here:
<cfdump var="#qCFCHART.FIRST#>"
Should have been
<cfdump var="#qCFCHART.FIRST#">
But I'd strongly recommend against using cfdump; just output the value normally, there shouldn't be any need to 'dump' values into production code.

The simple fix to this question was that I needed to mention <cfoutput>#serializeJSON(qCFCHART.First)#</cfoutput> after Number Percentage field and it worked fine.

Related

cube.js playground not plotting data correctly

I am using cube.js to compare the change in data over the time by plotting it as a line graph .
Step 1 :
After generating cube.js schema successfully , data looks like this:
Step 2 :
Now, while I am trying to check the line graph, it's showing the line as below . No line is formatted. Unfortunately, it's not working for the bar graph also .
Moreover, in SQL the data type for the value is : float(10,10) and timestamp
Apart from that, cube.js console has not error trace , rather its working fine :
Performing query: scheduler-0070c129-f83a-45db-ae09-aac6f9858200
Executing SQL: scheduler-0070c129-f83a-45db-ae09-aac6f9858200
--
SELECT FLOOR((UNIX_TIMESTAMP()) / 10) as refresh_key
Moreover , I tried as below : [all time ,w/o grouping and pivot settings as I need ] , yet no luck ,
However, If I add measure count , the count is plotting the lie not the expected y-axis data as I configured in pivot settings.
My question is : what's going wrong ?
My goal was to generate a line graph for the change of a numerical value over time:
x-axis: date/time.
y-axis: my numerical value.
Cube.js Generated the following schema for my data.
The problem with this schema was that String Type was assigned to the age dimension(clearly should be a Number). Moreover ,there are no measures for filed age ,which I am trying to plot.
cube(`ConceptDrifts`, {
sql: `SELECT * FROM cube.concept_drifts`,
preAggregations: {
},
joins: {
},
measures: {
count: {
type: `count`,
drillMembers: [date]
},
testCount: {
sql: `test_count`,
type: `sum`
}
},
dimensions: {
age: {
sql: `age`,
type: `string`
},
maxAge: {
sql: `max_age`,
type: `string`
},
sex: {
sql: `sex`,
type: `string`
},
sexSd: {
sql: `sex_sd`,
type: `string`
},
date: {
sql: `date`,
type: `time`
}
},
dataSource: `default`
});
Therefore, I changed the schema at /cube/conf/schema# manually
Added new measures a:
ag :{
type : `number`,
sql : `age`,
drillMembers : [age]
}
And, changed the type (as number ) in dimensions :
dimensions: {
age: {
sql: `age`,
type: `number`
},
maxAge: {
sql: `max_age`,
type: `number`
},
sex: {
sql: `sex`,
type: `number`
},
sexSd: {
sql: `sex_sd`,
type: `number`
},
date: {
sql: `date`,
type: `time`
}
},
dataSource: `default`
});
As a result, the graph looks like below :
More reference :
Data Schema Concepts
Drilldowns

Type Mismatch error when altering a google.visualization.DataTable() column value even after explicitly changing its data type

I have a datatable that's being returned by google.visualization.data.group()
var aggData = google.visualization.data.group(
view,
[0],
aggColumns
);
I want to set several columns to be of type string with a tooltip role, and converting values in them to an html string
for (var col=2; col < aggData.getNumberOfColumns(); col = col + 2){
aggData.setColumnProperties(col,{'type':'string', 'role':'tooltip', 'p':{'html':true}});
//looking to see if the column type was actually changed
console.log('Column '+col+' type: ' + aggData.getColumnProperty(col, 'type'))
for (var row = 0; row < aggData.getNumberOfRows(); row = row + 1){
aggData.setValue(row, col, getHTML(aggData.getValue(row, col)))
}
}
function getHTML(count) {;
return 'Projects Completed: <b>' + count + '</b>';
}
I checked the column data type in the log and it does return a string but when i set the value to a string it throws a type mismatch error.
Column 2 type: string
Uncaught Error: Type mismatch. Value Projects Completed: <b>2</b> does not match type number in column index 2
I also tried setting the column type using setColumnProperty() method but it's the same result. What am I missing?
================================================================================================
Below is a snippet of the larger script if needed
Sample input data looks like
"Oct 1, 2019, 12:00:00 AM",Team C,68
"Sep 23, 2019, 12:00:00 AM",Team C,68
"Nov 29, 2019, 12:00:00 AM",Team C,87
"Dec 31, 2019, 12:00:00 AM",Team C,62
....................................
"Nov 21, 2018, 12:00:00 AM",Team A,79
"Dec 29, 2018, 12:00:00 AM",Team A,58
"Nov 15, 2018, 12:00:00 AM",Team B,96
"Dec 29, 2018, 12:00:00 AM",Team B,77
The data is being read into a data table
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Year');
data.addColumn('string', 'Team');
data.addColumn('number', 'Total Score');
var groupData = google.visualization.data.group(
data,
[
{
column: 0,
modifier: getYear,
type: 'number'
},
1
],
[
{
column: 2,
aggregation: google.visualization.data.sum,
type: 'number'
},
{
column: 2,
aggregation: google.visualization.data.count,
type: 'number',
role: 'tooltip'
}
]
);
// create data view from groupData
var view = new google.visualization.DataView(groupData);
// sum column array
var aggColumns = [];
// use year (column 0) as first view column
var viewColumns = [0];
// build calculated view & agg columns for each team
groupData.getDistinctValues(1).forEach(function (team, index) {
// add a column to the view for each team
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === team) {
return dt.getValue(row, 2);
}
return null;
},
label: team,
type: 'number'
});
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === team) {
return dt.getValue(row, 3);
}
return null;
},
label: 'Number of Projects',
type: 'number'
});
// add sum column for each team
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index*2 + 1,
label: team,
type: 'number'
});
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index*2 + 2,
type: 'number',
role: 'tooltip',
});
});
// set view columns
view.setColumns(viewColumns);
var aggData = google.visualization.data.group(
view,
[0],
aggColumns
);
/*
The aggData looks like
"2,018",137,2,173,2,0,0
"2,019",864,12,"1,028",12,610,12
*/
for (var col=2; col < aggData.getNumberOfColumns(); col = col + 2){
aggData.setColumnProperties(col,{'type':'string', 'role':'tooltip', 'p':{'html':true}});
console.log('Column '+col+' type: ' + aggData.getColumnProperty(col, 'type'))
for (var row = 0; row < aggData.getNumberOfRows(); row = row + 1){
aggData.setValue(row, col, getHTML(aggData.getValue(row, col)))
}
}
data table method setColumnProperties isn't doing what you expect.
it only sets the properties portion of the column --> 'p':{'html':true}
so after your code runs, you end up with the following in your column properties.
'p': {'type':'string', 'role':'tooltip', 'p':{'html':true}}
and in fact, it is not possible to change a column's type,
once it has been created.
instead, you'll need to either use the addColumn or insertColumn method.
another option would be to use a data view.
then you could use a calculated column for the tooltip,
and exclude the original column you are trying to change,
using the setColumns method on the data view.

trying to get the data like this from the cfc function

I have a cfc where i need t return the headers for the jqgrid for binding dynamically
i am trying to query the data like this:
colNames: ['ID', 'Institution Name', 'Display Name', 'Short Name', 'Board of Education', 'Scheme Name','Subscription Date'],
colModel: [
{ name: 'institutionid', sortable: true, },
{ name: 'institutionname', sortable: true },
{ name: 'displayname', sortable: true },
{ name: 'shortname' ,sortable: true},
{ name: 'supportedfield', sortable: true },
{ name: 'schemename', sortable: true },
{ name: 'subscriptionto', sortable: true}
]
i can easily get the colNames, but for colmodal how can i bring the elements of sort: true for all by default and format should be like arrayofstructs
Thanks
Query try
<cffunction name="headers" localmode="modern" access="remote" returnformat="json" hint="Handles the Functionality of returning the Table Headers">
<cfset columnsInfos = {}>
<cfset returnArray = []>
<cfset cList = QueryExecute("select top 1 * from mytable").columnList>
<cfset cListQueryObj = QueryNew(cList)>
<cfdump var="#cListQueryObj#" abort>
<cfset colNames = ListtoArray(cList)>
<cfloop query="#cListQueryObj#">
<cfset rowStruct = {}>
<cfloop list="#cList#" index="colname">
<cfset "rowStruct['#colname#']" = cListQueryObj[colname]>
</cfloop>
<cfset arrayAppend(returnArray,rowStruct)>
<cfdump var="#rowStruct#">
</cfloop>
<cfset columnsInfos["colModel"] = returnArray>
<cfset columnsInfos["colNames"] = colNames>
<cfreturn columnsInfos>
</cffunction>
Serializing a query object won't return the expected result. Since you are using the built-in returnFormat="json", the easiest (and probably only) approach is working with an array of structs, just like your JS example shows:
<cffunction name="headers" localmode="modern" access="public" returnformat="json" hint="Handles the Functionality of returning the Table Headers">
<!--- best practise: declare the returned scheme --->
<cfset result = {
"colNames": [],
"colModel": []
}>
<!--- get your table's columns (mockup) --->
<cfset columnList = "institutionid,institutionname,displayname,shortname,supportedfield,schemename,subscriptionto">
<!--- use the column names from your query? --->
<cfset result["colNames"] = listToArray(columnList)>
<!--- add an entry with "name" and "sortable" for every column --->
<cfloop list="#columnList#" index="columnName">
<cfset result["colModel"].add({
"name": columnName,
"sortable": true
})>
</cfloop>
<cfreturn result>
</cffunction>
Note that we are not calling serializeJSON on the result, because returnFormat="json" will already do that for us. Regarding your colNames: Your JS example uses mapped column names, not dynamic ones as shown in your code and the code above. You might want to make them either static or map them yourself.
I like Alex's approach, but I like cfscript better. I also like localized variables.
<cfscript>
/**
* #hint Handles the Functionality of returning the Table Headers
* #output false
* #returnFormat JSON
*/
public any function headers() {
// best practise: declare the returned scheme
var result = {
"colNames": [],
"colModel": []
};
// get your table's columns (mockup)
var columnList = "institutionid,institutionname,displayname,shortname,supportedfield,schemename,subscriptionto";
// use the column names from your query?
result.colNames = listToArray(columnList);
// add an entry with "name" and "sortable" for every column
for (var columnName in columnList) {
result.colModel.add({
"name": columnName,
"sortable": true
});
}
return result;
}
writedump(headers);
writedump(headers());
</cfscript>
Function signature
Function results
Also see
JSON response using cfscript function

underscore: groupBy on django timestamp

i have the objects each having timestamp field , consist datetime like
data1 --> "2014-06-26T11:06:19.315404+00:00"
data2 --> "2014-06-26T08:04:29.755019+00:00"
data3 --> "2014-06-26T08:03:51.008563+00:00"
using underscore.js i;m trying to group the data by timestamp field like
grp_data = _.groupBy(result, "timestamp")
Expected result:
{"2014-06-26": [data1, data2, data3] }
what is happening is :
{"2014-06-26": [data1],
{"2014-06-26": [data2],
{"2014-06-26": [data3],
}
the reason of above behavior is since the each timestamp of data1, data2, data3 are different because of T11:06:19.315404+00:00" which is appending in timestamp.
that is why data is not grouped expectedly.
Is there any way around this ?
Pass a function to the groupBy that extracts the date part:
var result = [
{ id: 'data1', timestamp: "2014-06-26T11:06:19.315404+00:00" },
{ id: 'data2', timestamp: "2014-06-26T11:06:19.315404+00:00" },
{ id: 'data3', timestamp: "2014-06-26T11:06:19.315404+00:00" }
];
var extractDate = function(datum){
return datum.timestamp.substring(0,10);
}
var grp_data = _.groupBy(result, extractDate);

Google Table Chart: Date Format

I am returning data to the chart using JSON.
I've managed to format the date for the x-axiz of the Line Chart, using;
var options = {
hAxis: {
format: ' dd MMM yy'
},
}
But I need help doing the same for a Table Chart where one of the columns should be of date format.
At the moment it is displaying "/Date(1372761341103)/"
How do I format this option?
As I understand it, the "options" variable setting is not available for the Table Chart.
Also, when I add my columns, setting my 'Date' column's data type to 'date' doesn't work...no chart is returned.
This is my code currently:
function drawChart3() {
$.get('/MyMall/GetAdRunData', {},
function (data) {
/* Add data */
var tdata = new google.visualization.DataTable()
tdata.addColumn('number', 'Id');
tdata.addColumn('string','Date');
tdata.addColumn('number', 'Opens');
for (var i = 0; i < data.length; i++) {
tdata.addRow([data[i].Id, data[i].Date, data[i].Opens]);
}
/* Draw chart */
var chart = new google.visualization.Table(document.getElementById('chart_adRun'));
//var formatter = new google.visualization.ColorFormat();
//var monthYearFormatter = new google.visualization.DateFormat({ pattern: "MMM yyyy" });
monthYearFormatter.format(tdata, 0);
formatter.addRange(-1, 1, 'white', 'orange');
formatter.addRange(0, 2, 'red', '#33ff33');
formatter.addRange(1, 10, 'red', 'pink');
formatter.format(tdata, 1); // Apply formatter to second column
chart.draw(tdata, { allowHtml: true, showRowNumber: false });
}
)
}
I solved it this way...
for (var i = 0; i < data.length; i++) {
var date = new Date(parseInt(data[i].Date.substr(6)));
tdata.addRow([data[i].Id, date, data[i].Opens]);
}