Customizing Chart.js tool tips - tooltip

<script>
var passings = [["New York","5001","05/18 00:36","S 28 MPH"], ["Phili","5002","05/18 01:36","S 50 MPH"], ["Richmond","5003","05/18 02:36","S 40 MPH"], ["Wilson","5004","05/18 03:36","S 30 MPH"],
["Savannah","5005","05/18 04:36","S 29 MPH"], ["Miami","5006","05/18 05:36","S 40 MPH"]]
leftK1 = ["20","30","50","20","30","40"]
var labelL1 = "Rain %";
var ctx = document.getElementById("myChart").getContext("2d");
var canvasWidth = 600;
ctx.canvas.width = canvasWidth;
ctx.canvas.height = 700;
Chart.defaults.global.defaultFontSize = 14;
Chart.defaults.global.defaultFontFamily = "Lato, sans-serif";
var chartData = null;
var chartOptions = null;
var chartDataSets = [ {
label : labelL1,
fill : false,
data : leftK1,
borderColor : 'rgb(255, 99, 132)'
} ];
chartData = {
labels : passings,
datasets : chartDataSets
}
chartOptions = {
responsive : true,
maintainAspectRatio : false,
elements : {
line : {
tension : 0, // disables bezier curves
}
},
animation : {
},
legend : {
display : true,
position : 'top',
labels : {
fontColor : 'rgb(255, 99, 132)'
}
},
title : {
display : true,
text : 'Passings Chart'
},
scales : {
yAxes : [ {
ticks : {
max : 80,
min : 0
},
gridLines : {
zeroLineWidth : 5
},
scaleLabel : {
display : true,
labelString : "Rain Percantage",
fontFamily : "Lato, sans-serif",
fontSize : 18
}
} ],
xAxes : [ {
ticks : {
autoSkip : false,
maxTicksLimit : 15,
maxRotation : 0,
minRotation : 0,
fontFamily : "Lato, sans-serif",
fontSize : 12
}
} ]
}
// end scales
}
window.myChart = new Chart(ctx, {
type : 'line',
data : chartData,
options : chartOptions
});
</script>
<h:form id="ChartForm">
<div >
<canvas id="myChart" ></canvas>
</div>
</h:form>
enter image description hereI have passed Labels as an array to the chart (Chart.js version 2.7) so that I have multiple rows of X-Axis Labels. While displaying as tool tip, it is displaying whole array for each tool tip. I have seen several postings where they gave ways to display values from legend and and customizing Y-axis data.
Is there a way to display a short form of Label (X-axis label) as tooltip ?

You can use Callbacks as it is mentioned in Chart.js Documentatoin
You can even customize your tooltips for example:
var myPieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
tooltips: {
// Disable the on-canvas tooltip
enabled: false,
custom: function(tooltipModel) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
// Create element on first render
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = "<table></table>";
document.body.appendChild(tooltipEl);
}
// Hide if no tooltip
if (tooltipModel.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set caret Position
tooltipEl.classList.remove('above', 'below', 'no-transform');
if (tooltipModel.yAlign) {
tooltipEl.classList.add(tooltipModel.yAlign);
} else {
tooltipEl.classList.add('no-transform');
}
function getBody(bodyItem) {
return bodyItem.lines;
}
// Set Text
if (tooltipModel.body) {
var titleLines = tooltipModel.title || [];
var bodyLines = tooltipModel.body.map(getBody);
var innerHtml = '<thead>';
titleLines.forEach(function(title) {
innerHtml += '<tr><th>' + title + '</th></tr>';
});
innerHtml += '</thead><tbody>';
bodyLines.forEach(function(body, i) {
var colors = tooltipModel.labelColors[i];
var style = 'background:' + colors.backgroundColor;
style += '; border-color:' + colors.borderColor;
style += '; border-width: 2px';
var span = '<span style="' + style + '"></span>';
innerHtml += '<tr><td>' + span + body + '</td></tr>';
});
innerHtml += '</tbody>';
var tableRoot = tooltipEl.querySelector('table');
tableRoot.innerHTML = innerHtml;
}
// `this` will be the overall tooltip
var position = this._chart.canvas.getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.position = 'absolute';
tooltipEl.style.left = position.left + tooltipModel.caretX + 'px';
tooltipEl.style.top = position.top + tooltipModel.caretY + 'px';
tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px';
tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;
tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px';
}
}
}
});
See the Samples
and more

