Javascript code -
$.jqplot.config.enablePlugins = true;
var defaultHighlighter = {tooltipAxes: 'y',showTooltip: true,tooltipLocation: 'n',tooltipOffset: 10,yvalues:1,formatString:'%.0f user'};
var globalTicks = [[-1,' '],[0,'12 am'],[1,'1 am'],[2,'2 am'],[3,'3 am'],[4,'4 am'],[5,'5 am'],[6,'6 am'],[7,'7 am'],[8,'8 am'],[9,'9 am'],[10,'10 am'],[11,'11 am'],[12,'12 pm'],[13,'1 pm'],[14,'2 pm'],[15,'3 pm'],[16,'4 pm'],[17,'5 pm'],[18,'6 pm'],[19,'7 pm'],[20,'8 pm'],[21,'9 pm'],[22,'10 pm'],[23,'11 pm'],[24,[' ']]];
var fullGraphOptions = {seriesDefaults: {pointLabels:{show:false},showMarker:true,markerOptions:{style: 'filledCircle'}},axes:{xaxis:{rendererOptions:{tickRenderer:$.jqplot.CanvasAxisTickRenderer},tickOptions:{angle:-45},ticks:globalTicks},yaxis:{min:0,tickOptions:{formatString:'%.0f'}}},highlighter:defaultHighlighter};
fullanalysis1 = $.jqplot('hourlyGraph-1', [[[63,63],[68,68],[87,87],[108,108],[135,135],[138,138],[147,147],[167,167],[130,130],[145,145],[144,144],[127,127],[134,134],[132,132],[147,147],[158,158],[157,157],[166,166],[170,170],[124,124],[107,107],[77,77],[62,62],[88,88]]], fullGraphOptions);
fullanalysis2 = $.jqplot('hourlyGraph-2', [[[63,63],[68,68],[87,87],[108,108],[135,135],[138,138],[147,147],[167,167],[130,130],[145,145],[144,144],[127,127],[134,134],[132,132],[147,147],[158,158],[157,157],[166,166],[170,170],[124,124],[107,107],[77,77],[62,62],[88,88]]], fullGraphOptions);
fullanalysis3 = $.jqplot('hourlyGraph-3', [[[63,63],[68,68],[87,87],[108,108],[135,135],[138,138],[147,147],[167,167],[130,130],[145,145],[144,144],[127,127],[134,134],[132,132],[147,147],[158,158],[157,157],[166,166],[170,170],[124,124],[107,107],[77,77],[62,62],[88,88]]], fullGraphOptions);
fullanalysis4 = $.jqplot('hourlyGraph-4', [[[63,63],[68,68],[87,87],[108,108],[135,135],[138,138],[147,147],[167,167],[130,130],[145,145],[144,144],[127,127],[134,134],[132,132],[147,147],[158,158],[157,157],[166,166],[170,170],[124,124],[107,107],[77,77],[62,62],[88,88]]], fullGraphOptions);
All the four graphs have the same result -
No plotting is done at all.
The data I have in the code is just a sample.
What could be the problem? The screenshot's of Firefox running on
Fedora 14.
Thank you,all.
Edit: I don't get any error in the Firebug console.
You seems to have got your data formatted the wrong way. You are trying to graph a single series with an array. Instead of giving data as [63,63],[68,68],[87,87 ...], It should be [63,68,87 ...]. Here is the right way to do get the chart running:
var data = [63, 68, 87, 108,135,138,147,167,130];
var globalTicks = ['12 am','1 am','2 am','3 am','4 am','5 am','6 am','7 am','8 am'];
var fullGraphOptions = {
seriesDefaults: {
pointLabels:{
show:true
},
showMarker:true,
markerOptions:{
style: 'filledCircle'
}
},
axes:{
xaxis:{
renderer: $.jqplot.CategoryAxisRenderer,
tickRenderer:$.jqplot.CanvasAxisTickRenderer,
tickOptions:{
angle:-45
},
ticks:globalTicks
},
yaxis:{
min:0,
tickOptions:{
formatString:'%.0f'
}
}
},
highlighter:defaultHighlighter
};
fullanalysis1 = $.jqplot('chartdiv', [data], fullGraphOptions);
Related
I want to render multiple charts with same class name.The div with same class name contains canvas object.Most of the options are same but a few are different.I want to send them via data attributes.Everything is okay but when i am going to select canvas element on dom-object, it comes :
Uncaught TypeError: Object.defineProperty called on non-object
I dont know why it's happening.
Below is the html code
<td
class ="crypt-marketcap-canvas"
data-charts ="[65,59,81,81,56,55,40,80,90]"
data-bg = "d3f0df"
data-border = "8cd8aa">
<canvas />
</td>
and js codes are
var charts = document.getElementsByClassName("crypt-marketcap-canvas");
for( let chart of charts ){
let data = chart.dataset.charts;
// console.log(chart.dataset.charts);
let bg = chart.dataset.bg;
let border = chart.dataset.border;
let canvas = chart.querySelector('canvas');
// console.log(canvas);
let ctx = canvas.getContext('2d');
console.log(ctx);
let lineChartData = {
labels : ["1","2","3","4","5","6","7","8","9"],
datasets : [
{
backgroundColor : '#' + bg,
borderColor : '#' + border,
data : data,
bezierCurve : true
}
]
}
new Chart(ctx, { //Error is showing on this line
type:"line",
data:lineChartData,
options:options
});
}
Your issue here is that data is a string "[65,59,81,81,56,55,40,80,90]" which Chart can't understand.
If you do a JSON.parse it would work:
let data = JSON.parse(chart.dataset.charts);
That converts the data back to an array which, I guess, is your intention.
var charts = document.getElementsByClassName("crypt-marketcap-canvas");
for( let chart of charts ){
let data = JSON.parse(chart.dataset.charts);
// console.log(chart.dataset.charts);
let bg = chart.dataset.bg;
let border = chart.dataset.border;
let canvas = chart.querySelector('canvas');
let ctx = canvas.getContext('2d');
let lineChartData = {
labels : ["1","2","3","4","5","6","7","8","9"],
datasets : [
{
backgroundColor : '#' + bg,
borderColor : '#' + border,
data : data,
bezierCurve : true
}
]
}
new Chart(ctx, { //Error is showing on this line
type:"line",
data:lineChartData,
options: {}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script>
<table>
<tbody>
<tr>
<td
class ="crypt-marketcap-canvas"
data-charts ="[65,59,81,81,56,55,40,80,90]"
data-bg = "d3f0df"
data-border = "8cd8aa">
<canvas />
</td>
</tr>
</tbody>
</table>
Extra
If you have any control on how data-charts is being written to the DOM I'd say avoid [ and just would do something like this:
<td
class ="crypt-marketcap-canvas"
data-charts ="65,59,81,81,56,55,40,80,90"
data-bg = "d3f0df"
data-border = "8cd8aa">
<canvas />
</td>
Then on your script: let data = chart.dataset.charts.split(','); leading to the same result.
Reason I recommend this is because JSON.parse can throw exceptions if something odd happens so you'd have to wrap within a try/catch block.
I want to populate a dynamic column chart such that the rows as well the columns are dynamic.
Here is a sample json array that I want to transform:
{"location":"Chain","item_category":"A","delay":"681"},
{"location":"Chennai ","item_category":"A","delay":"286"},{"location":"Bawal","item_category":"A","delay":"339"},{"location":"Haridwar","item_category":"A","delay":"1256"},{"location":"Ludhiana","item_category":"A","delay":"1048"},{"location":"Bawal","item_category":"B","delay":"1"}
There are 3 parameters namely location, item_category and delay where:
Location represents columns. (Varies dynamically)
Delay range should be on Y-axis. (Varies dynamically)
On x-axis they are mapped with items.
So far, I'm able to fetch all the required data but unable to create a graph out of it. I have referred to various libraries such as Google-visualization, Pchart, JPGraph and many more.
Each time I freeze on populating the graph dynamically.
Here is a sample code for populating Google Column Chart:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Item Category', 'Location 1', 'Location 2', 'Location 3,...'],
['item1', 1000, 400, 200,...delay value of location 'n'],
['item2', 1170, 460, 250,...],
['item3', 660, 1120, 300]...],
['item4', 1030, 540, 350]
.
.
]);
//I want to populate this data variable using PHP
var chart = new google.charts.Bar(document.getElementById('my_Chartid'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
These are the links I have referred. I want to populate this data variable in javascript dynamically.
Google column chart dashboard
https://developers.google.com/chart/interactive/docs/gallery/columnchart
first, need to convert json data to normal array
then use a data view to create a column for each category
then aggregate the data and draw the chart
google.charts.load('current', {
callback: function () {
var jsonData = [
{"location":"Chain","item_category":"A","delay":"681"},
{"location":"Chennai ","item_category":"A","delay":"286"},
{"location":"Bawal","item_category":"A","delay":"339"},
{"location":"Haridwar","item_category":"A","delay":"1256"},
{"location":"Ludhiana","item_category":"A","delay":"1048"},
{"location":"Bawal","item_category":"B","delay":"100"}
];
// load chart data
var chartData = [];
jsonData.forEach(function (row, rowIndex) {
// column headings
var columns = Object.keys(row);
if (rowIndex === 0) {
chartData.push(columns);
}
// row values
var chartRow = [];
columns.forEach(function (column, colIndex) {
var chartCell = row[column];
if (colIndex > 1) {
chartCell = parseFloat(chartCell);
}
chartRow.push(chartCell);
});
chartData.push(chartRow);
});
var data = google.visualization.arrayToDataTable(chartData);
// create data view
var view = new google.visualization.DataView(data);
// init column arrays
var aggColumns = [];
var viewColumns = [0];
// build view & agg column for each category
data.getDistinctValues(1).forEach(function (category, index) {
// add view column
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === category) {
return dt.getValue(row, 2);
}
return null;
},
label: category,
type: 'number'
});
// add agg column
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index + 1,
label: category,
type: 'number'
});
});
// set view columns
view.setColumns(viewColumns);
// agg view
var group = google.visualization.data.group(
view,
[0],
aggColumns
);
var chart = new google.charts.Bar(document.getElementById('chart_div'));
// use group data to draw chart
chart.draw(group);
},
packages:['bar']
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I use D3.js and upon loading data from csv file the page isn't rendering when I remove the alert() statements. I;'m not a js specialist and I know it's something to do with asynchronous modes of operation but I don't know what to change.
when alert("AAAAAAAA"); is removed it works I appreciate this is a bespoke
issue so the other posts on the subject were not easily understood.
Many Thanks
Andy
</style>
<div id='dashboard2' align="center"></div>
<div id='dashboard' align="center"></div>
<script src="/xxxxxxxx/templates/uber/js/d3.min.js"></script>
<script type="text/javascript">
var climate_csv = function()
{
d3.csv("/xxxxxxxx/templates/uber/js/theclimate.csv", function(climate_statistics)
{
//prices is an array of json objects containing the data in from the csv
console.log("climate_statistics:", climate_statistics)
climate_data = climate_statistics.map(function(d)
{
//each d is one line of the csv file represented as a json object
console.log("d", d)
month = d.month;
console.log("month:", d.month, month)
low = +d.low;
console.log("low:", d.low, low)
high = +d.high;
console.log("high:", d.high, high)
rainfall = +d.rainfall;
console.log("rainfall:", d.rainfall, rainfall)
sunshine = +d.sunshine;
console.log("sunshine:", d.sunshine, sunshine)
nighttime = +d.nighttime;
console.log("nighttime:", d.nighttime, nighttime);
return {"Month": month, "cStats": {"low": low , "high": high} , "rainfall": rainfall , "sun":{"Sunshine": sunshine , "Nighttime": nighttime}}
})
})
}
</script>
<script type="text/javascript">
var climateStats2=[
{TempRange:'Low',cStats:{low:0}}
];
var climateStats3=[
{TempRange3:'High',cStats:{high:0}}
];
var climateStats4=[
{TempRange4:'Rainfall',cStats:{rainfall:0}}
];
var climateStats5=[
{TempRange4:'Rainfall',cStats5:{lower5:0, upper5:0}}
];
climate_csv();
alert("AAAAAAAA");
dashboard('#dashboard',climate_data,climateStats2,climateStats3,climateStats4,climateStats5);
Seems like your data is not fully loaded, when you call dashboard. It works with the alert because while the alert is open, your script is paused. Another thing is, that you are using global variables here. Let's avoid this using callbacks.
D3's csv function uses a callback and calls it, when the data is ready.
d3.csv("/xxxxxxxx/templates/uber/js/theclimate.csv", function(climate_statistics) {
/* ... */
});
You can now either call the dashboard function inside the callback, or add a callback to your function. Let's do the latter here:
var climate_csv = function( callback ) {
d3.csv(
"/xxxxxxxx/templates/uber/js/theclimate.csv",
function( climate_statistics ) {
var climate_data = climate_statistics.map(function( d ) {
month = d.month;
low = +d.low;
high = +d.high;
rainfall = +d.rainfall;
sunshine = +d.sunshine;
nighttime = +d.nighttime;
return {
"Month": month,
"cStats": {
"low": low,
"high": high
},
"rainfall": rainfall,
"sun": {
"Sunshine": sunshine,
"Nighttime": nighttime
}
};
});
// we are done with mapping our data
// let's call the callback with the data
callback(climate_data);
});
};
/* ... */
climate_csv(function( climate_data ) {
dashboard('#dashboard', climate_data, climateStats2, climateStats3,
climateStats4, climateStats5);
});
Put the function that is not working when you remove the alert inside the success callback, that will make the trick.
.csv works async, so when you put the alert, the request is completed on the background, when you remove it no "wait time" is added (as it should be) and that's why it's not working.
Not using d3.js, but this doc could help:
https://github.com/mbostock/d3/wiki/CSV
d3.csv("path/to/file.csv")
.row(function(d) { return {key: d.key, value: +d.value}; })
.get(function(error, rows) { console.log(rows); });
Hope it helps.
I'm trying to draw a chart in an application where I show data month on month, and would like to add labels to the x-axis to signify the years, but when I try to add a label it automatically adds the year and month cluttering up the look of the application.
var e=new google.visualization.arrayToDataTable([
["Year",county_1,county_2,"National"],
["Jan-10",med_jan_10_1,med_jan_10_2,med_jan_10_3],
["Feb-10",med_feb_10_1,med_feb_10_2,med_feb_10_3],
["Mar-10",med_mar_10_1,med_mar_10_2,med_mar_10_3],
["Apr-10",med_apr_10_1,med_apr_10_2,med_apr_10_3],
["May-10",med_may_10_1,med_may_10_2,med_may_10_3],
["Jun-10",med_jun_10_1,med_jun_10_2,med_jun_10_3],
["Jul-10",med_jul_10_1,med_jul_10_2,med_jul_10_3],
["Aug-10",med_aug_10_1,med_aug_10_2,med_aug_10_3],
["Sept-10",med_sep_10_1,med_sep_10_2,med_sep_10_3],
["Oct-10",med_oct_10_1,med_oct_10_2,med_oct_10_3],
["Nov-10",med_nov_10_1,med_nov_10_2,med_nov_10_3],
["Dec-10",med_dec_10_1,med_dec_10_2,med_dec_10_3],
["Jan-11",med_jan_11_1,med_jan_11_2,med_jan_11_3],
["Feb-11",med_feb_11_1,med_feb_11_2,med_feb_11_3],
["Mar-11",med_mar_11_1,med_mar_11_2,med_mar_11_3],
["Apr-11",med_apr_11_1,med_apr_11_2,med_apr_11_3],
["May-11",med_may_11_1,med_may_11_2,med_may_11_3],
["Jun-11",med_jun_11_1,med_jun_11_2,med_jun_11_3],
["Jul-11",med_jul_11_1,med_jul_11_2,med_jul_11_3],
["Aug-11",med_aug_11_1,med_aug_11_2,med_aug_11_3],
["Sept-11",med_sep_11_1,med_sep_11_2,med_sep_11_3],
["Oct-11",med_oct_11_1,med_oct_11_2,med_oct_11_3],
["Nov-11",med_nov_11_1,med_nov_11_2,med_nov_11_3],
["Dec-11",med_dec_11_1,med_dec_11_2,med_dec_11_3],
["Jan-12",med_jan_12_1,med_jan_12_2,med_jan_12_3],
["Feb-12",med_feb_12_1,med_feb_12_2,med_feb_12_3],
["Mar-12",med_mar_12_1,med_mar_12_2,med_mar_12_3],
["Apr-12",med_apr_12_1,med_apr_12_2,med_apr_12_3],
["May-12",med_may_12_1,med_may_12_2,med_may_12_3],
["Jun-12",med_jun_12_1,med_jun_12_2,med_jun_12_3],
["Jul-12",med_jul_12_1,med_jul_12_2,med_jul_12_3],
["Aug-12",med_aug_12_1,med_aug_12_2,med_aug_12_3],
["Sept-12",med_sep_12_1,med_sep_12_2,med_sep_12_3],
["Oct-12",med_oct_12_1,med_oct_12_2,med_oct_12_3],
["Nov-12",med_nov_12_1,med_nov_12_2,med_nov_12_3],
["Dec-12",med_dec_12_1,med_dec_12_2,med_dec_12_3],
["Jan-13",med_jan_13_1,med_jan_13_2,med_jan_13_3],
["Feb-13",med_feb_13_1,med_feb_13_2,med_feb_13_3],
["Mar-13",med_mar_13_1,med_mar_13_2,med_mar_13_3],
["Apr-13",med_apr_13_1,med_apr_13_2,med_apr_13_3],
["May-13",med_may_13_1,med_may_13_2,med_may_13_3],
["Jun-13",med_jun_13_1,med_jun_13_2,med_jun_13_3],
["Jul-13",med_jul_13_1,med_jul_13_2,med_jul_13_3],
["Aug-13",med_aug_13_1,med_aug_13_2,med_aug_13_3],
["Sept-13",med_sep_13_1,med_sep_13_2,med_sep_13_3],
["Oct-13",med_oct_13_1,med_oct_13_2,med_oct_13_3],
["Nov-13",med_nov_13_1,med_nov_13_2,med_nov_13_3],
["Dec-13",med_dec_13_1,med_dec_13_2,med_dec_13_3],
["Jan-14",med_jan_14_1,med_jan_14_2,med_jan_14_3],
["Feb-14",med_feb_14_1,med_feb_14_2,med_feb_14_3],
["Mar-14",med_mar_14_1,med_mar_14_2,med_mar_14_3],
["Apr-14",med_apr_14_1,med_apr_14_2,med_apr_14_3],
["May-14",med_may_14_1,med_may_14_2,med_may_14_3],
["Jun-14",med_jun_14_1,med_jun_14_2,med_jun_14_3],
["Jul-14",med_jul_14_1,med_jul_14_2,med_jul_14_3],
["Aug-14",med_aug_14_1,med_aug_14_2,med_aug_14_3],
["Sept-14",med_sep_14_1,med_sep_14_2,med_sep_14_3],
]);
var b={
title:"House Price Index by County:",
curveType:"function",
is3D:true,
legend:"top",
width:600,
height:250,
hAxis: {textPosition: 'none' }};
var d=new google.visualization.LineChart(document.getElementById("chart_div"));
d.draw(e,b)
}
Can anyone suggest a way to just have the labels of the years (2010:2014) on the graphs?
You will likely need to loop through the data to change it as you see fit:
var exampleData = ["Jan-10",med_jan_10_1,med_jan_10_2,med_jan_10_3];
for (var i = 0; i < exampleData.length; i++) {
var date = exampleData[i][0];
var year = '20' + date.split('-')[1];
exampleData[i][0] = year;
}
!SOLVED!
I want to automatically create charts with users and their time spent on pages of a website.
I have a file - "log.xml" where I keep information with users (customers), visited pages, dates and their time spent; and after I "get" this Xml file with Ajax, I want to parse it and create with values "extracted" charts with JqPlot.
My problem is that I can't loop through more than just one customer and it don't build chart for the single customer.
If I remove the code block with initialization of variable plot I can loop through all my customers from Xml.
Please, if someone can tell me what is wrong, and how to create charts for all customers...
Here is the code of the file "log.xml":
<?xml version="1.0"?>
<log>
<customer id="14" name="Florin Virdol">
<page name="/mobilestore/index.php">
<date_ts on="2011-12-02" timeSpent="205"/>
</page>
<page name="/mobilestore/products_all.php">
<date_ts on="2011-12-02" timeSpent="15"/>
</page>
</customer>
<customer id="0" name="guest">
<page name="/mobilestore/services.php">
<date_ts on="2011-12-02" timeSpent="50"/>
</page>
</customer>
</log>
Here is the javascript code of the "operations":
$(document).ready(function()
{
//read from xml
$.ajax({
type: "GET",
url: "log.xml",
dataType: "xml",
success: parseXml
});
});//ready
//parse xml
function parseXml(xml) {
var i = 0;
$(xml).find("customer").each(function() {
$('<div class = "jqplot graph" id = "chart' + i + '"></div>').appendTo('#content');
var customerName = $(this).attr("name");
var line_inside = []; // declare as array
$(this).find("page").each(function() {
var pageName = $(this).attr("name");
$(this).find("date_ts").each(function() {
var timeSpent_ = $(this).attr("timeSpent");//if mai multe timespent, sa faca totalul, else singuru; timespent
line_inside.push([pageName,timeSpent_]); //do not string cat, push onto array
});
});
var line = '[' + line_inside + ']';
//--------jqplot----!!! if i remove this block, will loop through customers------------
var plot = $.jqplot('chart' + i, [line_inside],
{
title: customerName,
series:[{renderer:$.jqplot.BarRenderer}],
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
label: 'Web Page',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: { labelPosition:'middle', angle: -30 }
},
yaxis: {
autoscale:true,
label: 'Total Time Spent',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: { labelPosition:'middle', angle: -30 }
}
}
});
//-------jqplot----!!! if i remove this block, will loop through customers------------
i++;
});//find customer
}//parse xml
SOLUTION: made modifications that Mark suggested, and it works.
(now, above code works!)
You are passing strings that look like arrays and not actual arrays to jqplot.
Try:
var line_inside = []; // declare as array
$(this).find("page").each(function() {
var pageName = $(this).attr("name");
$(this).find("date_ts").each(function() {
var timeSpent_ = $(this).attr("timeSpent");//if mai multe timespent, sa faca totalul, else singuru; timespent
line_inside.push([pageName,timeSpent_]); //do not string cat, push onto array
});
});
alert(line_inside); // this is an array of arrays
var plot = $.jqplot('chart' + i, [line_inside],
Since you want a different plot for each customer, you need to make plot a local var to your inline function: "var plot" not just "plot" -- same goes for "line". You are assigning a global scope variable and overwriting it each time, currently.