Chartjs convert toBase64 not working in an iframe - image

I have a problem when i am trying to generate the Base64 of my chartjs line.
The console.log of my base64 string is : "data:," (attachment)
i am launching this code in an iframe, not in the parent page. On this chart, there are 30000 lines of data.
**When i directly launched the page, i have no problem, everything is OK.
**
Here is my code :
`
function generateTrend2(data){
var line = document.getElementById('chartContainer').getContext('2d')
var dataY = []
var dataX = []
data.forEach(function (item) {
dataY.push(item.y)
dataX.push(item.x)
})
var lineChart = new Chart(line, {
type: 'line',
data: {
labels: dataX,
datasets: [{
data: dataY,
label: "Sample Coverage",
borderColor: "#3e95cd",
fill: false,
borderWidth: 1
}]
},
options: {
animation: {
duration: 0,
},
hover: {
animationDuration: 0,
},
responsiveAnimationDuration: 0,
onAnimationComplete: done(),
elements: {
point:{
radius: 0
}
}
}
});
function done(){
setTimeout(function(){
var image = lineChart.toBase64Image();
console.log(image)
$("body").append("<input type='hidden' value='" + image + "' id='img-chart' >")
},1000)
}
}
`
I tried to put a delay of 200,500,1000,5000,10000, but the result is the same in my var image...
I have generated an other base64 with an other chart with similar code, the same system, in an iframe and i have no problem.

Related

Odd animation with multiple series

I was trying to adapt the spline animation for time series (https://www.highcharts.com/demo/dynamic-update) for multiple series.
I modified the example here https://jsfiddle.net/2wj3fquL/
Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series;
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.random();
series[0].addPoint([x, y], true, true);
y = Math.random();
series[1].addPoint([x, y], true, true);
}, 1000);
}
}
},
time: {
useUTC: false
},
title: {
text: 'Live random data'
},
accessibility: {
announceNewData: {
enabled: true,
minAnnounceInterval: 15000,
announcementFormatter: function (allSeries, newSeries, newPoint) {
if (newPoint) {
return 'New point added. Value: ' + newPoint.y;
}
return false;
}
}
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
headerFormat: '<b>{series.name}</b><br/>',
pointFormat: '{point.x:%Y-%m-%d %H:%M:%S}<br/>{point.y:.2f}'
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}, {
name: 'other data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}]
});
Unfortunately the effect is odd since one series moves smooth while the other doesn't ...
How could I solve this problem?
Thanks
That is because the chart is redrawn twice. Disable redraw in the first addPoint method call.
events: {
load: function() {
...
setInterval(function() {
...
series[0].addPoint([x, y], false, true);
series[1].addPoint([x, y], true, true);
}, 1000);
}
}
Live demo: https://jsfiddle.net/BlackLabel/0n2yw57m/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#addPoint

jVectorMap active marker on page load

