从Google Charts的SQL查询格式化ColdFusion JSON

Bec*_*cca 5 coldfusion charts json google-visualization

完全披露 - 我对任何类型的网络编码都很陌生,所以TIA请耐心等待!

我要做的是查询数据并使用它来构建动态Google图表.在Coldfusion中,我查询了SQL Server的数据,然后输出为JSON(我在http://jsonlint.com/上验证了这个JSON ,它说它有效).如果我尝试在Google图表中直接使用此JSON,则会收到错误:"未捕获的错误:无效的JSON字符串",因为JSON的格式不是Google图表所需的格式.

以下是ColdFusion从SQL查询创建的JSON片段:

{"COLUMNS":["DATE","TEMP_C"],"DATA":[["08\/09\/2016",27.04],["08\/09\/2016",26.98],["08\/09\/2016",27.02],      …etc
Run Code Online (Sandbox Code Playgroud)

以下是Google图表预期的格式:

{ 
"cols": [ 
    {"id":"","label":"SignIn Method","pattern":"","type":"string"},
    {"id":"","label":"Count","pattern":"","type":"number"} 
   ], 
"rows": [ 
    {"c":[{"v":"manual","f":null},{"v":123,"f":null}]}, 
    {"c":[{"v":"swipe","f":null},{"v":20,"f":null}]} 
   ] 
}
Run Code Online (Sandbox Code Playgroud)

我一直在尝试将JSON重组为Google图表所需的格式,我无法弄明白.我一直在尝试使用这个问题中的信息: 有没有办法在coldfusion中轻松地将cfquery输出转换为DataTable JSON格式?

所以我有点工作的部分是这样的:

<cfset chartsData = structNew()>
<cfset chartsData["cols"] = arrayNew(1)>

<cfset chartsRow = structNew()>
   <cfset chartsRow["id"] = ""> 
   <cfset chartsRow["label"] = "Date">
   <cfset chartsRow["pattern"] = "">
   <cfset chartsRow["type"] = "date">

   <cfset chartsRow2["id"] = ""> 
   <cfset chartsRow2["label"] = "Temp_C">
   <cfset chartsRow2["pattern"] = "">
   <cfset chartsRow2["type"] = "number">  

   <cfset arrayAppend(chartsData["cols"], chartsRow)>
   <cfset arrayAppend(chartsData["cols"], chartsRow2)>

   <cfset chartsDataJSON = serializeJSON(chartsData)>

  <cfset chartsData2 = structNew()>
  <cfset chartsData2["rows"] = arrayNew(1)>

  <!--- use a query loop to copy query data to this struct --->
   <cfloop query="qAEBdata">
   <cfset chartsRow3 = structNew()>
   <cfset chartsRow3["c"] = []>
   <cfset chartsRow3["v"] = "#Date#">
   <cfset chartsRow3["f"] = "null">
   <cfset chartsRow3["type"] = "date">

   <cfset arrayAppend(chartsData2["rows"], chartsRow3)>
   <cfset chartsDataJSON2 = serializeJSON(chartsData2)>
</cfloop>

   <cfoutput>#chartsDataJSON#,</cfoutput>
   <cfoutput>#chartsDataJSON2#</cfoutput>
Run Code Online (Sandbox Code Playgroud)

这导致了这个输出:

{
"cols":[
{"pattern":"","label":"Date","id":"","type":"date"},
{"pattern":"","label":"Temp_C","id":"","type":"number"}
]
}, 
{    <!---note that google charts does not want this structure --->
"rows":[
{"f":"null","v":"08\/11\/2016","c":[],"type":"date"},
{"f":"null","v":"08\/11\/2016","c":[],"type":"date"},
{"f":"null","v":"08\/11\/2016","c":[],"type":"date"}   …etc
Run Code Online (Sandbox Code Playgroud)

我的问题是:(1)为什么重新排序'id','label','pattern','type'和'c','v','f','type'?我该如何纠正?(2)显然,我没有正确构建格式,尤其是 对于行,我无法弄清楚如何纠正它.任何人都可以帮助推动我朝着正确的方向前进吗?

更新: 我在@WhiteHat和@Leigh的帮助下更新了我的代码,如下:

<cfquery name="qAEBdata" datasource="mydb">
SELECT convert(nvarchar, date, 101) AS Date, temp AS Temp_C
FROM mytable
WHERE threeletter = 'AEB'
and date > '8/11/2016' 
</cfquery> 

<cfset chartsData = structNew()>
   <cfset chartsData["cols"] = arrayNew(1)>
   <cfset chartsData["rows"] = arrayNew(1)>

   <cfset chartsRow = structNew()>
   <cfset chartsRow["id"] = ""> 
   <cfset chartsRow["label"] = "Date">
   <cfset chartsRow["pattern"] = "">
   <cfset chartsRow["type"] = "string">

   <cfset chartsRow2["id"] = ""> 
   <cfset chartsRow2["label"] = "Temp_C">
   <cfset chartsRow2["pattern"] = "">
   <cfset chartsRow2["type"] = "number">

   <cfset arrayAppend(chartsData["cols"], chartsRow)>
   <cfset arrayAppend(chartsData["cols"], chartsRow2)>

<cfloop query="qAEBdata">
  <cfset chartsRow3 = structNew()>
  <cfset chartsRow3["c"] = []>
  <cfset chartsRow3Value0 = structNew()>
  <cfset chartsRow3Value0["v"] = "#Date#">
  <cfset chartsRow3Value1 = structNew()>
  <cfset chartsRow3Value1["v"] = "#Temp_C#">
  <cfset arrayAppend(chartsRow3["c"], chartsRow3Value0)>
  <cfset arrayAppend(chartsRow3["c"], chartsRow3Value1)>
  <cfset arrayAppend(chartsData["rows"], chartsRow3)>
</cfloop>

<cfset chartsDataJSON = serializeJSON(chartsData)>
<cfoutput>#chartsDataJSON#,</cfoutput>
Run Code Online (Sandbox Code Playgroud)

这会将数据放入Google图表的正确JSON结构中除了我的输出在最后有一个尾随逗号(它也在列之前放置行,但这似乎并不重要).这是我的输出:

{"rows":[
{"c":[{"v":"08\/12\/2016"},{"v":26.93}]},
{"c":[{"v":"08\/12\/2016"},{"v":26.94}]},
"cols":[
{"pattern":"","label":"Date","id":"","type":"string"},
{"pattern":"","label":"Temp_C","id":"","type":"number"}]},
Run Code Online (Sandbox Code Playgroud)

我已经尝试在'serializeJSON'之后添加每个这些方法(一次一个),并且它们不会删除逗号.将"-1"增加到更高的数字会导致删除括号并最终从数据中删除文本:

<cfset chartsDataJSON = reReplace(chartsDataJSON, ",$", "", "all")>
<cfset chartsDataJSON = chartsDataJSON.substring(0, len(chartsDataJSON)- 1)>
<cfset chartsDataJSON = left(chartsDataJSON, len(chartsDataJSON)-1)>
Run Code Online (Sandbox Code Playgroud)

例如使用这个:

 <cfset chartsDataJSON = left(chartsDataJSON, len(chartsDataJSON)-2)>
Run Code Online (Sandbox Code Playgroud)

输出结尾的结果如下所示(注意:结果是一个"]"括号在逗号之前丢失,但逗号仍在那里):

"cols":[{"pattern":"","label":"Date","id":"","type":"string"},{"pattern":"","label":"Temp_C","id":"","type":"number"}, 
Run Code Online (Sandbox Code Playgroud)

第二次更新 我发现我的愚蠢逗号在哪里删除它,它是在我输出它的地方之后,这是有道理的,为什么我无法删除它在我尝试的地方:

<cfoutput>#chartsDataJSON#,</cfoutput>
Run Code Online (Sandbox Code Playgroud)

我试图将JSON数据拉入谷歌图表,我得到"无效的JSON字符串":

<!---build chart--->  
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
google.charts.load('current', {
  callback: function () {
    var fusionObject = 'chartDataJSON';

    var chartsDataJSON = new google.visualization.DataTable(fusionObject);

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(chartsDataJSON);
  },
  packages: ['corechart']
});
  </script>
Run Code Online (Sandbox Code Playgroud)

但是如果我直接粘贴JSON,那么图表就可以了.

最终更新 - 正确格式化JSON并绘制图表! 正如Leigh指出的那样,我需要为ColdFusion正确调用变量(对我而言,这是一个非常重要的时刻).更正后的代码:

 <!---build chart--->  
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
google.charts.load('current', {
  callback: function () {
    var fusionObject = ('<cfoutput>#chartsDataJSON#</cfoutput>');

    var chartsDataJSON = new google.visualization.DataTable(fusionObject);

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(chartsDataJSON);
  },
  packages: ['corechart']
});
  </script>

</head>
<body>
  <div id="chart_div"></div>
</body>
Run Code Online (Sandbox Code Playgroud)

Whi*_*Hat 1

"rows"需要添加到同一个对象中"cols"

每个"c"还需要一些改变

使用以下代码片段...

<!--- simulate data query --->
<cfset qAEBdata = queryNew("")>
<cfset queryAddColumn(qAEBdata, "Date", "varchar", ["08/09/2016","08/10/2016","08/11/2016"])>
<cfset queryAddColumn(qAEBdata, "Temp_C", "decimal", [27.04,26.98,27.02])>

<cfset chartsData = structNew()>
<cfset chartsData["cols"] = arrayNew(1)>
<cfset chartsData["rows"] = arrayNew(1)>

<cfset chartsRow = structNew()>
<cfset chartsRow["id"] = "">
<cfset chartsRow["label"] = "Date">
<cfset chartsRow["pattern"] = "">
<cfset chartsRow["type"] = "string">

<cfset chartsRow2["id"] = "">
<cfset chartsRow2["label"] = "Temp_C">
<cfset chartsRow2["pattern"] = "">
<cfset chartsRow2["type"] = "number">

<cfset arrayAppend(chartsData["cols"], chartsRow)>
<cfset arrayAppend(chartsData["cols"], chartsRow2)>

<cfloop query="qAEBdata">
  <cfset chartsRow3 = structNew()>
  <cfset chartsRow3["c"] = []>
  <cfset chartsRow3Value0 = structNew()>
  <cfset chartsRow3Value0["v"] = "#Date#">
  <cfset chartsRow3Value1 = structNew()>
  <cfset chartsRow3Value1["v"] = "#Temp_C#">
  <cfset arrayAppend(chartsRow3["c"], chartsRow3Value0)>
  <cfset arrayAppend(chartsRow3["c"], chartsRow3Value1)>
  <cfset arrayAppend(chartsData["rows"], chartsRow3)>
</cfloop>

<cfset chartsDataJSON = serializeJSON(chartsData)>
<cfoutput>#chartsDataJSON#</cfoutput>
Run Code Online (Sandbox Code Playgroud)

在@Leigh 提供的 try Cold fusion gist runner

我能够创建以下 JSON

{
  "cols": [{
    "pattern": "",
    "label": "Date",
    "id": "",
    "type": "string"
  }, {
    "pattern": "",
    "label": "Temp_C",
    "id": "",
    "type": "number"
  }],
  "rows": [{
    "c": [{
      "v": "08/09/2016"
    }, {
      "v": 27.04
    }]
  }, {
    "c": [{
      "v": "08/10/2016"
    }, {
      "v": 26.98
    }]
  }, {
    "c": [{
      "v": "08/11/2016"
    }, {
      "v": 27.02
    }]
  }]
}
Run Code Online (Sandbox Code Playgroud)

生成以下图表...
(运行以下代码片段)

<!--- simulate data query --->
<cfset qAEBdata = queryNew("")>
<cfset queryAddColumn(qAEBdata, "Date", "varchar", ["08/09/2016","08/10/2016","08/11/2016"])>
<cfset queryAddColumn(qAEBdata, "Temp_C", "decimal", [27.04,26.98,27.02])>

<cfset chartsData = structNew()>
<cfset chartsData["cols"] = arrayNew(1)>
<cfset chartsData["rows"] = arrayNew(1)>

<cfset chartsRow = structNew()>
<cfset chartsRow["id"] = "">
<cfset chartsRow["label"] = "Date">
<cfset chartsRow["pattern"] = "">
<cfset chartsRow["type"] = "string">

<cfset chartsRow2["id"] = "">
<cfset chartsRow2["label"] = "Temp_C">
<cfset chartsRow2["pattern"] = "">
<cfset chartsRow2["type"] = "number">

<cfset arrayAppend(chartsData["cols"], chartsRow)>
<cfset arrayAppend(chartsData["cols"], chartsRow2)>

<cfloop query="qAEBdata">
  <cfset chartsRow3 = structNew()>
  <cfset chartsRow3["c"] = []>
  <cfset chartsRow3Value0 = structNew()>
  <cfset chartsRow3Value0["v"] = "#Date#">
  <cfset chartsRow3Value1 = structNew()>
  <cfset chartsRow3Value1["v"] = "#Temp_C#">
  <cfset arrayAppend(chartsRow3["c"], chartsRow3Value0)>
  <cfset arrayAppend(chartsRow3["c"], chartsRow3Value1)>
  <cfset arrayAppend(chartsData["rows"], chartsRow3)>
</cfloop>

<cfset chartsDataJSON = serializeJSON(chartsData)>
<cfoutput>#chartsDataJSON#</cfoutput>
Run Code Online (Sandbox Code Playgroud)
{
  "cols": [{
    "pattern": "",
    "label": "Date",
    "id": "",
    "type": "string"
  }, {
    "pattern": "",
    "label": "Temp_C",
    "id": "",
    "type": "number"
  }],
  "rows": [{
    "c": [{
      "v": "08/09/2016"
    }, {
      "v": 27.04
    }]
  }, {
    "c": [{
      "v": "08/10/2016"
    }, {
      "v": 26.98
    }]
  }, {
    "c": [{
      "v": "08/11/2016"
    }, {
      "v": 27.02
    }]
  }]
}
Run Code Online (Sandbox Code Playgroud)

但是,必须更改第一列以type: 'string'
不确定如何从 ColdFusion 获取实际日期到 JSON