Adding data labels (annotations?) to Google Charts (Visualizations API) drawn from a query - google-sheets

I'm creating a line chart by querying data entered into a Google Sheet, and I need to add data labels, i.e. the little numbers next to the points on the chart. I found plenty of documentation on how to do this with charts drawn from a manually entered data-table, but not from a query to a Google Sheet. Please help.
google.charts.load('current', {'packages':['corechart', 'line']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var query = new google.visualization.Query(
'URL'
);
query.setQuery('SELECT A, B OFFSET 0'); //select specific cells from the table
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var options = {
title: '',
height : 250,
width : '100%',
}
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}

correct, you want to add annotations.
this can be done using an annotation column role.
the annotation column role, should directly follow the series column it represents in the data table.
in this case, since you are getting the data from a query,
we can use a DataView to add the annotation using a calculated column.
first, we create the data view.
var view = new google.visualization.DataView(data);
then we use the setColumns method,
to add the column indexes from the query,
and our calculated column for the annotation.
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}]);
finally, we need to use the view to draw the chart.
chart.draw(view, options);
see following snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(drawChart);
function drawChart() {
var query = new google.visualization.Query(
'URL'
);
query.setQuery('SELECT A, B OFFSET 0'); //select specific cells from the table
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var options = {
title: '',
height : 250,
width : '100%',
};
// create data view with calculated annotation column
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(view, options); // <-- use view to draw the chart
}
Note: when using google.visualization.LineChart, you only need the 'corechart' package.
the 'line' package is for their material line chart --> google.charts.Line

Related

Very Small Scale on Highcharts

I have this script on my .html page to display a graph. My values are from -1 to 1 and I have values like 0.0045. It is possible to define this scale on Y axis?
<script>
function js_fun() {
$.getJSON('/myopteboard/data/selectedEngines/'
+ getAllEnginesIdsSelected(), function(datas) {
$.each(datas, function(index, indexData) {
data = indexData.evidencesValues;
console.log(data);
drawChart(data, indexData.name);
});
});
}
var data = [];
var options1 = {
chart : {
renderTo : 'thermal_graph'
},
yAxis : {
labels : {
format : '{value:.002f}'
}
},
series : []
};
var drawChart = function(data, name) {
console.log(name);
// 'series' is an array of objects with keys: 'name' (string) and 'data' (array)
var newSeriesData = {
name : name,
data : data
};
// Add the new data to the series array
options1.series.push(newSeriesData);
// If you want to remove old series data, you can do that here too
// Render the chart
var chart = new Highcharts.Chart(options1);
};
</script>
Next time please provide fiddle for your code.
Try tickInterval option for axis http://jsfiddle.net/Paulson/zwwsuc0L/

openlayers 3 featureKey exists in featureChangeKeys