i have custom colors for regions and custom images for marker icons. Hovering, clicking on markers changes everytjing like i want but... How to make one marker, marked after loading a map, i cant find solution. I've been trying to click the marker icon with jquery, finding by element attribute, the click worked (according to the console log), but nothing changed on the map.
https://jsfiddle.net/6ss2eahr/7/
$(document).ready(function () {
var markers = [
{ latLng: [54.5039433, 18.3233958], name: 'Gdynia', region: 'PL-PM' },
{ latLng: [51.7472675, 18.0070145], name: 'Kalisz', region: 'PL-WP' },
{ latLng: [50.2138079, 18.8671087], name: 'Katowice', region: 'PL-SL' },
{ latLng: [50.8541274, 20.5456014], name: 'Kielce', region: 'PL-SK' }
];
var last_poi;
$('#map-pl').vectorMap({
map: 'pl_merc',
backgroundColor: '#fff',
zoomButtons: false,
zoomOnScroll: false,
regionsSelectable: false,
regionsSelectableOne: true,
markersSelectable: true,
markersSelectableOne: true,
markers: markers,
markerStyle: {
initial: {
image: 'https://www.royalparks.org.uk/_media/images/map_icons/find-my-location-icon.png'
},
hover: {
image: 'http://tiltedkilt.com/wp-content/themes/base/library/images/pin-small-icon.png',
cursor: 'pointer'
},
selected: {
image: 'http://tiltedkilt.com/wp-content/themes/base/library/images/pin-small-icon.png'
},
selectedHover: {
image: 'http://tiltedkilt.com/wp-content/themes/base/library/images/pin-small-icon.png'
}
},
regionStyle: {
hover: { fill: '#fdefc9' },
initial: { stroke: "white", "stroke-width": 1, fill: "#fcf8ed" },
selected: { fill: "#ffcc39" }
},
onMarkerClick: function (event, id) {
var mapObject = $('#map-pl').vectorMap('get', 'mapObject');
mapObject.clearSelectedRegions();
mapObject.setSelectedRegions(markers[id].region);
last_poi = id;
},
onMarkerOver: function (event, id) {
var mapObject = $('#map-pl').vectorMap('get', 'mapObject');
mapObject.clearSelectedRegions();
if (last_poi) {
mapObject.setSelectedRegions(markers[last_poi].region);
}
mapObject.setSelectedRegions(markers[id].region);
},
onMarkerOut: function (event, id) {
var mapObject = $('#map-pl').vectorMap('get', 'mapObject');
mapObject.clearSelectedRegions();
if (last_poi) {
mapObject.setSelectedRegions(markers[last_poi].region);
}
},
onRegionTipShow: function (e, label, code) {
e.preventDefault();
}
});
});
All the functions getSelectedMarkers, setSelectedRegions, and so on can handle array of values, so the solution is pretty easy to dynamically select one or more Marker and the corresponding Region:
var mapObject = $('#map-pl').vectorMap('get', 'mapObject');
// select Gdynia by index
var selectedMarkers = [0],
selectedRegions = [];
selectedMarkers.forEach(function(item) {
selectedRegions.push(mapObject.markers[item].config.region);
});
mapObject.setSelectedMarkers(selectedMarkers);
mapObject.setSelectedRegions(selectedRegions);
Your can remove the whole logic to keep track of the marker index using last_poi, which is causing the deselection in onMarkerOut and replace with the above function to get the selected Region directly from the mapObject.

Transform too dense data

Trying to display line chart using plotly.js, my data are collected per second. I fed my graph but the result looks strange even if I zoom in, to very low detail where it should be displayed per seconds.
Are there any methods I could use to preprocess the data so it would display well in different scales (as I zoom in and out)?
var gd = document.getElementById('tester');
var layout = {
xaxis: {
showgrid: true,
tickformat: "%H:%M:%S",
},
margin: {
l: 40,
b: 40,
r: 30,
t: 20
},
hovermode: 'x',
};
var draw = function(data, layout) {
Plotly.newPlot(gd, data, layout, {
showLink: false,
displaylogo: false
});
};
var dataurl = 'https://gist.githubusercontent.com/fhurta/6c53839fbc91a363d62966a972a5e4a2/raw/2cd735f0b024e496164dacec92fa4a7abcd5da2e/series.csv';
Plotly.d3.csv(dataurl, function(rows) {
var data = [{
type: 'scatter',
x: rows.map(function(row) {
return new Date(row['Time']);
}),
y: rows.map(function(row) {
return row['Value1'];
}),
line: {
width: 1
}
}];
draw(data, layout);
});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="tester" style="width:600px;height:300px;"></div>

ZoomRange Highstock works not correct?

I made a Highstock diagramm and got aproblem with zooming on the yAxis.
I have a Button and 2 textfield to get the wanted min/max values for the axis. With min:0, max: 100 it works well. With min:0, max:80 it doesn't (max will still be 100 in the Diagramm).
If I use the mouse for zooming it works well (even a min of: 3.7 and a max of 3.894 is possible). But using the mouse is not an Option, because in the later Diagramm there will be 3 yAxes with individual zoom.
$(function () {
var seriesOptions = [],
seriesCounter = 0,
names = ['MSFT', 'AAPL', 'GOOG'];
/**
* Create the chart when all data is loaded
* #returns {undefined}
*/
function createChart() {
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 4
},
chart:{
zoomType: 'xy'
},
yAxis: [
{
labels: {
format: '{value}',
},
height: '100%',
opposite: false,
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
],
plotOptions: {
series: {
compare: 'percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2
},
series: seriesOptions
},
function(chart){
$('#btn').click(function(){
var min = temp_min.value,
max = temp_max.value;
chart.yAxis[0].setExtremes((min),(max));
});
});
}
$.each(names, function (i, name) {
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=' + name.toLowerCase() + '-c.json&callback=?', function (data) {
if(seriesCounter==0){
seriesOptions[i] = {
name: name,
data: data,
yAxis: 0
};
} else {
seriesOptions[i] = {
name: name,
data: data,
yAxis: 0
};
}
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter += 1;
if (seriesCounter === names.length) {
createChart();
}
});
});
});
JSFiddle
Another Question: Is it possible to set up a scrollbar for the yAxis as well?
Thanks for your help, Patrick
This is related with fact that tickInterval is not regular, so is rounded to value (like 100). The solution is using tickPositioner which calculates ticks, based on extremes which you define.
tickPositioner: function (min,max) {
var positions = [],
tick = Math.floor(min),
increment = Math.ceil((max - min) / 5);
for (tick; tick - increment <= max; tick += increment) {
positions.push(tick);
}
return positions;
},
http://jsfiddle.net/6s11kcwd/
The scrollbar is supported only for xAxis.

