Highcharts setExtremes overflow issue - highcharts

I have a Highcharts column graph with 10 series on the x axis.
http://qaa.balcroft.com/images/chart1.png
I want to allow the user to zoom in so I added a button to setExtremes:
$('#zoomInButton').click(function () {
var chart = $('#container').highcharts();
chart.xAxis[0].setExtremes(4, 9);
});
However this causes the graph to overflow into the y axis title area on the left hand side.
http://qaa.balcroft.com/images/chart2.png
I've tried amending xAxis.minRange and yAxis.overflow but neither fixes the problem.
Any suggestions?
The function to create the graph is
function inialiseGraphOnLoad(strOrgCode, strLevelCode, currentLevel, strTeamName){
var jsonMimeType = "application/json;charset=UTF-8";
$.ajax({
type: "POST",
url: "ajax/getStaffOnLoad.php",
cache: false,
data: {org: strOrgCode, levelcode: strLevelCode, level: currentLevel},
beforeSend: function(x) {
if(x && x.overrideMimeType) {
x.overrideMimeType(jsonMimeType);
}
},
dataType: 'json',
success: function(dataDepts){
//Create array of employee names
chartWidth = 0;
maxZoom = 0;
var listDepts = [];
for (var i = 0; i < dataDepts.employees.length; i++) {
chartWidth = chartWidth + 250;
maxZoom = maxZoom + 1;
var arrayEmployee = dataDepts.employees[i].name;
var splitResult = arrayEmployee.split("||");
var strEmployeeCode=splitResult[0];
var strEmployeeName=splitResult[1];
var employeeURL = serverURL + strEmployeeCode + '">' + strEmployeeName + '</a>';
listDepts.push(employeeURL);
}
var mainPageWidth = $('#staffMainPage').width();
if(chartWidth > mainPageWidth){
chartWidth = mainPageWidth;
}else if(chartWidth < 500){
chartWidth = 500;
}
$('#hid_lastPage').val(maxZoom);
//Create series array
var seriesArray = [];
for (var i = 0; i < dataDepts.groups.length; i++) {
seriesArray.push({
name : dataDepts.groups[i].name,
dataLabels: {
enabled: true,
rotation: -90,
color: '#424242',
align: 'right',
x: 4,
y: 10,
style: {
fontFamily: 'Verdana, sans-serif'
},
formatter:function(){
if(this.y > 0){
return this.y;
}
}
},
color : dataDepts.groups[i].colour,
data : []
});
for (var j = 0; j < dataDepts.employees.length; j++) {
if(i == 0){
seriesArray[i].data.push(dataDepts.employees[j].rating1);
}else if(i == 1){
seriesArray[i].data.push(dataDepts.employees[j].rating2);
}else if(i == 2){
seriesArray[i].data.push(dataDepts.employees[j].rating3);
}else if(i == 3){
seriesArray[i].data.push(dataDepts.employees[j].rating4);
}else if(i == 4){
seriesArray[i].data.push(dataDepts.employees[j].rating5);
}else if(i == 5){
seriesArray[i].data.push(dataDepts.employees[j].rating6);
}else if(i == 6){
seriesArray[i].data.push(dataDepts.employees[j].rating7);
}else if(i == 7){
seriesArray[i].data.push(dataDepts.employees[j].rating8);
}else if(i == 8){
seriesArray[i].data.push(dataDepts.employees[j].rating9);
}else if(i == 9){
seriesArray[i].data.push(dataDepts.employees[j].rating10);
}else if(i == 10){
seriesArray[i].data.push(dataDepts.employees[j].rating11);
}else if(i == 11){
seriesArray[i].data.push(dataDepts.employees[j].rating12);
}else if(i == 12){
seriesArray[i].data.push(dataDepts.employees[j].rating13);
}else if(i == 13){
seriesArray[i].data.push(dataDepts.employees[j].rating14);
}else if(i == 14){
seriesArray[i].data.push(dataDepts.employees[j].rating15);
}
}
}
// Set up the chart
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
width: chartWidth,
height: 550,
marginBottom: 100,
margin: 80,
options3d: {
enabled: true,
alpha: 5,
beta: 10,
depth: 50,
viewDistance: 25
}
},
title: {
text: strTeamName
},
subtitle: {
text: 'Quality Rating By Employee'
},
xAxis: {
categories: listDepts,
useHTML: true,
minRange: 5,
title: {
text: '<br>(click an employee name for more detail)',
style: {
color: '#6E6E6E',
fontSize: '1em',
fontFamily: 'Verdana, sans-serif'
}
}
},
yAxis: {
min: 0,
title: {
text: 'Quality Rating (%)',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
valueSuffix: ' %'
},
scrollbar: {
enabled: true
},
plotOptions: {
column: {
depth: 25
},
bar: {
dataLabels: {
enabled: true
}
}
},
series:seriesArray
});
}
});
}