I have an ol.interaction.Select acting on an ol.source.Vector which is within an ol.layer.Vector. I can select and unselect individual countries fine. I am using a dragbox to select multiple countries. If I select anywhere outside of the multiply selected countries, the currently selected get unselected. Excellent!
However, the problem is that if I select a currently selected country within the multiple, I get the AssertionError: Assertion failed: featureKey exists in featureChangeKeys
Here's my Vector layer:
_countrySelectSource = new ol.source.Vector({
url: 'vendor/openlayers/geojson/countries.json',
format: new ol.format.GeoJSON()
});
var countryLayer = new ol.layer.Vector({
title: 'Country Select',
visible: true,
type: 'interactive-layers',
source: _countrySelectSource
});
I add countryLayer to my map, _map.
I then create a _CountrySelect object that allows me to setActive(true|false) on the interactions related to my country selection.
_CountrySelect = {
init : function(){
this.select = new ol.interaction.Select();
_map.addInteraction(this.select);
this.dragbox = new ol.interaction.DragBox({
condition: ol.events.condition.platformModifierKeyOnly
});
_map.addInteraction(this.dragbox);
this.setEvents();
},
setEvents: function(){
var selectedFeatures = this.select.getFeatures();
var infoBox = document.getElementById('info');
var selfDragbox = this.dragbox;
selfDragbox.on('boxend', function() {
// features that intersect the box are added to the collection of
// selected features, and their names are displayed in the "info"
// div
var extent = selfDragbox.getGeometry().getExtent();
_countrySelectSource.forEachFeatureIntersectingExtent(extent, function(feature) {
selectedFeatures.push(feature);
_countryCodes.push(feature.getId());
});
infoBox.innerHTML = _countryCodes.join(', ');
});
// clear selection when drawing a new box and when clicking on the map
selfDragbox.on('boxstart', function() {
selectedFeatures.clear();
infoBox.innerHTML = ' ';
});
_map.on('singleclick', function(event) {
selectedFeatures.clear();
_countryCodes = [];
_map.forEachFeatureAtPixel(event.pixel,function(feature){
selectedFeatures.push(feature);
var id = feature.getId();
var index = _countryCodes.indexOf(id);
if ( index === -1 ) {
_countryCodes.push(feature.getId());
}
});
infoBox.innerHTML = _countryCodes.join(', ');
});
},
setActive: function(active){
this.select.setActive(active);
this.dragbox.setActive(active);
}
};
_CountrySelect.init();
I am not sure if this is an issue with OL3 or my code. Maybe there's an event I'm not handling? Maybe it's the ol.interaction.DragBox (no luck researching on the DragBox). Let me know what further information I can provide.

How to load data in highcharts from text