Extjs4 drag and drop zones error with IE,FF and Safari

I have multiple grids in a panel. The base grids have data in them and can be dragged and dropped between each other. All the grids in the panel should be able to drag and drop between each other. This works perfectly in chrome but not Firefox, IE, or Safari.
In IE,FF and Safari the grids with data in them will drag and drop between each other w/o problem. They will not between the empty grids. I tried adding data to the empty grids but that wasn't the problem. Firebug also errors when using it with Extjs so any bugs i get are from a different dev tool. I have reinstalled all of those browsers and that is not the answer either. Im stuck...
edit I found out in chrome the viewconfig for my dragdrop groups are set but it doesnt set in the other browsers
This is my base grid with data in it.
var rround = "panel-game-"+round;
var ss = Ext.create('Ext.grid.Panel', {
stateful: true,
id: "panel-game-"+round,
stateId: 'stateGrid',
autoScroll: false,
store: store,
columns: [
{
text : 'Teams',
flex : 1,
sortable : true,
dataIndex: 'team_name'
}
],
height: 100,
width: 150,
title: 'Game ' + round,
viewConfig: {
stripeRows: true,
plugins: {
ptype: 'gridviewdragdrop',
dragGroup: [groups],
dropGroup: [groups]
},
listeners: {
drop: function(node, data, dropRec, dropPosition,record,store) {
var dropOn = dropRec ? ' ' + dropPosition + ' ' + dropRec.get('name') : ' on empty view';
var data = this.store.data.items;
var sdata = new Array();
data.each(function(e){
var bleh = {team_id: e.data.team_id, team_name:e.data.team_name};
sdata.push(bleh);
})
removeDupe(sdata,this.store);
}
}
}
});
This is my empty grid that should accept drops and should also drag when there is data in it.
var rCell = Ext.create('Ext.grid.Panel', {
stateful: true,
id: "panel-game-"+i+'-'+a,
stateId: 'stateGrid',
autoScroll: false,
store: rCellStore,
columns: [
{
text : 'Teams',
flex : 1,
sortable : true,
dataIndex: 'team_name'
}
],
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragGroup: [groups],
dropGroup: [groups]
},
listeners: {
beforedrop: function(node,data,overModel,dropPosition,eOpts){
console.log(node);
},
drop: function(node, data, dropRec, dropPosition, record) {
console.log("drop");
var dropOn = dropRec ? ' ' + dropPosition + ' ' + dropRec.get('title') : ' on empty view';
var f = node.id.replace('-body','');
var newval = data.records[0].data;
if(f != undefined && f != ''){
var fstore = Ext.getCmp(f).getStore();
fstore.add(newval);
}
var data = this.store.data.items;
var sdata = new Array();
data.each(function(e){
var bleh = {team_id: e.data.team_id, team_name:e.data.team_name};
sdata.push(bleh);
})
removeDupe(sdata,this.store);
}
}
},
height: 100,
width: 150,
title: 'Game ',
viewConfig: {
stripeRows: true
}
});
It does not give a dropzone avaliable when i and trying to drag something over. It could be that but im not sure how to fix it.
The problem was the second viewConfig{stripeRows:true}. Chrome could figure it out but the other browsers were overwriting the first viewConfig with the second.

Resources