Add anotation to a serie if value is > 0 - google-visualization

How to add annotation to serie C if value is > 0?
Fiddle
What configuration with...
data.addColumn({type: 'string', role: 'annotation'});
...is necessary?

You can add a calculated annotation column via the chart's view parameter:
view: {
columns: [0, 1, 2, 3, {
type: 'string',
role: 'annotation',
calc: function (dt, row) {
return (dt.getValue(row, 3) > 0) ? 'Yes' : null;
}
}]
}
See working example: http://jsfiddle.net/asgallant/hRpDp/3/

Related

How to filter the result whose type is array in loopback 4?

import {Entity, model, property} from '#loopback/repository';
#model()
export class Misc extends Entity {
#property({
type: 'number',
id: true,
generated: true,
})
id?: number;
#property({
type: 'array',
itemType: 'number',
required: true,
})
members: number[];
constructor(data?: Partial<Misc>) {
super(data);
}
}
export interface MiscRelations {
// describe navigational properties here
}
export type MiscWithRelations = Misc & MiscRelations;
Above is the model for misc API. I am using PostgreSQL.
I have inserted data in the table. Result of GET request from this table is as following -
[
{
"id":1,
"members":[
1,
2,
3
]
},
{
"id":2,
"members":[
1,
2,
3,
4,
5
]
},
{
"id":3,
"members":[
10,
20,
30,
40,
50
]
},
{
"id":4,
"members":[
100,
200,
300,
400,
500
]
},
{
"id":5,
"members":[
1,
2,
3,
500,
1000,
5000
]
}
]
I want to get the records who have members with value 1, so I applied a filter like this -
http://localhost:3000/miscs?filter[where][inq][members]=1
But this isn't working. If there is no way to execute such a query then can I do some change in the model to adjust its type such that it can accept CSV values and also can filter those data?
Please help. Thanks in advance!
For the Postgresql connector, use contains, which accepts an array:
?filter[where][contains][members][0]=1
- SAME AS -
{
where: {
contains: [1]
}
}
Finally, I found an answer. Regex can be used to match the record here like this
filter[where][members][regexp]=1,|1]

How to get data point x/y values when Google Visualisation line chart data point clicked [duplicate]