Related

How to edit "highcharts-label-icon" in highcharts-gantt

Highchart gantt : https://www.highcharts.com/docs/gantt/getting-started-gantt
I want to change this dropdown btn icon to right of text label.
How to edit it?
Jsfiddle : https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/gantt/demo/project-management
This is not possible from the API but you can achieve that by wrapping the renderLabel function.
(function(H) {
const {
addEvent,
isNumber,
isObject,
pick
} = H,
onTickHoverExit = function(label, options) {
var css = isObject(options.style) ? options.style : {};
label.removeClass('highcharts-treegrid-node-active');
if (!label.renderer.styledMode) {
label.css({
textDecoration: css.textDecoration
});
}
},
onTickHover = function(label) {
label.addClass('highcharts-treegrid-node-active');
if (!label.renderer.styledMode) {
label.css({
textDecoration: 'underline'
});
}
},
renderLabelIcon = function(tick, params) {
var treeGrid = tick.treeGrid,
isNew = !treeGrid.labelIcon,
renderer = params.renderer,
labelBox = params.xy,
options = params.options,
width = options.width || 0,
height = options.height || 0,
iconCenter = {
x: labelBox.x + tick.label.getBBox().width + width,
y: labelBox.y - (height / 2)
},
rotation = params.collapsed ? 90 : 180,
shouldRender = params.show && isNumber(iconCenter.y);
var icon = treeGrid.labelIcon;
if (!icon) {
treeGrid.labelIcon = icon = renderer
.path(renderer.symbols['circle'](options.x || 0, options.y || 0, width, height))
.addClass('highcharts-label-icon')
.add(params.group);
}
// Set the new position, and show or hide
icon[shouldRender ? 'show' : 'hide'](); // #14904, #1338
// Presentational attributes
if (!renderer.styledMode) {
icon
.attr({
cursor: 'pointer',
'fill': pick(params.color, "#666666" /* Palette.neutralColor60 */ ),
'stroke-width': 1,
stroke: options.lineColor,
strokeWidth: options.lineWidth || 0
});
}
// Update the icon positions
icon[isNew ? 'attr' : 'animate']({
translateX: iconCenter.x,
translateY: iconCenter.y,
rotation: rotation
});
};
H.wrap(H.Tick.prototype, 'renderLabel', function(proceed) {
var tick = this,
pos = tick.pos,
axis = tick.axis,
label = tick.label,
mapOfPosToGridNode = axis.treeGrid.mapOfPosToGridNode,
options = axis.options,
labelOptions = pick(tick.options && tick.options.labels, options && options.labels),
symbolOptions = (labelOptions && isObject(labelOptions.symbol, true) ?
labelOptions.symbol : {}),
node = mapOfPosToGridNode && mapOfPosToGridNode[pos],
level = node && node.depth,
isTreeGrid = options.type === 'treegrid',
shouldRender = axis.tickPositions.indexOf(pos) > -1,
prefixClassName = 'highcharts-treegrid-node-',
styledMode = axis.chart.styledMode;
var collapsed,
addClassName,
removeClassName;
if (isTreeGrid && node) {
// Add class name for hierarchical styling.
if (label &&
label.element) {
label.addClass(prefixClassName + 'level-' + level);
}
}
proceed.apply(tick, Array.prototype.slice.call(arguments, 1));
if (isTreeGrid &&
label &&
label.element &&
node &&
node.descendants &&
node.descendants > 0) {
collapsed = axis.treeGrid.isCollapsed(node);
renderLabelIcon(tick, {
color: (!styledMode &&
label.styles &&
label.styles.color ||
''),
collapsed: collapsed,
group: label.parentGroup,
options: symbolOptions,
renderer: label.renderer,
show: shouldRender,
xy: label.xy
});
// Add class name for the node.
addClassName = prefixClassName +
(collapsed ? 'collapsed' : 'expanded');
removeClassName = prefixClassName +
(collapsed ? 'expanded' : 'collapsed');
label
.addClass(addClassName)
.removeClass(removeClassName);
if (!styledMode) {
label.css({
cursor: 'pointer'
});
}
// Add events to both label text and icon
[label, tick.treeGrid.labelIcon].forEach(function(object) {
if (object && !object.attachedTreeGridEvents) {
// On hover
addEvent(object.element, 'mouseover', function() {
onTickHover(label);
});
// On hover out
addEvent(object.element, 'mouseout', function() {
onTickHoverExit(label, labelOptions);
});
addEvent(object.element, 'click', function() {
tick.treeGrid.toggleCollapse();
});
object.attachedTreeGridEvents = true;
}
});
}
});
}(Highcharts))
Demo:
https://jsfiddle.net/BlackLabel/k2rb6zgy/
Extending Highcharts:
https://www.highcharts.com/docs/extending-highcharts/extending-highcharts