I would like to use a CSV file as source for a highcharts graph.
Could you give some guidance? I need to understand basically how to get data in the web page.
Do I need to put the function that load the text file in the "series" part of the js function?
This is what I have so far:
<script type='text/javascript'>
var options = {
chart: {
renderTo: 'container',
defaultSeriesType: 'line'
},
title: {
text: 'chart example'
},
xAxis: {
categories: []
},
yAxis: {
},
series: []
};
$.get('test.csv', function(data) {
// Split the lines
var lines = data.split('\n');
// Iterate over the lines and add categories or series
$.each(lines, function(lineNo, line) {
var items = line.split(',');
// header line containes categories
if (lineNo == 0) {
$.each(items, function(itemNo, item) {
if (itemNo > 0) options.xAxis.categories.push(item);
});
}
// the rest of the lines contain data with their name in the first
// position
else {
var series = {
data: []
};
$.each(items, function(itemNo, item) {
if (itemNo == 1) {
series.name = item;
} else {
series.data.push(parseFloat(item));
}
});
options.series.push(series);
}
});
// Create the chart
var chart = new Highcharts.Chart(options);
});
This is how the data file is structured in the CSV file:
Compound,Value
mix1,0.244
mix2,0.453
pureCu,1
pureAg,0.98
The value of column 1 is an ID basically, so the distance between each of them could be considered as 1. So technically, the first column would be always from 1 to 15 for example, with the label using the name in the first column
I would like to put the second field on the Y, and on the X the first field; but using the code pasted (which is what is on an example on the Highcharts website), I can't really figure out how to set up correctly the values on each side of the chart.
Thanks
Here you can find tutorials from Highcharts to load data from external file: http://www.highcharts.com/docs/working-with-data/preprocessing
About refreshing page - yes you can refresh page every n-seconds, however it would be better (I think) to call AJAX to fetch new data from server and then replace it in Highcharts (simply using chart.series[0].setData( new_array_of_data );

How can I call stored procedure returning 2 tables in a controller in mvc entity framework 4?

I have a stored procedure which returns 2 tables. How can I call this stored procedure from a controller in MVC.
(I'm using Entity Framework 4)
Stored procedure:
create proc [dbo].[sp_list33](#emp dbo.list READONLY )
as
select * from dbo.Items
select * from dbo.dept
Here 'list' is a userdefined table type for passing table valued parameter.
CREATE TYPE [dbo].[list] AS TABLE(
[eid] [int] NULL,
[name] [nvarchar](50) NULL,
[age] [int] NULL
)
In controller:
[HttpPost]
public JsonResult Onclick(int id)
{
using (examemployeeEntities1 eee = new examemployeeEntities1())
{
//Create table value parameter
DataTable dt = new DataTable();
DataRow dr = dt.NewRow();
dt.Columns.Add("eid");
dt.Columns.Add("name");
dt.Columns.Add("age");
dt.Rows.Add(1, "john", 21);
dt.Rows.Add(2, "albert", 22);
dt.Rows.Add(3, "martin", 33);
SqlParameter emp1 = new SqlParameter("#emp", SqlDbType.Structured);
emp1.Value = dt;
emp1.TypeName = "list";
//eee.Database.ExecuteSqlCommand("EXEC sp_list4 #emp",emp1);
var resp = eee.Database.SqlQuery<Item>("exec sp_list33 #emp", emp1);
return Json(resp.ToList());
}
}
In view:
paragraph id is "sdf" and button id is "asd"!!!!!
Script:
$("#asd").click(function () {
var a = 1;
var content = "<table><th>Id</th><th>Name </th><th>Age</th></tr>";
$.ajax({
type: 'POST',
url: '/Home/Onclick/',
data: { 'id': a },
datatype: 'json',
success: function (data) {
$.each(data, function (i, item) {
content += "<tr>";
content += "<td style=\"background-color:White\">" + data[i].eid + "</td>";
content += "<td style=\"background-color:White\">" + data[i].name + "</td>";
content += "<td style=\"background-color:White\">" + data[i].age + "</td>";
content += "</tr>";
});
content += "</table>";
$('#sdf').html(content);
alert("success");
},
error: function () {
}
});
});
Result displays content in the Item table only. How to get two entities from stored procedure? It is only retrieving the first select statement. Can any one help me to solve this..?
Since you are not using EF5, you can't go the easy way
As Microsoft stated in that link:
"Prior to EF5, Entity Framework would allow the stored procedure to be called but would only return the first result set to the calling code."
But there is always a work-around. Follow this steps and you will be able to achieve it. Although is not a very straight forward solution.
Hope this helps

Extjs4 set tooltip on each column hover in gridPanel

I am getting tooltip on mouse hover by each row for current column but I am unable to get next column tooltip on continue hover on same row.
But I can get it if I hover on another row & again hover any column of the previous row by using:
listeners:{
'itemmouseenter': function (view, record, item, index, e, eOpts) {
var gridColums = view.getGridColumns();
var column = gridColums[e.getTarget(this.view.cellSelector).cellIndex];
Ext.fly(item).set({ 'data-qtip': 'Des:' + column.dataIndex });
}
}
Can anyone show me what I'm missing or point me in the right direction?
I have an easy one, using the renderer function:
{
xtype : 'gridcolumn',
dataIndex : 'status',
text : 'Status',
renderer : function(value, metadata) {
metadata.tdAttr = 'data-qtip="' + value + '"';
return value;
}
}
I was looking through this. I could manage to get the tool tip for each cell by doing something like this:
Ext.getCmp('DynamicDemandGrid').getView().on('render', function(view) {
view.tip = Ext.create('Ext.tip.ToolTip', {
// The overall target element.
target: view.el,
// Each grid row causes its own seperate show and hide.
delegate: view.cellSelector,
// Moving within the row should not hide the tip.
trackMouse: true,
// Render immediately so that tip.body can be referenced prior to the first show.
renderTo: Ext.getBody(),
listeners: {
// Change content dynamically depending on which element triggered the show.
beforeshow: function updateTipBody(tip) {
var gridColums = view.getGridColumns();
var column = gridColums[tip.triggerElement.cellIndex];
var val=view.getRecord(tip.triggerElement.parentNode).get(column.dataIndex);
tip.update(val);
}
}
});
});
Let me know if it helps
{
text: name,
width: 80,
dataIndex: dataIndex,
sortable: true,
listeners: {
afterrender: function ()
{
Ext.create('Ext.ToolTip',
{
target: this.getEl(),
anchor: direction | "top",
trackMouse: true,
html: this.text
});
}
}
}

Resources