Related

I want to show tooltip on mouse hover of every coordinate in angular-highchart, it should show x and y axis value in tooltip or label

chart = new Chart({
chart: {
type: "line",
// height : 1000
// height: 55 + '%',
height: (9 / 16) * 100 + "%",
// width: 1200,
},
title: {
text: "",
},
credits: {
enabled: false,
},
legend: {
title: {
text: "OrderNumber",
style: {
fontStyle: BOLD,
},
},
layout: "vertical",
align: "right",
verticalAlign: "top",
borderWidth: 1,
floating: true,
backgroundColor: WHITE,
},
xAxis: {
startOnTick: true,
endOnTick: true,
title: {
text: this.xLabel,
style,
},
type: CTYPE,
gridLineColor: BLACK,
// min:
// this.chartData != undefined
// ? Math.log10(Math.ceil(Math.min(this.chartData.series) / 10) * 10)
// : this.xMin,
max: this.xMax,
gridLineWidth: 1,
lineColor: BLACK,
minorGridLineColor: BLACK,
lineWidth: 1,
tickLength: 20,
tickInterval: 1,
minorTickInterval: 0.1,
minorGridLineWidth: 0.5,
// animation: false,
labels: {
formatter: function () {
var raise = require("superscript-text");
let num = Math.log10(this.value as number).toPrecision(1);
let base = "10";
let final = base + raise(num.toString());
return final;
},
},
},
yAxis: {
startOnTick: true,
endOnTick: true,
title: {
text: this.yLabel,
style,
},
max: this.yMax,
min: this.yMin,
type: CTYPE,
lineColor: BLACK,
lineWidth: 1,
gridLineColor: BLACK,
minorGridLineColor: BLACK,
gridLineWidth: 1,
tickLength: 20,
tickInterval: 1,
minorTickInterval: 0.1,
minorGridLineWidth: 0.5,
labels: {
formatter: function () {
var raise = require("superscript-text");
let num = Math.log10(this.value as number);
let base = "10";
let final = base + raise(num.toString());
return final;
},
},
},
plotOptions: {
series: {
stickyTracking: false,
marker: {
enabled: false,
},
states: {
hover: {
enabled: false,
},
inactive: {
opacity: 1,
},
},
animation: false,
visible: true,
},
line: {
events: {
legendItemClick: function (event) {
this.selectedItemList.forEach((item) => {
if (event.target.options.id === item.product.index) {
item.product.toggleSlashEye = !item.product.toggleSlashEye;
let count = 0;
this.selectedItemList.forEach((item) => {
if (item.product.toggleSlashEye === false) count++;
});
if (count === this.selectedItemList.length) this.isSeriesVisible = true;
else this.isSeriesVisible = false;
}
});
}.bind(this),
},
},
// animation: false,
},
tooltip: {
enabled: true,
followPointer: true,
formatter: function () {
return `<b>x = ${this.y}</b> y = <b>${this.x} </b>`;
},
},
series: [],
});
currnet code status - currently I am showing tooltip on series only.
expected - I want to show the tooltip on the locations where the yaxis and xaxis graph lines cross.

HighStock: Trend jumping out of Chart Area on zooming with zoomType='xy' or zoomType='y'