adding a title to marker on map in mapbox also would like to give the marker a name in firebase

(function() {
'use strict';
//
// Utilities
//
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
function now() {
return Math.floor(Date.now() / 1000);
}
//
// Environment
//
var myUuid;
var mapId;
mapId = location.hash.replace(/^#/, '');
if (!mapId) {
mapId = (Math.random() + 1).toString(36).substring(2, 12);
location.hash = mapId;
}
if (typeof localStorage == 'undefined') {
document.getElementById('map').innerHTML = 'Sorry but your browser is not supported'
return
}
myUuid = localStorage.getItem('myUuid');
if (!myUuid) {
myUuid = guid();
localStorage.setItem('myUuid', myUuid);
}
//
// Mapbox
//
var map;
var markers = {};
var mapZooming = false;
L.mapbox.accessToken = config.mapbox.accessToken;
map = L.mapbox.map('map', config.mapbox.mapId, {
zoomControl: false,
attributionControl: false,
tileLayer: {
maxNativeZoom: 19
}
}).setView([48.861920, 2.341755], 18)
// map.on('ready', function() { console.log('map.ready') });
// https://github.com/bbecquet/Leaflet.PolylineDecorator
L.RotatedMarker = L.Marker.extend({
options: { angle: 0 },
_setPos: function(pos) {
L.Marker.prototype._setPos.call(this, pos);
if (L.DomUtil.TRANSFORM) {
// use the CSS transform rule if available
this._icon.style[L.DomUtil.TRANSFORM] += ' rotate(' + this.options.angle + 'deg)';
} else if (L.Browser.ie) {
// fallback for IE6, IE7, IE8
var rad = this.options.angle * L.LatLng.DEG_TO_RAD,
costheta = Math.cos(rad),
sintheta = Math.sin(rad);
this._icon.style.filter += ' progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' +
costheta + ', M12=' + (-sintheta) + ', M21=' + sintheta + ', M22=' + costheta + ')';
}
}
});
L.rotatedMarker = function(pos, options) {
return new L.RotatedMarker(pos, options);
};
map.on('zoomstart', function() {
mapZooming = true
})
map.on('zoomend', function() {
mapZooming = false
})
function createIcon(uuid, point) {
var color
var svg;
if (uuid === myUuid) {
// Own marker
color = '#2196f3'
} else if (point.timestamp < now() - 60) {
// Inactive marker
color = '#bdbdbd'
} else {
// Others marker
color = '#ff9800'
}
var svg = '<svg width="70" height="70" xmlns="http://www.w3.org/2000/svg">'
+ '<path fill="#fff" d="m35,18.000002c-9.400002,0 -17,7.599995 -17,16.999998s7.599998,17 17,17s17,-7.599998 17,-17s-7.599998,-16.999998 -17,-16.999998zm0,30.999998c-7.700001,0 -14,-6.299999 -14,-14s6.299999,-13.999998 14,-13.999998s14,6.299997 14,13.999998s-6.300003,14 -14,14z"/>'
+ '<circle fill="' + color + '" stroke="null" r="14.031405" cy="35.000002" cx="34.999999"/>'
+ (point.orientation ? '<polygon fill="' + color + '" points="47.699997901916504,16.983383178710938 47.000000953674316,17.68338394165039 35.000000953674316,12.7833890914917 23.00000286102295,17.68338394165039 22.300002098083496,16.983383178710938 35.000000953674316,4.28338623046875" />' : '')
+ '</svg>'
return L.icon({
iconUrl: 'data:image/svg+xml;base64,' + btoa(svg),
iconSize: [40, 40],
})
}
I found this code on Github and im trying to set a name to the marker but I am having trouble doing so can some one point me in the right direction I would like to display a name when you hover over the marker.
function addPoint(uuid, point) {
var marker = L.rotatedMarker([point.coords.latitude, point.coords.longitude], {
//zIndexOffset: (uuid === myUuid ? 1000 : 0),
icon: createIcon(uuid, point)
})
markers[uuid] = marker;
marker.options.angle = point.orientation;
marker.addTo(map)
map.fitBounds(Object.keys(markers).map(function(uuid) {
return markers[uuid].getLatLng()
}))
}
function removePoint(uuid) {
if (markers[uuid]) {
map.removeLayer(markers[uuid])
//markers[uuid] = null
}
}
function updatePoint(uuid, point) {
// Avoid clipping effect when zooming map + updating point at the same time.
if (mapZooming) {
map.once('zoomend', function() {
updatePoint(uuid, point)
})
return
}
var marker = markers[uuid]
marker.setIcon(createIcon(uuid, point));
marker.options.angle = point.orientation
marker.setLatLng([point.coords.latitude, point.coords.longitude])
}
function putPoint(uuid, point) {
if (markers[uuid]) {
updatePoint(uuid, point)
} else {
addPoint(uuid, point)
}
}
In Fire Base instead of some random number and letters I would like to give the markers names
//
// Firebase
//
var endpoint;
endpoint = new Firebase('https://' + config.firebase + '.firebaseio.com/maps/' + mapId);
endpoint.on('child_added', function(childSnapshot) {
var uuid = childSnapshot.key()
var point = childSnapshot.val()
if (uuid === myUuid) return
addPoint(uuid, point)
})
endpoint.on('child_changed', function(childSnapshot) {
var uuid = childSnapshot.key()
var point = childSnapshot.val()
if (uuid === myUuid) return
putPoint(uuid, point)
})
endpoint.on('child_removed', function(oldChildSnapshot) {
var uuid = oldChildSnapshot.key()
removePoint(uuid)
})
//
// Tracking
//
var watchPositionId;
var currentCoords = null;
var currentOrientation = null;
function pushCurrentStatus() {
if (!currentCoords) return
endpoint.child(myUuid).set({
coords: {
latitude: currentCoords.latitude,
longitude: currentCoords.longitude,
},
orientation: currentOrientation,
timestamp: now()
})
}
pushCurrentStatus = _.throttle(pushCurrentStatus, 50)
if (navigator.geolocation) {
setTimeout(function() {
watchPositionId = navigator.geolocation.watchPosition(
successWatchPosition,
failWatchPosition,
{enableHighAccuracy: false}
)
}, 0)
setTimeout(function() {
navigator.geolocation.clearWatch(watchPositionId)
watchPositionId = navigator.geolocation.watchPosition(
successWatchPosition,
failWatchPosition,
{enableHighAccuracy: true}
)
}, 5000)
}
function successWatchPosition(position) {
if (!position.coords) return
currentCoords = position.coords
pushCurrentStatus()
putPoint(myUuid, {coords: currentCoords, orientation: currentOrientation})
}
function failWatchPosition() {
alert('Fail to get your location')
}
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', deviceOrientationHandler, true)
}
function deviceOrientationHandler(event) {
var alpha;
if (event.webkitCompassHeading) {
alpha = event.webkitCompassHeading;
} else {
alpha = event.alpha;
}
if (!alpha) return
currentOrientation = 360 - alpha
pushCurrentStatus()
putPoint(myUuid, {coords: currentCoords, orientation: currentOrientation})
}
//
// Remove old markers
//
setInterval(function() {
endpoint.limitToFirst(100).once('value', function(snap) {
var now = Math.floor(Date.now() / 1000)
snap.forEach(function(childSnapshot) {
var uuid = childSnapshot.key()
var point = childSnapshot.val()
if (uuid === myUuid) return
if (childSnapshot.val().timestamp < now - 60 * 30) {
endpoint.child(uuid).set(null)
} else {
updatePoint(uuid, point)
}
})
})
}, 5000);
})();