i want to take out 'text value' on mouse click on anywhere on the row/svg image ,for i.e. in the below image if i click anywhere on 2nd blue highlighted row, then i should be able to get the text 'Adams' as alert. I tried to iterate thru svg elements but svg elements are created horizontally rather then vertically
you can use the 'select' event, to determine the value selected
when the 'select' event fires, check chart.getSelection()
google.visualization.events.addListener(chart, 'select', function () {
selection = chart.getSelection();
if (selection.length > 0) {
console.log(dataTable.getValue(selection[0].row, 0));
}
});
getSelection returns an array of the selected rows,
Timeline charts only allow one row to be selected at a time,
so the selection will always be in the first element
chart.getSelection()[0]
each element in the array will have properties for row and column
(column will always be null for a Timeline chart)
once you have the row, you can use getValue on the DataTable
dataTable.getValue(selection[0].row, 0)
getValue takes two arguments, rowIndex and columnIndex
use 0 to get the value of the first column
see following working snippet...
google.charts.load('current', {
callback: function () {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'President' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ 'Washington', new Date(1789, 3, 30), new Date(1797, 2, 4) ],
[ 'Adams', new Date(1797, 2, 4), new Date(1801, 2, 4) ],
[ 'Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4) ]]);
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
google.visualization.events.addListener(chart, 'select', function () {
selection = chart.getSelection();
if (selection.length > 0) {
console.log(dataTable.getValue(selection[0].row, 0));
}
});
chart.draw(dataTable);
},
packages: ['timeline']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>
EDIT
to capture the click anywhere on the row, outside the colored bar,
use the 'ready' event to find the svg elements and add a listener
the elements will have an x attribute of zero (0)
and a fill attribute other than 'none'
since the number of elements will match the number of rows,
we can use the index of the element, amongst its peers, to find the value
see following working snippet,
both the 'select' and 'click' events are used to find the value clicked
google.charts.load('current', {
callback: function () {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'President' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ 'Washington', new Date(1789, 3, 30), new Date(1797, 2, 4) ],
[ 'Adams', new Date(1797, 2, 4), new Date(1801, 2, 4) ],
[ 'Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4) ]]);
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var saveRows = [];
google.visualization.events.addListener(chart, 'ready', function () {
chartRows = container.getElementsByTagName('rect');
Array.prototype.forEach.call(chartRows, function(row) {
if ((parseInt(row.getAttribute('x')) === 0) && (row.getAttribute('fill') !== 'none')) {
saveRows.push(row);
row.addEventListener('click', function (e) {
for (var i = 0; i < saveRows.length; i++) {
if (e.target === saveRows[i]) {
getRowLabel(i);
break;
}
}
}, false);
}
});
});
google.visualization.events.addListener(chart, 'select', function () {
selection = chart.getSelection();
if (selection.length > 0) {
getRowLabel(selection[0].row);
}
});
function getRowLabel(index) {
console.log(dataTable.getValue(index, 0));
}
chart.draw(dataTable);
},
packages: ['timeline']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>

Google Visualization API series data in rows not columns. Pivot? [duplicate]

I want to display "population" of various countries through the years in the same line chart. The data displayed is based on selections from a multi-select dropdown "Countries". Underlying Data Table has 3 columns:
Year, Country, Population
2012,countryA,33
2013,countryA,35
2014,countryA,40
2012,countryB,65
2013,countryB,70
2014,countryB,75
2012,countryC,15
2013,countryC,20
2014,countryC,25
I am trying to create a pivoted Data View from the underlying Data Table
The code I am using is:
function drawLineChart() {
var arr = $('#country').val();
var lineChartJson = $.ajax({
url: "../json/lineChart.json",
dataType: "json",
async: false
}).responseText;
var lineChartData = new google.visualization.DataTable(lineChartJson);
var view = new google.visualization.DataView(lineChartData);
var viewCols = [0];
for(var i = 0; i < arr.length; i++) {
var viewCols1 = [{
type: 'number',
label: arr[i],
calc: function (dt, row) {
return (dt.getValue(row, 1) == arr[i]) ? dt.getValue(row, 2) : null;
}
}];
viewCols = viewCols.concat(viewCols1);
}
view.setColumns(viewCols);
var aggCols = [{
column: 1,
type: 'number',
label: view.getColumnLabel(1),
aggregation: google.visualization.data.sum
}];
for(var i = 2; i < 4; i++) {
var aggCols1 = [{
column: i,
type: 'number',
label: view.getColumnLabel(i),
aggregation: google.visualization.data.sum
}];
aggCols = aggCols.concat(aggCols1);
}
var pivotedData = google.visualization.data.group(view, [0], aggCols);
But this does not seem to work as expected and I just get 1 Line in the chart with values for all countries added up (although I can see the legend for 3 countries)
On the other hand if I set my View columns as below, it works as expected.
view.setColumns([0, {
type: 'number',
label: arr[0],
calc: function (dt, row) {
return (dt.getValue(row, 1) == arr[0]) ? dt.getValue(row, 2) : null;
}
}, {
type: 'number',
label: arr[1],
calc: function (dt, row) {
// return values of C only for the rows where B = "bar"
return (dt.getValue(row, 1) == arr[1]) ? dt.getValue(row, 2) : null;
}
}, {
type: 'number',
label: arr[2],
calc: function (dt, row) {
return (dt.getValue(row, 1) == arr[2]) ? dt.getValue(row, 2) : null;
}
}]);
What is going wrong in the loop? Is something wrong with "concat" in the loop where I am creating View Columns? I also saw the viewCols array by using console.log and it seems to have the right elements
I was trying to follow the below post:
Creating pivoted DataView from existing google charts DataTable object
the problem has to do with scope
arr[i] is undefined within calc: function (dt, row)
here is another way to pivot the data...
google.charts.load('current', {
callback: function () {
var arr = [
'countryA',
'countryB',
'countryC'
];
var lineChartData = google.visualization.arrayToDataTable([
['Year', 'Country', 'Population'],
[2012,'countryA',33],
[2013,'countryA',35],
[2014,'countryA',40],
[2012,'countryB',65],
[2013,'countryB',70],
[2014,'countryB',75],
[2012,'countryC',15],
[2013,'countryC',20],
[2014,'countryC',25]
]);
// sort by year
lineChartData.sort([{column: 0}]);
// get unique countries
var countryGroup = google.visualization.data.group(
lineChartData,
[1]
);
// build country data table
var countryData = new google.visualization.DataTable({
cols: [
{label: 'Year', type: 'number'},
]
});
// add column for each country
for (var i = 0; i < countryGroup.getNumberOfRows(); i++) {
countryData.addColumn(
{label: countryGroup.getValue(i, 0), type: 'number'}
);
}
// add row for each year / country
var rowYear;
var rowIndex;
for (var i = 0; i < lineChartData.getNumberOfRows(); i++) {
if (rowYear !== lineChartData.getValue(i, 0)) {
rowYear = lineChartData.getValue(i, 0);
rowIndex = countryData.addRow();
countryData.setValue(rowIndex, 0, rowYear);
}
for (var x = 1; x < countryData.getNumberOfColumns(); x++) {
if (countryData.getColumnLabel(x) === lineChartData.getValue(i, 1)) {
countryData.setValue(rowIndex, x, lineChartData.getValue(i, 2));
}
}
}
// draw agg table
new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table-div',
dataTable: countryData
}).draw();
// draw line chart
new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart-div',
dataTable: countryData
}).draw();
},
packages: ['corechart', 'table']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="table-div"></div>
<div id="chart-div"></div>
I could figure out the problem with my code above.
"calc" is the callback function in loop. So only last value of loop variable "i" is visible within the loop.
Putting a wrapper function fixes it:
for(var i = 0; i <= arr.length; i++)(function(i) {
var viewCols1 = [{
type: 'number',
label: arr[i],
calc: function (dt, row) {
return (dt.getValue(row, 1) == arr[i]) ? dt.getValue(row, 2) : null;
}
}];
viewCols = viewCols.concat(viewCols1);
})(i);

Add additional data to google chart dataTable

I'm using google scatterchart to show where defects are on a surface. All defects have an ID, when I click on a point I want an event to fire from where I can get that ID and do other stuff with it.
In google chart one can wire an selecthandler from where I can get what's selected, but how do I add an ID (or any other data) in the dataTable to a point without it being displayed?
For example:
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', 'Width');
dataTable.addColumn('number', 'Yellow');
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } });
dataTable.addColumn('number', 'Red');
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } });
dataTable.addColumn('number', 'Id'); <-- this doesn't work
The last column I want to add the ID of the defect and retrieve it via the selectHandler.
dataTable.addRow([123, 123, 'some tooltip', null, null, 999]);
Here I added ID 999 to the table. But I don't want the chart to display it. How do I add additional (hidden) data to a point?
You can add extra columns containing any information you want, and then hide them with a DataView:
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', 'Width');
dataTable.addColumn('number', 'Yellow');
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } });
dataTable.addColumn('number', 'Red');
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } });
dataTable.addColumn('number', 'Id');
// populate dataTable
var view = new google.visualization.DataView(dataTable);
// exclude column 5 (Id)
view.setColumns([0, 1, 2, 3, 4]);
Then draw your chart using the DataView instead of the DataTable.
setRowProperties(rowIndex, properties) would work in this case, remove Id column and add dataTable.setRowProperties(0,{'id':'999'});
You can get the property of the row by using getRowProperties(rowIndex);