I am working with HighCharts (Version:^5.0.14) and React(react:^15.0.1, react-dom:^15.0.1).
I am facing an issue with HighStock Chart Zooming. With the zoomType = 'xy' or zoomType='y', the zoomed HighStock trend jumps of the X-Axis and Y-Axis. Below is the picture. However if Zooming type zoomType = 'X' no issues. The problem is faced when including zoomType = 'y'
Below is the Code:
import React from 'react';
import highcharts from 'highcharts/highstock';
export default class Chart extends React.Component {
constructor (props) {
super(props);
this.state = {
chartName: `chart${this.props.chartNum}`
};
}
componentDidMount () {
let chartOptions = {};
chartOptions = {
rangeSelector: {enabled: false },
credits: { enabled: false },
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y:.2f}</b> <br/>'
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
plotOptions:{
series:{
turboThreshold:5000//set it to a larger threshold, it is by default to 1000,
}
},
xAxis:{
type: 'dateTime',
minRange:3600000,
events:{
setExtremes:function(event){
this.min=event.min;
this.max=event.max;
}
}
},
yAxis: {
offset: 15,
labels: {
align: 'center',
x: -5,
y: 0
},
opposite:false,
showLastLabel: true,
min: this.dataMin,
max: this.dataMax,
events:{
setExtremes:function(events){
console.log("Card::YAxis::setExtremes::events.min and events.max = " + events.min +", "+ events.max);
this.dataMin = events.min;
this.dataMax = events.Max;
this.min = events.min;
this.max = events.max;
}
},
tickPositioner: function () {
var positions;
var Maxdata = this.max;
var MinData = this.min;
if(ticksData != null){
positions = ticksData;
}else{
positions = [];
var tick = Math.floor(this.min);
if(this.min == this.max){
positions.push(this.min);
}else{
if (this.max !== null && this.min !== null) {
Maxdata = Maxdata.toFixed(2);
MinData = MinData.toFixed(2);
tick = parseFloat(MinData);
var increment = (Maxdata - MinData)/5;
increment=increment.toFixed(2);
for (tick; tick-increment<= Maxdata; tick=(parseFloat(increment)+parseFloat(tick)).toFixed(2)) {
if(positions.includes(tick)){
break;
}
else{
positions.push(tick);
}
}
}else{
positions = [0];
}
}
}
return positions;
}
}
};
chartOptions.chart = {
renderTo: document.getElementById(this.state.chartName),
zoomType: 'xy',
spacingBottom: 35,
resetZoomButton: {
position: {
align: 'right', // by default
verticalAlign: 'bottom', // by default
x: 8,
y: 20
}
},
events:{
redraw: function(){
var serie1 = this.series[0],
yExtremes = this.yAxis[0].getExtremes();
var yMin = yExtremes.min;
var yMax = yExtremes.max;
var dataSet = serie1.data;
var zoomedDataSet= [];
var dataGroup;
if(dataSet != undefined && dataSet != null){
for(var i=0; i<dataSet.length; i++)
{
if(dataSet[i] != undefined){
dataGroup = dataSet[i];
if(dataGroup[1] > yMin && dataGroup[1]< yMax){
zoomedDataSet.push(dataGroup);
}
}
}
serie1.data = zoomedDataSet;
}
}
}
};
// Generate chart.
this.generateChart(this.props.data, chartOptions);
}
componentWillUpdate (nextProps) {
let chartOptions = {};
chartOptions = {
rangeSelector: {enabled: false },
credits: { enabled: false },
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y:.2f}</b> <br/>'
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
plotOptions:{
series:{
turboThreshold:5000//set it to a larger threshold, it is by default to 1000,
}
},
xAxis:{
type: 'dateTime',
minRange:3600000,
events:{
setExtremes:function(event){
this.min=event.min;
this.max=event.max;
}
}
},
yAxis: {
offset: 15,
labels: {
align: 'center',
x: -5,
y: 0
},
opposite:false,
showLastLabel: true,
min: this.dataMin,
max: this.dataMax,
events:{
setExtremes:function(events){
console.log("Card::YAxis::setExtremes::events.min and events.max = " + events.min +", "+ events.max);
this.dataMin = events.min;
this.dataMax = events.Max;
this.min = events.min;
this.max = events.max;
}
},
tickPositioner: function () {
var positions;
var Maxdata = this.max;
var MinData = this.min;
if(ticksData != null){
positions = ticksData;
}else{
positions = [];
var tick = Math.floor(this.min);
if(this.min == this.max){
positions.push(this.min);
}else{
if (this.max !== null && this.min !== null) {
Maxdata = Maxdata.toFixed(2);
MinData = MinData.toFixed(2);
tick = parseFloat(MinData);
var increment = (Maxdata - MinData)/5;
increment=increment.toFixed(2);
for (tick; tick-increment<= Maxdata; tick=(parseFloat(increment)+parseFloat(tick)).toFixed(2)) {
if(positions.includes(tick)){
break;
}
else{
positions.push(tick);
}
}
}else{
positions = [0];
}
}
}
return positions;
}
}
};
chartOptions.chart = {
renderTo: document.getElementById(this.state.chartName),
zoomType: 'xy',
spacingBottom:35,
resetZoomButton: {
position: {
align: 'right', // by default
verticalAlign: 'bottom', // by default
x: 8,
y: 20
}
},
events:{
redraw: function(){
var serie1 = this.series[0],
yExtremes = this.yAxis[0].getExtremes(),
var yMin = yExtremes.min;
var yMax = yExtremes.max;
var dataSet = serie1.data;
var zoomedDataSet= [];
if(dataSet != undefined && dataSet != null ){
for(var i=0; i<dataSet.length; i++)
{
if(dataSet[i] != undefined){
dataGroup = dataSet[i];
if(dataGroup[1] >= yMin && dataGroup[1]<=yMax && dataGroup[0] >= xMin && dataGroup[0]<= xMax){
zoomedDataSet.push(dataGroup);
}
}
}
serie1.data = zoomedDataSet;
}
}
}
};
this.generateChart(nextProps.data, chartOptions);
}
generateChart (data, chartOptions) {
chartOptions.series = [
{
name: this.props.title,
type: this.props.status ? 'area' : 'line',
data: data,
clip: false
}
];
let chart = new highcharts.StockChart(chartOptions);
}
render () {
const selfStyle = {
height: '200px'
};
return (
<div
className="med-chart col-md-9"
id={this.state.chartName}
style={selfStyle}>
</div>
);
}
}
I have setExtremes set with event Min and Max values for Y-Axis, but it does not help. If any of you have faced a similar issue, request to share your approach to resolve this problem. Greatly appreciate your time in reading the post and your valuable inputs in advance.