Titanium - Changing orientation between windows

I'm developing an application for ipad and iphone using Titanium. You can navigate between different views. 1st view (the main view where you can go to another views) will be only on portrait mode, the rest of views can be in any orientation.
For this, I use different windows:
var winPortrait = Ti.UI.createWindow({
orientationModes : [Ti.UI.PORTRAIT],
fullscreen : false,
navBarHidden : true,
backgroundColor : "#00669c",
});
var appWindow = Titanium.UI.createWindow({
width : Ti.UI.FILL,
height : Ti.UI.FILL,
fullscreen : false,
navBarHidden : true,
backgroundColor : "#00669c",
backgroundImage : "Default-Portrait.png",
orientationModes : [Ti.UI.PORTRAIT, Ti.UI.LANDSCAPE_LEFT, Ti.UI.LANDSCAPE_RIGHT]
});
This works ok. When I open each window, orientation changes works ok.
To explain my problem, I'm going to specify the steps I do to reproduce it.
I'm viewing a screen on landscape:
I click to go to main view (portrait only) with device in landscape.
Main view is shown in portrait mode.
I rotate the device to portrait.
I go to the view again with device in portrait:
If I change device orientation, I receive the orientation change event, app detects is landscape mode and draw elements like landscape, but window or view (I don't know) its drawing like portrait, so it doesn't adjust correctly:
This doesn't occur on ios 7, but when I've tried with ios 5.1, it happens (I doesn't have a device with ios 6.x to try it)
Do you know how can I solve it or is a SO problem?
Thank you very much.
UPDATE
This is a simplification of the code I use:
In app.js:
var appWindow = Titanium.UI.createWindow({
width : Ti.UI.FILL,
height : Ti.UI.FILL,
fullscreen : false,
navBarHidden : true,
backgroundColor : "#00669c",
backgroundImage : "Default-Portrait.png",
orientationModes : [Ti.UI.PORTRAIT, Ti.UI.LANDSCAPE_LEFT, Ti.UI.LANDSCAPE_RIGHT]
});
var winPortrait = Ti.UI.createWindow({
orientationModes : [Ti.UI.PORTRAIT],
fullscreen : false,
navBarHidden : true,
backgroundColor : "#00669c",
});
var openView = function(e) {
currentView = e.win;
if (winPortraitHomeOpened && e.win != 'Home') {
appWindow.backgroundImage = '';
appWindow.addEventListener('open', function() {
//alert("appwindowopen")
if (appWindow != null) {
appWindow.height = Ti.UI.FILL;
appWindow.width = Ti.UI.FILL;
}
});
appWindow.open();
}
// Dependiendo de la vista, abre una ventana u otra
if (e.win == 'Home') {
winPortrait.open();
winPortraitHomeOpened = true;
setTimeout(function() {
var Home = require('/views/Home2');
activeView = Home.Constructor(winPortrait);
addActiveViewCloseWin();
}, 10);
} else if (e.win == 'test') {
var Test = require('/views/test/test');
activeView = Test.Constructor(appWindow, true);
}
if (currentView != 'Home') {
addActiveViewCloseWin();
}
};
var addActiveViewCloseWin = function() {
var anim_invisible = Titanium.UI.createAnimation({
opacity : 0,
duration : 300
});
var anim_visible = Titanium.UI.createAnimation({
opacity : 1,
duration : 300
});
if (winPortraitHomeOpened && currentView == 'Home') {
winPortrait.add(activeView);
} else {
appWindow.add(activeView);
}
if (lastActiveView != null) {
Trace.info("lastActiveView != null");
lastActiveView.animate(anim_invisible);
setTimeout(function() {
activeView.animate(anim_visible);
lastActiveView.close();
lastActiveView = activeView;
}, 300);
} else {
activeView.animate(anim_visible);
lastActiveView = activeView;
}
activeView.updateOrientation();
setTimeout(function() {
if (currentView == 'Home') {
appWindow.close();
} else {
if (winPortraitHomeOpened) {
winPortrait.close();
winPortraitHomeOpened = false;
}
}
}, 500);
};
Ti.Gesture.addEventListener('orientationchange', function(e) {
// Comprobar que ha cambiado de orientación. Se envían varios eventos juntos
var _currentOrientacion = 0;
if (utils.isLandscape())
_currentOrientacion = 1;
if (_currentOrientacion == orientacion) {
return;
}
orientacion = _currentOrientacion;
// Se actualiza las dimensiones y la orientación de los elementos
if (!winPortraitHomeOpened && !winPortraitConfOpened) {
if (appWindow != null) {
appWindow.height = Ti.UI.FILL;
appWindow.width = Ti.UI.FILL;
}
}
if (activeView != null) {
activeView.updateOrientation();
}
});
The code of Test.js:
exports.Constructor = function(parent) {
var view = Ti.UI.createView({
height : utils.getScreenHeight(),
width : utils.getScreenWidth(),
backgroundColor : 'red'
});
var cabeceraView = Cabecera.Constructor(view);
view.add(cabeceraView);
cabeceraView.setTitle('Prueba');
var backButton = Ti.UI.createImageView({
image : utils.imagesFolder() + "common/returnHome.png",
//top : view.height / 4,
left : utils.todp(8),
height : utils.todp(25),
width : utils.todp(65)
});
view.add(backButton);
backButton.addEventListener('click', function() {
openView({
win : 'Home'
});
});
var updateFechaCabecera = function() {
fechaView.setFecha('XXXX-XX-XX');
};
view.updateFechaCabecera = updateFechaCabecera;
var fechaView = Fecha.Constructor(view);
view.add(fechaView);
updateFechaCabecera();
// Vista ocupa todo salvo cabecera y fecha
var mainView = Ti.UI.createView({
height : utils.getScreenHeight() - utils.getCabeceraHeight() - utils.getFechaHeight(),
width : '100%',
top : utils.getCabeceraHeight() + utils.getFechaHeight(),
backgroundColor : "transparent",
});
view.add(mainView);
// Create a Label.
var aLabel = Ti.UI.createLabel({
text : 'aLabel',
color : 'pink',
font : {
fontSize : 40
},
textAlign : 'center'
});
// Add to the parent view.
mainView.add(aLabel);
var updateOrientation = function() {
Trace.info("updateOrientation de interconexines height width " + utils.getScreenHeight() + ' ' + utils.getScreenWidth());
view.height = utils.getScreenHeight();
view.width = utils.getScreenWidth();
if (utils.isPortrait()) {
aLabel.text = "PORTRAIT";
} else {
aLabel.text = "LANDSCAPE";
}
};
view.updateOrientation = updateOrientation;
var cerrar = function() {
Trace.info('cerrar Template');
view.visible = false;
view.hide();
if (cabeceraView != null) {
cabeceraView.close();
view.remove(cabeceraView);
cabeceraView = null;
}
if (fechaView != null) {
fechaView.close();
view.remove(fechaView);
fechaView = null;
}
// Eliminamos los elementos de la vista
if (view != null) {
utils.removeChildrens(view);
parent.remove(view);
};
view = null;
};
view.close = cerrar;
return view;
};
Have you tried to remove orientationModes in var winPortrait?
Your code should look like this:
var winPortrait = Ti.UI.createWindow({
fullscreen : false,
navBarHidden : true,
backgroundColor : "#00669c",
});

how to get the series name, id and title value dynamically from highcharts?

JSFiddle Link for the charts
if (chart.length == 3) {
for ( var i = 0; i < chart.length; i++) {
chart[i].renderer
.image('http://highcharts.com/demo/gfx/sun.png',chart[i].chartWidth - 40, 5, 20, 20)
.add()
.css({'cursor' : 'pointer'})
.attr({'title' : 'Charts'})
.on('click', function() {
alert("hi");console.log(chart[i]);
//var chartValue = $('#'+id).highcharts();
//var series = chartValue.series[1];
//console.log(series.name + "...hi" +series.title);
});
}
}
How can we get the charts details on click event?

How to setup Flot for iOS retina display

I have tested this on an iPad (3 generation). The line chart appears perfectly smooth.
http://justindarc.github.com/flot.touch/example/index.html
I have tried diffing the code with my flot code and cannot see any significant difference that would cause it to run in retina mode. My flot is version 0.7, same as his code. No matter what I try my own chart runs in non-retina mode.
What is the trick in running retina mode?
My setup code is rather long.
function setup_chart0(setup_options) {
var point_data = [];
if(setup_options.use_sample_data_for_chart0) {
point_data = generate_dummy_data(
setup_options.timestamp_generate_min,
setup_options.timestamp_generate_max
);
}
var average_data = henderson23(point_data);
var datasets = make_chart0_datasets(point_data, average_data);
if(is_dualaxis_detail_mode) {
datasets = make_chart0_dual_datasets(
[],
[],
[],
[]
);
}
var options = default_plot_options();
options.xaxis.min = setup_options.timestamp_visible_min;
options.xaxis.max = setup_options.timestamp_visible_max;
options.xaxis.panRange = [setup_options.timestamp_pan_min, setup_options.timestamp_pan_max];
options.yaxis.min = -0.025;
options.yaxis.max = 1.025;
options.yaxis.panRange = [-0.025, 1.025];
options.legend = { container: '#legend0', noColumns: 2 };
options.grid.markings = compute_markings_with_alertlevels;
if(is_dualaxis_detail_mode) {
options.y2axis = {};
options.y2axis.position = "right";
options.y2axis.min = -0.025;
options.y2axis.max = 1.025;
options.y2axis.panRange = [-0.025, 1.025];
options.legend = { container: '#legend_hidden', noColumns: 2 };
}
//save_as_file({ samples: point_data, average: average_data });
var el_placeholder0 = $("#placeholder0");
if(el_placeholder0.length){
//console.log('plotting chart 0');
var fade = false;
var el = el_placeholder0;
var el_outer = $("#placeholder0_outer");
var original_offset = el_outer.offset();
if(fade) {
el_outer.offset({ top: -5000, left: 0 }); // move plot container off screen
}
chart0 = $.plot(el, datasets, options);
if(fade) {
el.hide(); // hide plot - must do *after* creation
el_outer.offset(original_offset); // put plot back where it belongs
el.fadeIn('slow'); // fade in
}
/*var s = ' width: ' + chart0.width() + ' height: ' + chart0.height();
$('#label0').append(s);*/
if(solo_pan_mode) {
el.bind('plotpan', function (event, plot) {
set_data_should_redraw_chart0 = true;
set_data_should_redraw_chart1 = false;
set_data_should_redraw_chart2 = false;
fetch_data_for_chart(chart0, setup_options.timestamp);
show_loading_empty('#loader1');
show_loading_empty('#loader2');
});
el.bind('plotpanend', function (event, plot) {
set_data_should_redraw_chart0 = true;
set_data_should_redraw_chart1 = true;
set_data_should_redraw_chart2 = true;
copy_min_max(chart0, chart1, '#placeholder1');
copy_min_max(chart0, chart2, '#placeholder2');
hack_hide_loading_wheels = true;
maybe_hide_loading_wheels();
});
} else {
el.bind('plotpan', function (event, plot) {
fetch_data_for_chart(chart0, setup_options.timestamp);
sync_with_chart0();
});
}
}
}
I have modified jquery.flot.js like this:
In the top I have added
retinaMode = (window.devicePixelRatio > 1),
I have extended these functions
function makeCanvas(skipPositioning, cls) {
var c = document.createElement('canvas');
c.className = cls;
c.width = canvasWidth;
c.height = canvasHeight;
if (!skipPositioning)
$(c).css({ position: 'absolute', left: 0, top: 0 });
$(c).appendTo(placeholder);
if(retinaMode) {
c.width = canvasWidth * 2;
c.height = canvasHeight * 2;
c.style.width = '' + canvasWidth + 'px';
c.style.height = '' + canvasHeight + 'px';
}
if (!c.getContext) // excanvas hack
c = window.G_vmlCanvasManager.initElement(c);
// used for resetting in case we get replotted
c.getContext("2d").save();
if (retinaMode) {
c.getContext("2d").scale(2,2);
}
return c;
}
function getCanvasDimensions() {
canvasWidth = placeholder.width();
canvasHeight = placeholder.height();
if (canvasWidth <= 0 || canvasHeight <= 0)
throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
}
function resizeCanvas(c) {
// resizing should reset the state (excanvas seems to be
// buggy though)
if (c.width != canvasWidth) {
c.width = canvasWidth;
if(retinaMode) {
c.width = canvasWidth * 2;
}
c.style.width = '' + canvasWidth + 'px';
}
if (c.height != canvasHeight) {
c.height = canvasHeight;
if(retinaMode) {
c.height = canvasHeight * 2;
}
c.style.height = '' + canvasHeight + 'px';
}
// so try to get back to the initial state (even if it's
// gone now, this should be safe according to the spec)
var cctx = c.getContext("2d");
cctx.restore();
// and save again
cctx.save();
if(retinaMode) {
cctx.scale(2, 2);
}
}

Resources