Modify appearance of DataTable role in a Google Chart

I have a column chart for which I use the certainty role to indicate that a value is uncertain. This is visualized as a non-solid fill of the column. However, this appearance is a little too subtle, so I want to make it a little bit clearer. Is there a way to hook into the charts API, or specify options for a role, that can modify it's appearance?
The API does not support modifying the appearance of the uncertain columns. You can make a feature request to add support for modifying the appearance of uncertain elements.
Edit:
You can hack around the problem if your chart meets certain criteria (namely, you are using a Bar or ColumnChart with either 1 series of data or the "isStacked" option set to true; or a SteppedArea chart; or a LineChart/ScatterChart showing data points only [no lines]. LineCharts [with lines] and AreaCharts can be made to work, but it involves a lot more effort to make it happen. Other charts may be possible, but I haven't thought about how to make it work with them).
To make this work, you create a boolean column for your data (it doesn't have to have the "certainty" role, but assigning the role doesn't hurt anything either). Then you create a DataView or set the "view" parameter of a ChartWrapper to create one series of data for values where the boolean is true, and one series for values where the boolean is false, like this:
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Value');
data.addColumn('boolean', 'Boolean');
data.addRows([
['Germany', 700, true],
['USA', 300, true],
['Brazil', 400, false],
['Canada', 500, true],
['France', 600, false],
['Russia', 800, true]
]);
var chart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
dataTable: data,
options: {
// setting the "isStacked" option to true fixes the spacing problem
isStacked: true,
height: 300,
width: 600,
series: {
0: {
// options for Boolean = true
color: '#3366cc'
},
1: {
// options for Boolean = false
color: '#0099c6',
visibleInLegend: false
}
}
},
view: {
columns: [0, {
type: 'number',
label: data.getColumnLabel(1),
calc: function (dt, row) {
// return value if Boolean is true
return (dt.getValue(row, 2)) ? dt.getValue(row, 1) : null;
}
}, {
type: 'number',
label: data.getColumnLabel(1),
calc: function (dt, row) {
// return value if Boolean is false
return (dt.getValue(row, 2)) ? null : dt.getValue(row, 1);
}
}]
}
});
chart.draw();
}
See example: http://jsfiddle.net/asgallant/Xzbw5/