I am working on an application to create Line Chart using the Highcharts API. This application involves plotting a Date vs. Time Line Chart.
I need to have dynamic hyperlinks, for all or some of the data points.
The data for this chart is being retrieved from a database table and converted into JSON. This JSON is then being parsed by JavaScript and converted into data array that can be consumed by the Highcharts API. There is some data manipulation being done in the JavaScript while converting the data from JSON to data array.
The Highcharts API accepts the input in data array format that comprises of [x, y] combinations.
As I need to have a dynamic hyperlink for all or some of the data points, I have created another array that comprises of the hyperlinks.
I am unable to retrieve the hyperlink URL from the array on the fly as a particular hyperlink is clicked by the user.
I tried using it they was it has been used in this fiddle, http://jsfiddle.net/awasM/1/
A snippet of my code is given below:
series: [{
name: 'Release',
data: dataArray,
URLs: urlArray,
point: {
events: {
click: function() {
var someURL = this.series.userOptions.URLs[this.x];
if (someURL != "undefined")
window.open(someURL);
}
}
}
}]
However, as in my case date (in Unix/Epoch time format) is on x-axis (and time on y-axis), so using the x-axis value does not work.
i hope you could match this code to fix something.
point: {
events: {
click: function() {
var pointObject = this;
var pointindex = pointObject.x;
var pointdata = pointObject.y;
var getIndexOfURL = this.series.userOptions.URLs[pointindex];
var getIndexOfData = this.series.userOptions.data[pointindex];
if (getIndexOfURL){
window.open('http://'+getIndexOfURL);
}
}
}
}
Related
I'm trying to create multiple charts on a single page with Chart.js
I'm dynamically creating several canvas to host those charts.
The information concerning each charts are contained into JSON objects which are contained into 'allDatas'.
Note that the datas from allDatas are correctly formatted and each one have been tested, we can correctly create a Chart without any problem with them. It's the same for the canvas, they're all correct and we can display a chart in any of them. The problem occur when I'm trying to create multiple charts.
var displayDataviz = function(){
var datavizCanvas = document.querySelectorAll('.js-datavizCanvas');
for(var i=0; i<datavizCanvas.length;i++){
var canvas = datavizCanvas[i];
var data = allDatas[i];
data = data.replace(/"/g,'\"');
data = JSON.parse(data);
reCreateDataviz(canvas,data);
}
}
var reCreateDataviz = function(canvas, previousDataviz) {
console.log(canvas);
console.log(previousDataviz);
var myChart = new Chart(canvas, previousDataviz);
return myChart;
}
Here's what I obtain in the console, I logged the two objects so you can see that they're correct, and you can also see that the first chart (totally random) works fine.
I tried to create them manually and the same problem occurs.
Thanks for your help.
This reason why itÂ's not working is because, you are storing all the chart instances to a single variable (myChart), which distorts all other chart instances, except one.
To resolve this ...
add another parameter to the reCreateDataviz function ( for instance -
chartID ), which will contain an unique id for each chart :
var reCreateDataviz = function(canvas, previousDataviz, chartID) {
...
}
then, declare the variable, that stores the chart instance, like this :
window['myChart' + chartID] = new Chart(canvas, previousDataviz);
and finally, when calling reCreateDataviz function inside the for loop, pass i as the third argument, like so :
...
reCreateDataviz(canvas, data, i);
...
I've looked at every thread I could find on how to get a json feed into my google chart, but nothing seems to be working or the threads are slightly different from my problem.
Update: I'm trying to parse my json feed to only show certain columns. For example, my feed has a Actual and Goal column. I want my chart to only show the Actual column. I need the goal column for filtering reasons on the back end, so when the feed updates from the database it knows which records to pull.
After carefully following the json format for Google charts and figuring out a way to add the data, i'm am still unsuccessful in getting the actual data to show up. What's weird is that the graph shows up, it just doesn't have any data in it. I get no errors in my console.I've made sure my json string is valid, it is. I've tried logging my json feed to make sure that the information is being passed correctly and it is. The columns are added, as in the code, but the rows just won't show up.
I believe that in my data.addRow line, i'm not traversing correctly, but can't seem to figure out how to correctly get down to the specific cell.
function drawChart() {
$.ajax({
url: "--",
dataType:"json",
success: function (result) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Quarter');
data.addColumn('number', 'Actual');
for (var i = 0; i < result.rows.length; i++) {
data.addRow([result.rows[i], result.rows[i], result.rows[i]]);
}
Here is my json feed:
{ "cols":[ {"label":"Quarter", "type":"string"},{"label": "Actual", "type":"number"}, {"label":"Goal","type":"number"}], "rows":[ {"c":[{"v":"Q1"}, {"v":22}, {"v":30}]},
{"c":[{"v":"Q2"}, {"v":24}, {"v":30}]},
{"c":[{"v":"Q3"}, {"v":27}, {"v":30}]}
]}
You could build the DataTable with your raw JSON:
var data = new google.visualization.DataTable(json);
and then use a DataView to filter out your "Goal" column:
var view = new google.visualization.DataView(data);
view.setColumns([0, 1]);
Draw your chart using the DataView instead of the DataTable:
chart.draw(view, options);
You can pass your response data from ajax call (as Json formated) to your DataTable
var data = new google.visualization.DataTable(responseData);
I have several AmStockCharts on the page. Those are line graphs. The data gets fetched from MySQL DB in JSON format. If user clicks on a graph dot (a bullet) then a form gets showed up where user can modify the data and save it. In this case I would need to redraw the chart and I can't figure this out.
Here is the piece of code:
//drawing all charts there are
var chart;
$.getJSON('stats.php', function (data) { // get all data from all stats at once
var i=0;
for (chartData in data) {
i++;
chart = new AmCharts.AmStockChart();
var dataSet = new AmChart.DataSet();
dataSet.dataProvider = chartData;
// etc. etc. here are all the single graph parameters
$('#stats').append('<div id="chartdiv' + i + '"></div>');
chart.write("chartdiv" + i);
}
});
I get all charts drawn fine. But here are two problems then. First problem that I can't access them later as the 'chart' variable refers only to the last chart drawn. The second problem is that even if I try to redraw this last chart I get no result.
To redraw the chart I have tried the following:
function chart_redraw(stat) {
$.getJSON('stat.php?redraw=' + stat, function (data) { // get data for one particular stat
var dataSet = new AmCharts.DataSet();
dataSet.dataProvider = data;
...
chart.dataSets = [dataSet];
var stockPanel = new AmChart.StockPanel();
stockPanel.validateData();
chart.panels = [stockPanel];
chart.validateNow();
});
That didn't do anything, i.e. the chart does not get re-drawn.
The only thing I could do is to store the chart div in a hidden input at click event by:
function chartClick (event) {
var chartdiv = event.event.target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.id
$('#chart_n').val(chartdiv);
...
}
and then use it to remove the chart from that div and crate new one at that place but it is much slower then the validateData() would be.
When data is changed, all you need to do is set new data for data set:
dataSet.dataProvider = yourDataArray;
and then call
stockChart.validateData();
However your code should also change panel/dataset, so It's a bit strange for me. Do you get any console errors? In case not, I'd need to see full working source of your case., but I hipe my suggestion will work.
I believe what I am trying to accomplish should be a fairly common task, yet I'm having difficulty getting it to work. I simply wish to create a multi-series plot from a data set containing (for each record) an ISO8601 timestamp along with multiple data points. The data is in JSON format and I'm using dojox.charting.chart "Lines" type.
I'm already aware that the Dojo charts cannot directly handle time-based axis data, let alone ISO8601. So I've already dealt with converting the x-axis to milliseconds-since-T0 server-side.
Here is a distilled example excerpt of my JSON:
[{"Offset_ms":0,"CP":250.58368,"TP":181.88211},
{"Offset_ms":360000,"CP":233.18443,"TP":119.94824},
{"Offset_ms":540000,"CP":227.15465,"TP":117.99422},
{"Offset_ms":720000,"CP":222.87495,"TP":117.55895},
{"Offset_ms":896000,"CP":218.19876,"TP":117.64221},
{"Offset_ms":900000,"CP":219.77487,"TP":117.93475}]
And the distilled JavaScript (assume the above JSON is in the variable 'sequenceData'):
var chart = new dojox.charting.Chart("sequenceDataGraph");
chart.addPlot("default", {
type: "Lines",
tension: "X"
});
chart.addAxis("x", { labelFunc: labelTimeAxis });
chart.addAxis("y", { vertical: true });
var sequenceDataStore = new dojo.store.Observable(new dojo.store.Memory({
data: {
label: "Sequence",
items: sequenceData
}
}));
addSequenceDataSeries(chart, sequenceDataStore, "TP");
addSequenceDataSeries(chart, sequenceDataStore, "CP");
chart.render();
function addSequenceDataSeries(chart, sequenceDataStore, sColumnName) {
chart.addSeries(sColumnName, new dojox.charting.StoreSeries(sequenceDataStore, { query: {} },
sColumnName));
}
What appears to be happening, is that Dojo Chart is not using the x-axis data at all, but instead plotting each point at a fixed interval based on the number of data points. That is, each data point seems to be assigned an ordinal, such as if Offset_ms was merely 1, 2, 3... Since my data points are not always at fixed intervals, the resulting graph is distorted.
How do I instruct Dojo Chart to use the "Offset_ms" field in the JSON data for the x-axis component?
I've scoured the tutorials, the API docs and performed numerous Google & SO searches to no avail. I've even browsed portions of the Dojo source, particularly StoreSeries.js.uncompressed.js, but I'm not finding any answers. Surely this is possible, and hopefully trivial!
Unfortunately, the official dojo documentation is seriously lacking, and I only figured out how to do something similar by browsing the dojo source. Specifically, line 135 of the StoreSeries test, http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_StoreSeries.html
The StoreSeries constructor's third argument accepts an object that maps the X and Y axis to specific fields in your data store.
Change the following line in your code from this:
chart.addSeries(sColumnName, new dojox.charting.StoreSeries(sequenceDataStore, { query: {} },
sColumnName));
to this:
chart.addSeries(sColumnName, new dojox.charting.StoreSeries(sequenceDataStore, { query: {} },
{ x: "Offset_ms", y: sColumnName }));
sColumnName becomes { x: "Offset_ms", y: sColumnName }
I am using AmCharts for displaying some charts and I am trying to dynamically add the data from a series of JSON data sets which are acquired using jquery's getJSON
My question in short is, how do I loop through my various data sets creating dataSets for the charts using something like:
$.getJSON("GET NUMBER OF DATA SETS REQUIRED", function (locdata) {
$.each(locdata, function (i, item) {
$.getJSON("GET DATA FOR THIS DATASET", function (data) {
var dataSet = new AmCharts.DataSet();
dataSet.title = locdata[i].name;
dataSet.fieldMappings = [{
fromField: "takings",
toField: "takings"
}, {
fromField: "qty",
toField: "qty"
}];
dataSet.dataProvider = data; ;
dataSet.categoryField = "date";
)};
)};
)};
To explain what I am doing here:
Firstly, getting some JSON output from my database to determine how many record sets are required
Looping through the result from this to create recordsets
During each loop, the data is acquired by a second jQuery getJSON call to grab data based on the data required for this recordset
Creating an AmCharts Dataset
I can manually do this by explicitly coding to create each dataset individually and then doing
chart.dataSets = [dataSet0, dataSet1, dataSet2, dataSet3, dataSet4];
So I guess what I need to do is turn the whole of the code above into some kind of function which generates an array of datasets as per the line above?
I'm not sure how to do this with javascript though
you can simply push each data set to chart.dataSets array:
chart.dataSets.push(dataSet);