Add annotations with Chartkick - ruby-on-rails

I want to add annotations to my time series chart.
From Google's documentation:
data.addColumn({type:'string', role:'annotation'});
How can I pass these column properties through Chartkick?
<%= line_chart [{name: 'annotations', data: annotations_array},{name: 'numbers as a time series', data: 'numeric_array'}] %>

I created a pull request to the chartkick.js repo to add the functionality you're describing.
https://github.com/ankane/chartkick.js/pull/58
This is just for the JS library (chartkick.js), but the approach can be used in the ruby library by using the modified chartkick.js from this pull request and passing in the right role values (certainty, annotation, etc.) to the library options.
var data = [..., [Sat Mar 05 2016 17:13:22 GMT-0800 (PST), 1, false, "cool annotation"]];
new Chartkick.LineChart("chart-1", data, {
"library":
{"role":["certainty", "annotation"]}
});

If you're using chartjs-plugin-annotation.js:
https://github.com/chartjs/chartjs-plugin-annotation, then you need to use the library option which passes options from Chartkick through to the underlying chart provider, e.g. Chart.js.
Here's an example I got working to annotate a graph with a labelled vertical line:
<%=
line_chart profit_chart_path(staff), xtitle: 'Day', ytitle: 'Profit',
library: {
annotation: {
annotations: [
{
type: 'line',
mode: 'vertical',
scaleID: 'x-axis-0',
value: 'May 2018',
label: {
content: 'My Vertical Line',
enabled: true
}
}
]
}
}
%>
If, for instance, you wanted a horizontal annotated line with e.g. a numerical value, use these values instead:
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 20,
Ensure that you've registered the plugin first!
import ChartAnnotationsPlugin from 'chartjs-plugin-annotation';
Chart.plugins.register(ChartAnnotationsPlugin);

Try something like this (not tested):
<%= line_chart TABLE.group(XXX).where(XXX), library: {name: 'annotations', data: annotations_array, name: 'numbers as a time series', data: 'numeric_array', type:'string', role:'annotation'} %>

In 2022, with plugin version 1.4.0, working configuration is as follows:
library:
{
plugins:
{
annotation:
{
annotations:
{
line1:
{
type: 'line',
xMin: "2022-06-01",
xMax: "2022-06-01",
borderColor: 'rgb(255, 99, 132)',
borderWidth: 2
}
}
}
}
}
Without plugins key does not work.
You have to register a new plugin in app/javascript/application.js(if it is Rails app):
import { Chart } from 'chart.js';
// Make annotations for charts
import annotationPlugin from 'chartjs-plugin-annotation';
Chart.register(annotationPlugin);
an then in the view you can use it like this:
= line_chart #some_records, curve: false, prefix: "EUR ", thousands: "'", points: false,
library: {plugins: {annotation: {annotations: {line1: {type: 'line', xMin: Date.today.beginning_of_month.to_s, xMax: Date.today.beginning_of_month.to_s, borderColor: 'rgb(105,105,105)', borderWidth: 1}}}}}

Related

HighMap data table not loading points

I'm trying to populate a map of the U.S. in HighMaps with data from an html table. The map is showing but the data point is not. It's a latitude/longitude point. The documentation is sparse, so I'm not sure what I'm doing wrong. Here's a JSFiddle: https://jsfiddle.net/sfjeld/1wjm04fc/6/
Highcharts.mapChart('container', {
chart: {
map: 'countries/us/custom/us-all-territories'
},
series: [{
name: 'Basemap',
dataLabels: {
enabled: true,
format: '{point.name}'
}
},
{
// Specify points using lat/lon
type: 'mappoint',
data: {
table: 'pvsoiling-table',
startRow: 1,
startColumn: 1,
endColumn: 2
},
name: 'PV',
marker: {
fillColor: 'white',
lineColor: 'black',
lineWidth: 2,
radius: 10
},
color: Highcharts.getOptions().colors[1]
}
]
});
thanks,
Shauna
You can make the following changes to your code:
At the start of your <script> section, load your HTML table data into a JavaScript array:
var mapData = [];
Highcharts.data({
table: document.getElementById('pvsoiling-table'),
startColumn: 1,
endColumn: 2,
firstRowAsNames: true,
complete: function (options) {
options.series[0].data.forEach(function (p) {
mapData.push({
lat: p[0],
lon: p[1]
});
});
//console.log(mapData);
}
});
We will refer to this mapData array later on. Here is what it contains:
[
{ "lat": 33.3, "lon": -111.67 }
]
Make changes to the series section in your Highcharts.mapChart.
series: [{
name: 'Basemap',
nullColor: '#e0f9e3',
dataLabels: {
enabled: true,
format: '{point.name}'
}},
{
// Specify points using lat/lon
data: mapData,
type: 'mappoint',
name: 'PV',
marker: {
fillColor: 'white',
lineColor: 'black',
lineWidth: 1,
radius: 3
},
color: Highcharts.getOptions().colors[1]
}
]
The key part to note is the data: mapData option. The JavaScript mapData variable is the exact array that we need to represent a set of points on the map. In our case the array only contains one point - but that's because there is only one relevant row of data in the HTML table.
My map ends up looking like this:
It looks like the marker is in or near Phoenix, AZ.
Final notes:
(a) I also adjusted the marker to have lineWidth: 1 and radius: 3 (a bit smaller).
(b) I added a document ready function around everything, to ensure the DataTable is loaded before you try to read its data.
(c) There may be a more elegant way to do this, but I followed the approach in this demo. The demo actually shows how to join 2 different sets of data - not what you need. But it does show a good approach for extracting the HTML data so it can be used in the map.
Using the the Highcharts.data({...}) approach lets you access any HTML table. But since you are using DataTables, you can choose to do the following, instead. It uses the DataTables API to access each row of data:
var mapData = [];
$('#pvsoiling-table').DataTable({
"initComplete": function(settings, json) {
var api = this.api();
api.rows().data().each(function (p) {
mapData.push({ lat: Number(p[1]), lon: Number(p[2]) });
});
// your Highcharts.mapChart() logic, in a function:
buildChart();
}
});