HightCharts Realtime line error

HightCharts realtime line error
Who had the following problems?
var loadChart = function () {
$.getJSON('data.json', function (json) {
var index = 0;
var getData = function (index, type) {
var result = null;
if (type != undefined) {
result = parseInt(json[index][type]);
} else {
result = json[index];
}
return result;
};
var getSeriesData = function () {
// 结构
var JJData = [],
PCData = [],
PhoneData = [],
item;
var time = (new Date()).getTime();
for (var i = -179; i <= 0; ++i) {
item = json[index++];
JJData.push({
x: time + i * 2000,
y: parseInt(item.JJ)
});
PCData.push({
x: time + i * 2000,
y: parseInt(item.PC)
});
PhoneData.push({
x: time + i * 2000,
y: parseInt(item.Phone)
});
}
var result = [{
name: "JJ",
data: JJData
}, {
name: "PC",
data: PCData
}, {
name: "Phone",
data: PhoneData
}];
return result;
};
chart = new Highcharts.Chart({
chart: {
renderTo: 'container1',
type: 'spline', //spline
backgroundColor: 'rgba(202, 202, 202, 0.2)',
animation: Highcharts.svg, // don't animate in old IE
//marginRight: 10,
events: {
load: function () {
var series = this.series;
loadMinuteData = function () {
if (!minuteFlag) {
clearInterval(setMinuteInter);
return false;
}
var x = (new Date()).getTime(); // current time
var result = getData(index++);
// 第三个参数为true,移除最开始的数据
//console.log("minute");
//console.log(series[0]);
//alert(series[0]);
series[0].addPoint([x, parseInt(result.JJ)], true, true);
series[1].addPoint([x, parseInt(result.PC)], true, true);
series[2].addPoint([x, parseInt(result.Phone)], true, true);
};
var setMinuteInter = setInterval(loadMinuteData, 2000);
}
}
},
title: {
text: '实时在线人数'
},
xAxis: [{
type: 'datetime',
tickPixelInterval: 60
}],
yAxis: {
title: {
text: '人数'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
plotOptions: {
spline: {
marker: {
enabled: false
}
}
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: true
},
exporting: {
enabled: false
},
series: getSeriesData()
});
});
}

After print chart another chart is not visible in page

I am using two instance of high chart(Highcharts.JS v4.1.6) parallel, but when i tried to print the chart using export functionality, another chart gets invisible when print command gets completed.
Chart configuration:
var chart1, chart2;
var options, options2;
options = {
title: {
text: '',
floating: true,
align: 'left',
width: 610,
style: {
fontSize: '1.4em'
}
},
chart: {
renderTo: 'content1',
type: 'bar',
marginLeft: 210,
marginTop: 80,
spacingBottom: 15,
spacingLeft: 10,
spacingRight: 10
},
credits: {
enabled: false
},
credits: {
text: 'Source: xxxx',
href: '',
position: {
align: 'right',
x: -30,
y: -3
}
},
exporting: {
buttons: {
contextButton: {
align: 'right',
x: 2,
y: 10,
text: 'Download',
verticalAlign: 'top'
}
}
},
xAxis: {
categories: [],
labels: {
step: 1,
enabled: true,
formatter: function() {
var text = this.value,
formatted = text.length > 25 ? text.substring(0, 30) : text;
return '<div class="js-ellipse" style="width:150px; overflow:hidden" title="' + text + '">' + formatted + '</div>';
},
style: {
fontSize: '12px'
}
}
},
yAxis: {
max: 100,
plotLines: [{
color: 'black',
dashStyle: 'Solid',
value: 0,
width: 2
}, {
color: 'black',
width: 2,
value: 50
}
],
title: {
text: ''
},
},
legend: {
itemStyle: {
color: '#000000',
fontWeight: ''
},
layout: 'horizontal',
align: 'center',
x: 1,
verticalAlign: 'top',
y: 35,
floating: true,
backgroundColor: '#FFFFFF',
reversed: true
},
tooltip: {
style: {
padding: 30
},
formatter: function() {
return '' +
'<strong>' + this.x + '</strong><br>' + this.series.name + ': ' + Highcharts.numberFormat(this.y, 1) + "%";
}
},
plotOptions: {
series: {
grouping: true,
pointPadding: 0,
borderWidth: 0,
dataLabels: {
enabled: true,
crop: false,
formatter: function() {
return this.y.toFixed(1);
}
}
}
},
series: [],
}
options2 = {
title: {
text: ''
},
chart: {
renderTo: 'content2',
type: 'bar',
spacingBottom: 15,
spacingLeft: 10,
spacingRight: 10,
marginTop: 80
},
credits: {
text: 'Source: xxx',
href: '',
position: {
align: 'right',
x: -30,
y: -3
}
},
exporting: {
buttons: {
contextButton: {
align: 'right',
x: 2,
y: 10,
text: 'Download',
verticalAlign: 'top'
}
}
},
xAxis: {
categories: [],
labels: {
enabled: false,
step: 1,
overflow: 'justify',
crop: false,
formatter: function() {
var text = this.value,
formatted = text.length > 25 ? text.substring(0, 30) : text;
return '<div class="js-ellipse" style="width:150px; overflow:hidden" title="' + text + '">' + formatted + '</div>';
},
style: {
fontSize: '12px'
}
}
},
yAxis: {
plotLines: [{
color: 'black',
dashStyle: 'Solid',
value: 0,
width: 2
}],
title: {
text: ''
},
},
legend: {
itemStyle: {
color: '#000000',
fontWeight: ''
},
layout: 'horizontal',
align: 'center',
x: 1,
verticalAlign: 'top',
y: 35,
floating: true,
backgroundColor: '#FFFFFF',
reversed: true
},
tooltip: {
style: {
padding: 30
},
formatter: function() {
return '' +
'<strong>' + this.x + '</strong><br>' + this.series.name + ': ' + Highcharts.numberFormat(this.y, 1) + "%";
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
crop: false,
formatter: function() {
return this.y.toFixed(1);
}
}
}
},
series: [],
}
Before Print chart:
After Print when left side chart export print button used:
After Print when right side chart export print button used:
This will happen when print chart is used otherwise it work well.I couldn't figure out the issue.Please help me.
Thanks.
I have refer the below code that resolved my issue.
var beforePrint = function()
{
chart1 = jQuery('#content1').highcharts();
chartWidth1 = chart1.chartWidth;
chartHeight1 = chart1.chartHeight;
chart1.setSize(578,chartHeight1, false);
chart2 = jQuery('#content2').highcharts();
chartWidth2 = chart2.chartWidth;
chartHeight2 = chart2.chartHeight;
chart2.setSize(405,chartHeight2, false);
};
var afterPrint = function() {
chart1.setSize(chartWidth1,chartHeight1, false);
chart1.hasUserSize = null; // This makes chart responsive
chart2.setSize(chartWidth2,chartHeight2, false);
chart2.hasUserSize = null; // This makes chart responsive
};
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function(mql) {
if (mql.matches) {
beforePrint();
} else {
afterPrint();
}
});
}
window.onbeforeprint = beforePrint;
window.onafterprint = afterPrint;

