I am trying to create a pie chart in jqplot. I am not sure if i am missing anything here but the chart is not rendering at all.
Below is one of my action method in dashboard_controller in Rails:
def index
#trans = Transaction.joins(:category).group("categories.name").sum(:amount)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #trans }
end
end
here is the json data i got after executing the action method.
{"Bills & Utilities":1019.11,"Uncategorized":196.57,"Home":30.29,"Entertainment":300.0,"Food & Dining":465.45,"Personal Care":63.92,"Auto & Transport":571.44}
Here is my html and javascript
<script type="text/javascript" src="/assets/jqplot/jqplot.js"></script>
<script type="text/javascript" src="/assets/jqplot/plugins/jqplot.pieRenderer.min.js"></script>
<script type="text/javascript" src="/assets/jqplot/plugins/jqplot.ciParser.js"></script>
<script type="text/javascript" src="/assets/jqplot/plugins/jqplot.json2.js"></script>
<link rel="stylesheet" type="text/css" href="/assets/jqplot/jqplot.css" />
<div id="chart10" style="margin-top:20px; margin-left:20px; width:460px; height:300px;"></div>
<script class="code" type="text/javascript">
$(document).ready(function() {
$.getJSON('/dashboard/index.json', function(data){
//var data = [['Heavy Industry', 12],['Retail', 9], ['Light Industry', 14]];
plot = jQuery.jqplot('chart10', data, {
title: ' ',
//dataRenderer: $.jqplot.ciParser,
seriesDefaults: {
shadow: true,
renderer: $.jqplot.PieRenderer,
rendererOptions: {
fill: false,
sliceMargin: 4,
showDataLabels: true
}
},
legend: { show:true }
});
});
}); // document.ready
</script>
Any ideas what could be wrong?
Am I missing something? Your json return variable data looks like this:
{"Bills & Utilities":1019.11,"Uncategorized":196.57,"Home":30.29,"Entertainment":300.0,"Food & Dining":465.45,"Personal Care":63.92,"Auto & Transport":571.44}
While jqPlot wants it like this:
[["Bills & Utilities",1019.11],["Uncategorized",196.57],["Home",30.29],["Entertainment",300.0],["Food & Dining",465.45],["Personal Care",63.92],["Auto & Transport":571.44]]
Edits For Comment
Putting the data in the correct format:
data = {"Bills & Utilities":1019.11,"Uncategorized":196.57,"Home":30.29,"Entertainment":300.0,"Food & Dining":465.45,"Personal Care":63.92,"Auto & Transport":571.44};
jqData = []
$.each(data, function(k,v){jqData.push([k,v]);});
See fiddle here.
Related
Below code has been thankfully provided by machun for toggling between RTL and LTR directions in Kendo UI widgets.
The code consists of:
HTML:
kendo autocomplete form plus a button to activate support for RTL and LTR language.
Script:
k-rtl class container
datasource (json file)
kendo autocomplete widget initializing + template to show image beside data and to open data links in the same tab
k-rtl class
The problem is that links don't open correctly. It shows a 404 Not Found error plus a /undefined at the end of the URL.
Live demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/kendo.all.min.js"></script>
</head>
<body>
<div id="container">
<input type="button" id="toggleRTL" value="Activate RTL Support" class="k-button" />
<input id="autocomplete" type="text" />
</div>
</body>
</html>
<script>
/*------k-rtl class container----------*/
function createAutoComplete(){
if($("#autocomplete").data("kendoAutoComplete") != null){
$("#autocomplete").parent().remove();
$("#container").append("<input id='autocomplete' type='text' />")
}
/*------datasource (json file)---------*/
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "json.txt",
dataType: "json",
data: {
q: "javascript"
}
}
},
schema: {
data: "results"
}
});
/*------kendo autocomplete widget initializing + template to show image beside data and to open data links in the same tab----------*/
$("#autocomplete").kendoAutoComplete({
dataSource: dataSource,
dataTextField: "name",
template: '<span><img src="/kendo-autocomplete-test/img/#: id #.jpg" /></span>' + '<span data-href="#:link#">#:name#</span>',
select: function(e) {
var href = e.item.find("span").data("href");
location.assign(href);
}
});
}
/*------k-rtl class----------*/
createAutoComplete();
$('#toggleRTL').on('click', function(event) {
var form = $('#container');
console.log(form);
if (form.hasClass('k-rtl')) {
console.log("test1");
form.removeClass('k-rtl')
} else {
console.log("test2");
form.addClass('k-rtl');
}
createAutoComplete();
})
</script>
I advice to debug your function first then simply check the variable and make sure it contain the right thing. You overlooked a simple thing that your jquery dom selector isn't quite right resulting var href contain "undefined".
Change
var href = e.item.find("span").data("href");
To
var href = e.item.find("span[data-href]").attr("data-href");
Take a look here
I am facing some issues with the formatting of the y-axis with jqplot. The labels of the y-axis go behind the chart. I tried already a lot of things (adapting the css file but nothing really helped). I hope you can help me.
My html and java script code:
<html>
<head>
<script type="text/javascript" src="./js/jquery.min.js"></script>
<script type="text/javascript" src="./js/jquery.jqplot.min.js"></script>
<script type="text/javascript" src="./js/plugins/jqplot.json2.min.js"></script>
<script type="text/javascript" src="./js/plugins/jqplot.dateAxisRenderer.min.js"></script>
<script type="text/javascript" src="./js/plugins/jqplot.canvasTextRenderer.min.js"></script>
<script type="text/javascript" src="./js/plugins/jqplot.canvasAxisLabelRenderer.min.js"></script>
<script type="text/javascript" src="./js/plugins/jqplot.canvasAxisTickRenderer.min.js"></script>
<script type="text/javascript" src="./js/plugins/jqplot.cursor.min.js"></script>
<link rel="stylesheet" type="text/css" hrf="./js/jquery.jqplot.css"/>
<script type="text/javascript">
$(document).ready(function(){
var sineRenderer = function() {
var data = [[]];
var jsonData = $.ajax({
url: "http://127.0.0.1/beaglemeter/getData.php",
dataType:"json",
async: false
}).responseText;
data = JSON.parse(jsonData);
return [data]; //brackets have to be added in order to fulfill the required data format
};
// we have an empty data array here, but use the "dataRenderer"
// option to tell the plot to get data from our renderer.
var plot1 = $.jqplot('chart_div',[],{
title: 'BeagleMeter',
gridPadding:{left:75,right:25,top:35,bottom:35},
axes:{
xaxis:{
label:'Date/Time',
renderer:$.jqplot.DateAxisRenderer,
tickOptions:{angle: -40, fontFamily: 'Arial', fontSize: '11pt',labelPosition:'middle'},
tickRenderer:$.jqplot.CanvasAxisTickRenderer,
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
},
yaxis:{
label:'Power in W',
tickOptions:{fontFamily: 'Arial', fontSize: '11pt'},
tickRenderer:$.jqplot.CanvasAxisTickRenderer,
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
}
},
cursor:{
show:true,
zoom:true,
showTooltip:false
},
dataRenderer: sineRenderer,
series:[{lineWidth:2, showMarker:false}]
});
});
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<center>
<div id="chart_div" style="height:400px;width:80%"></div>
</center>
</body>
</html>
This is how it looks:
https://drive.google.com/file/d/0B6Nf7EU4lCsNLThESGJXVEZjQjA/edit?usp=sharing
Thanks,
Christoph
I figured it out (actually by a coincidence;-). The code line referring to the css file has a typo: hrf instead of href. Here the correct one:
<link rel="stylesheet" type="text/css" href="./js/jquery.jqplot.css"/>
Additionally I added here the getData.php file so someone else could recycle the code as a full working example:
<?php
header('Content-Type: application/json');
date_default_timezone_set('Europe/Berlin');
$channel = $_GET["channel"];
$period = $_GET["period"];
$begin = $_GET["begin"];
$beginUTS = strtotime($begin);
$endUTS = $beginUTS + 86400;
if ($db = new SQLite3('NameOfDatabaseFile')) {
$result = $db->query("SELECT * FROM 'table' LIMIT 0, 10000");
$rows = array();
while($row = $result->fetchArray(SQLITE3_ASSOC)) {
//$rows[] = array($row['timestamp'], $row['value']);
$rows[] = array(date("Y-m-d H:i", $row['timestamp']), $row['value']);
//date("H:i:s - m.d.y", $timestamp));
//$rows[] = $row;
}
} else {
die($sqliteerror);
}
print json_encode($rows);
?>
I have a column with some notes displaying in the rows. Since the notes are huge, I have cut short the notes in the controller itself and sent that to my aspx page. What I want to achieve is, I want to display the complete notes in the form of a tool tip on mouse over of the grid row ( or if possible exactly on cell ). Is there any way to achieve this? Any help would be highly appreciated. Thanks in Advance.
Posting the answer as it might help anyone.
I got that working after doing this...
columns.Bound(p => p.partialNotes).Title("Description").HeaderHtmlAttributes(new { style = "text-align:center" }).HtmlAttributes(new { style = "text-align:left" }).Width("8%").HtmlAttributes(new { title = "#= completeNotes #" });
I have just added HtmlAttributes(new { title = "#= completeNotes #" })
So now when I place the mouse over the Description column data , I get the complete Notes as a tool tip.
Using a 3rd party widget is also a possibility. I've added qtip tips to column headers like this
KendoUI grid column array item
{
field:"property",
headerTemplate:kendo.template($("#h_Entity_property").html())
},
The header template
<link rel="stylesheet" type="text/css" href="lib/Craga89-qTip2-bfcc9ef/dist/jquery.qtip.min.css"/>
<link rel="stylesheet" type="text/css" href="lib/Craga89-qTip2-bfcc9ef/util/qtip.util.css"/>
<script type="text/javascript" src="lib/Craga89-qTip2-bfcc9ef/dist/jquery.qtip.min.js"></script>
<script type="text/javascript" src="lib/Craga89-qTip2-bfcc9ef/util/Dialogues.js"></script>
<script type="text/javascript" src="lib/Craga89-qTip2-bfcc9ef/util/Qtip2Util.js"></script>
<script type="text/x-kendo-template" id="h_Entity_property">
Property
<img onclick="Qtip.local(this, 'i_Entity_property')" src="img/info.gif"/>
<div id="i_Entity_property" style="display:none;">
Elaborate a bit...
</div>
</script>
Tooltip generator
var Qtip = {
local:function (element, contentId) {
$(element).qtip($.extend({}, qTipSharedOptions, {
content:{
text:$('#' + contentId).html(),
title:{
text:' ',
button:true
}
}
}
));
},
...
};
var qTipSharedOptions = {
position:{
at:'top right', // Position the tooltip above the link
my:'bottom left',
viewport:$(window), // Keep the tooltip on-screen at all times
effect:false // Disable positioning animation
},
style:{
classes:'ui-tooltip-tipsy ui-tooltip-shadow'
},
show:{
ready:true,
event:false,
solo:true // Only show one tooltip at a time
},
hide:false
};
you can do like below:
$("#Kendo-grid-div-id").kendoTooltip({
filter: "td:nth-child(2),td:nth-child(3)", //comma separated multiple columns
position: "bottom", //possible values: bottom,top,left,right,center
content: function(e){
var content = e.target.html();
return content;
}
}).data("kendoTooltip");
Has anyone had any luck with this?
I copied and pasted the exact example code here http://www.jqplot.com/deploy/dist/examples/barTest.html into my text editor. I added all the .js files and .css file required. when I run the page in any browser, I am not seeing the bars or the animation. I have looked at the source code on the above URL as well to see how it works. Could someone tell me why I can the animated bar chart on the URL but not from my desktop? What's different? Here is the exact code I copied:
<html>
<title>Untitled Document</title>
<link rel="stylesheet" href="js/jquery.jqplot.min.css" type="text/css" />
<!--[if lt IE 9]><script language="javascript" type="text/javascript" src="js/excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="js/jquery.jqplot.min.js"></script>
<script language="javascript" type="text/javascript" src="js/excanvas.min.js"></script>
<script language="javascript" type="text/javascript" src="plugins/jqplot.barRenderer.min.js"></script>
<script>
$(document).ready(function(){
$.jqplot.config.enablePlugins = true;
var s1 = [2, 6, 7, 10];
var ticks = ['a', 'b', 'c', 'd'];
plot1 = $.jqplot('chart1', [s1], {
// Only animate if we're not using excanvas (not in IE 7 or IE 8)..
animate: !$.jqplot.use_excanvas,
seriesDefaults:{
renderer:$.jqplot.BarRenderer,
pointLabels: { show: true }
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks
}
},
highlighter: { show: false }
});
$('#chart1').bind('jqplotDataClick',
function (ev, seriesIndex, pointIndex, data) {
$('#info1').html('series: '+seriesIndex+', point: '+pointIndex+', data: '+data);
}
);
});
</script>
</head>
<body>
<div id="chart1" style="margin-top: 20px; margin-left: 20px;width: 300px; height: 300px; position: relative;"></div>
<div><span>Moused Over: </span><span id="info1">Nothing</span></div>
</body>
</html>
here is what I see in the browser after running that code:
Thanks
For anyone interested, I've found the answer. The example code taken from the barchart.html page in my post doesn't appear to need the conditional syntax (below) in order to animate the bars:
$.jqplot.config.enablePlugins = true;
// Only animate if we're not using excanvas (not in IE 7 or IE 8)..
animate: !$.jqplot.use_excanvas,
From the animate example on the examples page , the following code will do the trick:
animate: true,
// Will animate plot on calls to plot1.replot({resetAxes:true})
animateReplot: true,
I read the entire documentation and was doing a lot of playing around with the code. Eventually, I got to the full "examples" page (not the few listed on the tests and examples page which I initially viewed since it was listed first in the documentation). I really wanted to understand the plugin code since the developer took so much time to really provide a ton of info, comments and updates to his code base.
I am new to jQuery & jgrid. I am trying to use columnchooser to both to let user remove columns and change column order. Removing and adding columns are working fine. But changing the column order is not working. Below is what I have in the code.
<head>
<link rel="stylesheet" type="text/css" media="screen" href="/xxxx/resources/css/jquery/ui-lightness/jquery-ui-1.8.6.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/xxxx/resources/css/jqgrid/ui.jqgrid.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/xxxx/resources/css/edi/standard.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/xxxx/resources/css/jquery/ui-multiselect/ui.multiselect.css" />
<script type="text/javascript" src="/xxxx/resources/js/jquery/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="/xxxx/resources/js/jquery/jquery-ui-1.8.6.custom.min.js"></script>
<!-- <script type="text/javascript" src="/xxxx/resources/js/jquery/jquery-ui-1.8.11.custom.js"></script>-->
<script type="text/javascript" src="/xxxx/resources/js/jqgrid/grid.locale-en.js"></script>
<script type="text/javascript" src="/xxxx/resources/js/jquery/ui.multiselect.js"></script>
<script type="text/javascript" src="/xxxx/resources/js/jqgrid/jquery.jqGrid.min.js"></script>
<script type="text/javascript">
var jq = jQuery.noConflict();
jq.jgrid.no_legacy_api = false;
</script>
<script type="text/javascript" src="/xxxx/resources/js/jqgrid/jquery.jqGrid.min.js"></script> <!-- 3.8.2 version-->
<!--<script type="text/javascript" src="/xxxx/resources/js/jqgrid/jquery.searchFilter.js"></script>-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>XXXX</title>
</head>
ui.multiselect.js file contains the suggested fix already.
$.widget("ui.multiselect", {
options: {
sortable: true,
searchable: true,
doubleClickable: true,
animated: 'fast',
show: 'slideDown',
hide: 'slideUp',
dividerLocation: 0.6,
nodeComparator: function(node1,node2) {
var text1 = node1.text(),
text2 = node2.text();
return text1 == text2 ? 0 : (text1 < text2 ? -1 : 1);
}
}},
destroy: function() {
this.element.show();
this.container.remove();
// Modified to work with jquery.ui.1.8
if ($.Widget === undefined)
$.widget.prototype.destroy.apply(this, arguments);
else {
$.Widget.prototype.destroy.apply(this, arguments);
return this;
}}
And I am using the columnchooser as below.
jq("#grid").jqGrid('navButtonAdd','#pager',
{ caption: "Columns",
title: "Reorder Columns",
onClickButton : function (perm){
jq("#grid").jqGrid('columnChooser');
}
});
Below is what I have tried so far.
When I add {"msel_opts": $.ui.multiselect.defaults} as an option, I am getting ui undefined JS error.
When I tried to include grid.jqueryui.js, got object or method not supported.
I am stuck # this. Would somebody help please?
It is difficult to find the error in your code, because you posted only one code fragment. Probably you try to add the button in the navigator toolbar with respect of 'navButtonAdd' before you created the navigator toolbar with respect of 'navGrid'.
In any way one small working example here could help you to find your error.
For others who are in the same requirement, you may consider my columnchooser implementation.
My Dialog Form Declaration. (Dialog box which will be shown when columnchooser button is clicked.
All required fields will not be allowed to remove.
Creating the ColumnChooser Button for my Grid.
jq("#grid").jqGrid('navButtonAdd','#pager',{
caption: "Columns",
title: "Customize Columns",
onClickButton : function (){
/*jq("#grid").jqGrid('columnChooser',{
height:columnChooserHt
});*/
createDialogDiv();
jq( "#dialog-form" ).dialog('open');
}
});
Adding Save(OK) and Cancel Buttons to my Div.
jq(function(){
jq( "#dialog-form" ).dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"OK": function() {
changeColView();
jq( "#dialog-form" ).dialog('close');
},
Cancel: function() {
jq( "#dialog-form" ).dialog('close');
}
},
close: function() {
}
});
});
Function which inserts the column names with the select boxes which needed to be displayed on the ColumnChooser Dialog Box.
function createDialogDiv(){
var colModelDiv = jq("#grid").jqGrid('getGridParam','colModel');
var colNamesDiv = jq("#grid").jqGrid('getGridParam','colNames');
//alert(JSON.stringify(colModelDiv));
//alert(JSON.stringify(colNameDiv));
var container = document.getElementById('dialog-form');
//alert(colNamesDiv.length);
var chckBox="";
for(i=0;i<colNamesDiv.length;i++){
if(colModelDiv[i].hidden && colModelDiv[i].hidden == true ){
chckBox+="<input type='checkbox' id='"+colNamesDiv[i]+"' name='"+colNamesDiv[i]+"' value='"+colModelDiv[i].name+"'>"+colNamesDiv[i]+"</input><br/>";
}else{
if(colModelDiv[i].editrules && colModelDiv[i].editrules.required){
chckBox+="<input type='checkbox' id='"+colNamesDiv[i]+"' name='"+colNamesDiv[i]+"' value='"+colModelDiv[i].name+"' disabled>"+colNamesDiv[i]+"</input><br/>";
}
else
chckBox+="<input type='checkbox' id='"+colNamesDiv[i]+"' name='"+colNamesDiv[i]+"' value='"+colModelDiv[i].name+"' checked>"+colNamesDiv[i]+"</input><br/>";
}
}
container.innerHTML=chckBox;
}
Finally the actual method which changes the Columns chosen from Columnchooser.
function changeColView(){
var colModelDiv = jq("#grid").jqGrid('getGridParam','colModel');
var colNamesDiv = jq("#grid").jqGrid('getGridParam','colNames');
for(i=0;i<colNamesDiv.length;i++){
var chckBox=document.getElementById(colNamesDiv[i]);
if(chckBox && chckBox.value && (!(chckBox.checked || chckBox.disabled))){
jq("#grid").jqGrid('hideCol',chckBox.value);
}
if(chckBox && chckBox.checked){
jq("#grid").jqGrid('showCol',chckBox.value);
}
}
jq("#grid").trigger('reloadGrid');
}
Plz let me know your thoughts on this one.