How to setup logarithmic axis for line chart in rails chartkick?

Is there way to setup log axis using chartkick and default chart.js library?
Yes, you can pass the axis options using 'library' option like this:
<%= line_chart data, {
library: {
legend: {
position: 'bottom',
},
scales: {
yAxes: [
{
id: 'y-axis',
type: 'logarithmic'
},]
}
}
} %>
For more options please consult with chart.js docs.

Drawing linear function by using Chartkick gem and Google chart

I am trying to draw a linear function(like y=ax+b) by using Chartkick gem and google chart on my rails application.
'a' and 'b' will be given as parameters.
The problem is that I am trying to achieve an infinite line graph using google chart out of slope 'a' and 'b' and I don't know how to achieve this in a proper way.
I came up with the solution of drawing a line chart with two points, (-b/a, 0) and (0, b) and give trendlines option onto it.
<!-- y = 0.55x floatify(2,#datas[4][2]) + 1.47 floatify(2,#datas[3][2]) -->
<%= line_chart [
{name: "targets",
data: [
["#{-(#datas[3][2].to_f/#datas[4][2].to_f).round(2)}",0],
[0,"#{#datas[3][2].to_f}"]
]
},
],
library: {
title: "#{#simplereg.variable_name}",
subtitle: "#{#simplereg.data_name}",
legend: "right",
vAxis: {title: 'average'},
trendlines: {
0: {
type: 'exponential',
visibleInLegend: true
}
}
}
%>
However, rails cannot read a '0' value as an option of trendlines unlike what google chart documentation says.
-> https://developers.google.com/chart/interactive/docs/gallery/trendlines
I have no clue how to fix this code to work.
Please help me... I don't mind throwing up this code and writing in completely different way.
Thanks ahead.
Use something like below
<%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %>
<%= line_chart [
{name: "targets",
data: [
["-2/3",0],
[0,"2"]
]
},
],
library: {
title: "ABC",
subtitle: "XYZ",
legend: "right",
vAxis: {title: 'average'},
trendlines: {
"0"=> {
type: 'exponential',
visibleInLegend: true
}
}
}
%>
basically instead of symbo 0: use "0" =>

HighCharts Stacked column

I'm using HighCharts, I have this array,
I would like to create a chart like this:
As I know, the format of series is like this:
series:[{
name: 'Production',
data: [0.074, 0.040,0.034,0.036,0.068]
}, {
name: 'Reprise',
data: [0.024,0.022,0.029, 0.055, 0.052]
}]
with categories array:
['Mario', 'Andre', 'Jean Jacques', 'Fidy', 'Judith']
How could I do if I want to paste each value of column Volumes to each Production Stacked Bar value like the chart above ?
Thanks!
you can see an example here: http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/column-stacked/
series: [{
name: 'Volume',
data: [1, 0.16, 0.46, 0.37, 0.24]
}, {
name: 'Reprise',
data: [0.024, 0.0.....]
}, {
name: 'Production',
data: [....]
}]
Later edit: to display volume as data label you can use the formatter function:
column: {
stacking: 'normal',
dataLabels: {
formatter: function () {
return this.x;//you can have a little logic here if (thix.x == 'Production) return myVariable[y];myVariable will contains values from volume or something similar
}
}
}
Define volume in your data array:
data: [{y:0.074,volume:1}, {y:0.040,volume:0.15}]
And use formatter in datalabels options to get custom value:
formatter: function () {
return this.point.volume + ' km';
}
jsfiddle

Mixed Chart Types using Chartkick/Highcharts on Rails

I'm trying to create a mixed column/line chart using Highcharts.
I've been trying to use the library functionality to set one of my data series to be of type "line". I have tried a few different approaches, but I can't seem to figure out how to pass the type parameter of a given series using the Highcharts API.
<%= column_chart( ChartData.new(#forecast).revenue_and_net_income, library: {
title: {
text: "Revenue and Net Income"
},
series: [{
1 => {
type: "line"
}
}],
} ) %>
Where my data come from the following method:
def revenue_and_net_income
data = [
{
name: "Revenue",
data: revenue_by_year
},
{
name: "Net Income",
data: net_income_by_year,
}
]
end
Not sure what I'm doing wrong? I only seem to be able to access the Highcharts API methods listed under 'Chart', none of the series options etc. seem to work. Can anyone point me in the right direction for how to successfully get this to work?
you can try this way.
<%= line_chart [
{
name: "Amount", type: "column", data: #cause.donations.map {
|t| [t.user.name, t.amount]
}
},
{
name: "Test", type: "line", data: #cause.donations.map {
|t| [t.user.name, t.amount]
}
}
],
prefix: "$",
adapter: "highcharts"
%>
just don't care line_chart, column_chart or anythings... ONLY custom type in data. OK

Resources