Why I get "Uncaught SyntaxError: Unexpected token ILLEGAL"?

Could someone help me please?
I've tried to move js code from view to separate js file, but I got many errors like this: Uncaught SyntaxError: Unexpected token ILLEGAL. Why it happened?
My js code for high charts:
var chart;
var monthCategories = #{Date::ABBR_MONTHNAMES[1..12].inspect};
var monthNames = #{Date::MONTHNAMES.to_json}
var currentView = '#{#current_view}';
var currentMonth = #{#current_month};
var CURRENT_YEAR = #{Date.current.year};
var currentYear = #{#current_year};
var currentIndex = #{#current_index};
var currentInterval = '#{#current_interval}';
var seriesColors = #{{ "Applicants" => status_color(20), "Inquiries" => status_color(10), 'Conversion Rate' => '#7FC315', 'RSVPs'=> '#937CB0'}.to_json}
var registrantsData = #{#registrants_data.to_json};
var applicantsData = #{#applicants_data.to_json};
var pendingData = #{#pending_data.to_json};
var toursData = #{#tours_data.to_json};
var conversionData = #{#conversion_data.to_json};
var toursRequestedCount = #{#tours_requested.count}
$(document).ready(function() {
getDataForView = function() {
if (currentView == 'Applicants') { return applicantsData; }
if (currentView == 'Inquiries') { return registrantsData; }
if (currentView == 'Conversion Rate') { return conversionData; }
if (currentView == 'RSVPs') { return toursData; }
}
getSeriesColor = function() {
return seriesColors[currentView];
}
changeChartMonth = function(increase) {
if (increase && currentIndex < 23) { currentIndex = currentIndex + 1 }
if (!increase && currentIndex > 1) { currentIndex = currentIndex - 1 }
switchChartSeries();
}
selectedYear = function() {
year = currentIndex < 12 ? CURRENT_YEAR - 1 : CURRENT_YEAR;
return year;
}
updateTextIndication = function() {
var text = '';
$('.nav-arrow').hide();
if (currentInterval == 'days') {
text = monthNames[currentIndex % 12 + 1] + ' ';
if (currentIndex > 1) { $('.left-nav-arrow').show(); }
if (currentIndex < 23) { $('.rigth-nav-arrow').show(); }
$('.year').hide();
year = selectedYear();
text = text + year;
$('strong.current_chart_date').text(text);
$('span.current_chart_view').text(currentView + ' for:');
$('strong.current_chart_date').show();
} else {
$('strong.current_chart_date').hide();
$('.left-nav-arrow').hide();
$('.rigth-nav-arrow').hide();
$('.year').show();
}
$('.chart_interval a').removeClass('active');
$('.chart_interval a.' + currentInterval).addClass('active');
}
setYear = function(year) {
if (year == CURRENT_YEAR) {
currentIndex = 12;
} else {
currentIndex = 11;
}
$('a.year').removeClass("active_year");
$("a[year="+year+"]").addClass("active_year");
}
switchChartSeries = function() {
var dataSource = getDataForView();
var seriesType = 'column';
var categories;
data = dataSource[currentIndex];
if (currentInterval == 'months') {
categories = monthCategories;
temp = [];
for (var i=0; i<dataSource.length; i++) {
if (dataSource[i].drilldown.year == selectedYear()) {
temp.push(dataSource[i]);
}
}
dataSource = temp;
}
if (currentInterval == 'days') {
categories = data.drilldown.categories;
dataSource = data.drilldown.data;
}
updateTextIndication();
updateNavTabs();
chart.xAxis[0].setCategories(categories);
while(chart.series.length > 0)
chart.series[0].remove(true);
if (currentView == 'Conversion Rate') {
seriesType = 'area';
chart.yAxis[0].setExtremes(0, 100);
} else {
seriesType = 'column'
var maxVal = 0
if (currentInterval == 'days') {
maxVal = Math.max.apply(Math, dataSource)
} else {
for (var i = 0; i < dataSource.length; i++) {
if (dataSource[i].y > maxVal) {
maxVal = dataSource[i].y
}
}
}
if (maxVal < 3) {
chart.yAxis[0].setExtremes(0, 3)
} else {
chart.yAxis[0].setExtremes(0, null)
}
}
chart.addSeries({
name: currentView,
type: seriesType,
data: dataSource,
color: getSeriesColor(),
borderRadiusTopLeft: 3,
borderRadiusTopRight: 3,
marker: {
symbol: 'circle',
fillColor: 'white',
lineColor: '#7FC315',
lineWidth: 3
},
// fillColor: '#7FC315',
// fillOpacity: 0.9,
lineWidth: 1
});
}
updateNavTabs = function() {
var display = function ($target, count) {
var dataKey = ((count <= 0) ? "zero" : (count <= 1) ? "one" : "many");
var title = $target.closest("li").data(dataKey)
$target.text(count);
$target.closest("a").text(" " + title).prepend($target);
}
display($('strong.applicants'), calculateNumber(applicantsData));
display($('strong.registrants'), calculateNumber(registrantsData));
$('strong.conversion').text(calculateConversation(conversionData) + '%');
}
getDataSource = function(data) {
var dataSource = [];
if (currentInterval == 'days') {
dataSource = data[currentIndex].drilldown.data;
} else {
for (var i=0; i<data.length; i++) {
if (data[i].drilldown.year == selectedYear()) {
dataSource = dataSource.concat(data[i].drilldown.data);
}
}
}
return dataSource;
}
calculateNumber = function(data) {
var dataSource = getDataSource(data);
var number = 0;
for (var i=0; i<dataSource.length; i++) {
number += dataSource[i];
}
return number;
}
calculateConversation = function(data) {
var dataSource = getDataSource(data);
var number = 0;
var length = 0;
for (var i=0; i<dataSource.length; i++) {
if (dataSource[i] != 0) {
number += dataSource[i];
length ++;
}
}
if (length != 0)
number = (number/length).toFixed(0);
return number;
}
chart = new Highcharts.Chart({
chart: {
renderTo: 'pipeline',
type: 'column',
spacingTop: 10
},
credits: {
enabled: false
},
title: {
text: null
},
legend: {
enabled: false
},
xAxis: {
categories: #{(1..Time::days_in_month(Date.current.month)).map{ |d| d }.inspect }
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: null
}
},
tooltip: {
shadow: true,
useHTML: true,
formatter: function() {
var title;
if (currentInterval == 'months') {
titleInside = '<b>' + monthNames[monthCategories.indexOf(this.x) + 1] +'</b><br/>'
} else {
titleInside = '<b>' + monthNames[currentIndex % 12 + 1] + ' ' + this.x +'</b><br/>'
}
title = '<div class="highChartsTooltip">'+ titleInside + this.series.name + ': ' + Math.round(this.y) + '</div>'
if (currentView == 'Conversion Rate') {
title = '<div class="highChartsTooltip">'+ titleInside + this.series.name + ': ' + Math.round(this.y) + '%' + '</div>'
}
return title
}
},
plotOptions: {
area: {
fillOpacity: 0.05,
point: {
events: {
click: function() {
chartPointClick(this)
}
}
}
},
column: {
cursor: 'pointer',
point: {
events: {
click: function() {
chartPointClick(this)
}
}
}
}
},
series: []
});
chartPointClick = function(sender) {
var drilldown = sender.drilldown;
if (drilldown) {
currentInterval = 'days';
if (currentIndex < 12) {
currentIndex = drilldown.month - 1;
} else {
currentIndex = 12 + drilldown.month - 1;
}
switchChartSeries();
} else {
var start_date = new Date(selectedYear(), currentIndex % 12, sender.x + 1);
var end_date = new Date(selectedYear(), currentIndex % 12, sender.x + 2);
var url = '#{admin_students_path}'
if( currentView == "Inquiries" ){
var search_type = 'created';
var status_scope = 'inquiries_students';
} else{
var search_type = 'submitted';
var status_scope = 'applied_students';
}
var params = encodeURI('display_all=true&default=') + status_scope + encodeURI('&result_type=and&search[') + search_type + encodeURI('_at_gteq]=') + $.datepicker.formatDate('yy-mm-dd', start_date) + '&' +
encodeURI('search[') + search_type + encodeURI('_at_lteq]=') + $.datepicker.formatDate('yy-mm-dd', end_date);
document.location.href = url + '?' + params
}
}
switchChartInterval = function(sender, interval) {
$('.chart_interval a').removeClass('active')
sender.addClass('active');
currentInterval = interval;
if (interval == 'months') {
year = selectedYear();
setYear(year);
}
switchChartSeries();
}
$('.boxes li').click(function() {
var $this = $(this);
var proposedView = $this.data('view');
if (currentView != proposedView) {
currentView = proposedView;
if (currentView == 'RSVPs') {
$('#pipeline').hide()
$('#rsvps').show()
$('.months-filter').hide()
} else {
$('#rsvps').hide()
$('#pipeline').show()
$('.months-filter').show()
switchChartSeries();
}
$('.boxes li').removeClass('active');
$this.addClass('active');
}
return false;
})
$('.boxes li[data-view="' + currentView + '"]').addClass('active');
$('#programs').change(function() {
var program = $(this);
$.ajax({
url: "#{admin_dashboard_change_program_path}",
data: {
program_id: program.val(),
current_view: currentView,
current_month: currentIndex % 12 + 1,
current_year: selectedYear(),
current_interval: currentInterval
},
beforeSend: function() {
program.hide();
$('#programs_spinner').show();
},
complete: function() {
switchChartSeries();
if($('.boxes li.active').data('view') === 'RSVPs'){
$('#pipeline').hide()
$('#rsvps').show()
$('.months-filter').hide()
}
}
})
})
switchChartSeries();
});
Thank a lot for help guys!
The #{...} in here
var monthCategories = #{Date::ABBR_MONTHNAMES[1..12].inspect};
is ruby code: it will only work in ruby. it's not valid javascript on it's own: when it runs through the erb interpreter it will generate (hopefully) valid js.
You can do it in a js.erb file for example (or an html.erb file for that matter) because the .erb file is evaluated in ruby. But you can't do it in a plain js file.

Resources