Flot Graph not rendering properly in firefox - javascript

I am using Flot Graphs and they are plotting fine. But in firefox v33, on redrawing multiple times black rectangles are appearing. My options:
var lineChartOptions = {
series : {
lines : {
show : true
},
points : {
show : true
},
shadowSize : 3
},
grid : {
hoverable : true //IMPORTANT! this is needed for tooltip to work
},
yaxis : {
tickDecimals : 0,
min : 0,
max : 100
},
xaxes : [ {
mode : "time",
timeformat : "%d/%m/%y"
}],
tooltip : true,
tooltipOpts : {
content : "%y activations on %x",
shifts : {
x : -60,
y : 25
}
}
};
On Ajax call:
var axes = plotObj.getAxes();
axes.yaxis.options.max = null;
plotObj.setData(graph_json);
plotObj.setupGrid();
plotObj.draw();
It replicates when Y-Axis value goes from a lower to higher value. For the following set of data on three ajax calls in the order mentioned:
[{"data":[["2014-11-02",5],["2014-11-03",2],["2014-11-04",2]],"label":"Skype","color":8}]
[{"data":[["2014-10-01",0],["2014-10-31",0]],"label":"Skype","color":8}]
[{"data":[["2014-09-03",1],["2014-11-02",5],["2014-11-03",2],["2014-11-04",2]],"label":"Skype","color":8}]

This occured due to follpwing line:
axes.yaxis.options.max = null;
I tried using this as a workaround to make flot calculate the new maximum for Y-Axis itself after setting it in the options. But it seems to cause rendering issues

Related

How do I set a bar chart to default to a suggested maximum in chart.js v1.01?

I'm using Chart.js v1.0.1-beta.3. I'm creating an interactive bar chart where users can click on a bar to increase the value of that bar.
By default, the histogram begins with empty values. The y-axis in that case defaults to a [0,1] scale. When users start adding data to the histogram, the y-axis maximum changes to adjust, which causes a jarring shift in the appearance of the graph at low values.
I'd like to have the y-axis default to, say, a [0,10] scale even when no data is entered. This StackOverflow question is the most relevant info I can find on how to address problems like this; the best solution on that page is to use the 'suggestedMax' parameter in the chart options:
scales: {
yAxes: [{
ticks: {
suggestedMax : 10
}
}]
},
although this might apply only to v2+ of the library, it's hard to tell. In any event, this doesn't work, and the y-axis defaults to [1,0] when there's no data. I've also tried every combination of every other suggestion on that page, including
using scaleOverride : true, display : true, setting explicit min and max parameters within 'ticks', scaleBeginsAtZero : true, beginAtZero : true, and scaleStartValue : 0,
If I try to upgrade to the most current release, v2.7.3, the charts don't appear on the rendered page at all. I don't have the time or inclination to debug what's happening there, so I'm stuck with v1.0.1.
How do I have a bar chart default to a suggested maximum in this version? Is it even possible?
Looking through the documentation included with v1.0.1 (zip file), there doesn't appear to be a way to do this. I can't see any option to set the scale values.
In v2.7.3 this is quite simple. A working example is below. The chart starts empty, with a y-axis scale from 0-10. Clicking 'Add Series' adds a new bar with a value of 5. Clicking a bar increments value by 1.
let btn1 = document.getElementById('add'),
canvas = document.getElementById('chart'),
chart = new Chart(canvas, {
type: 'bar',
data: {
labels: [],
datasets: []
},
options: {
scales: {
yAxes: [{
ticks: {
min: 0,
suggestedMax: 10
}
}]
}
}
});
canvas.addEventListener('click', function(e) {
let idx = chart.getDatasetAtEvent(e)[0]._datasetIndex;
chart.config.data.datasets[idx].data[0]++;
chart.update();
});
btn1.addEventListener('click', function() {
chart.config.data.datasets.push({
data: [5]
});
chart.update();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<button id="add">Add Series</button> Click a bar to increment its value by 1.
<canvas id="chart"></canvas>

Fill Chart js with $http.get() data

Trying to get some data off of a webservice and display it in a chart. I figured chart js would be a good means to do so. (actually using tc-angular-chartjs). The $http.get( ) call I am using to test is:
$http.get('http://myjson.com/1chr1').success(function(data2) {
data2.forEach(function(r) {
$scope.labels.push(r.name);
$scope.scores.push(r.score);
});
});
and here is the whole js file for just the doughnut chart:
'use strict';
angular
.module( 'app.doughnut', [] )
.controller( 'DoughnutCtrl', function ( $scope ) {
$scope.labels = [];
$scope.scores = [];
$scope.data = [
{
value: 700,
color:'#F7464A',
highlight: '#FF5A5E',
label: 'Red'
},
{
value: 50,
color: '#46BFBD',
highlight: '#5AD3D1',
label: 'Green'
},
{
value: 100,
color: '#FDB45C',
highlight: '#FFC870',
label: 'Yellow'
}
];
$scope.options = {
// Sets the chart to be responsive
responsive: true,
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : true,
//String - The colour of each segment stroke
segmentStrokeColor : '#fff',
//Number - The width of each segment stroke
segmentStrokeWidth : 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout : 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect
animationEasing : 'easeOutBounce',
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false,
//String - A legend template
legendTemplate : '<ul class="tc-chart-js-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
};
});
The issue I am running into is that most of these examples use the same format to supply the chart with data (static data with the same labels like value/label/color/highlight).
For my needs the colors or highlight dont really matter but I need the data pulled from a wesbervice where the value I need for the chart is called name and the label for the chart is called score.
So I was thinking I could do the $http.get( ) call and put the labels and scores into 2 different arrays and then the data portion in the js would look something like:
$scope.data = {
labels : ["option 1","option 2","option 3"],
values : [ 10, 20, 30 ],
datasets: [ value : values, color : #F7484A, highlight : #FF5A5E, label : labels]
};
I saw something like this done for a Chart.js bar graph, but not for a doughnut graph, and I cannot seem to get it to work. Maybe it isnt possible?
Are there any other alternatives? I mean I cannot be the only person who needs to display dynamic data into a nice responsive chart, but all of the examples use static data.
EDIT ANSWER I took dubhov's advice. Also found out my webservice link was messed up so I wasnt getting any data :p. Here is the new js for future reference:
'use strict';
angular
.module('app.doughnut', [])
.controller('DoughnutCtrl', function($scope, $http) {
$http.get('https://api.myjson.com/bins/1chr1').success(function(data2) {
$scope.data = [];
data2.forEach(function(r) {
$scope.data.push({
'value': r.score,
'color': '#F7464A',
'highlight': '#FF5A5E',
'label': r.name
});
});
});
$scope.options = {
// Sets the chart to be responsive
responsive: true,
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke: true,
//String - The colour of each segment stroke
segmentStrokeColor: '#fff',
//Number - The width of each segment stroke
segmentStrokeWidth: 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout: 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect
animationEasing: 'easeOutBounce',
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false,
//String - A legend template
legendTemplate: '<ul class="tc-chart-js-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
};
});
Chart.js expects the data to be formatted like it is with the static examples. Can't you just add an object to the data array with the data you need? Like this:
$scope.data.push({'value':r.score,
'label':r.name,
'color':'#RANDOMCOLOR',
'highlight':'#SLIGHTLYSHADEDRANDOMCOLOR'});
As far as the colors, which may or may not be required by the API (I think they will be), you can either go random, or if you know that your dataset is limited, you can select from a static list of colors. Here's some ideas on randoms: https://stackoverflow.com/a/25709983/769971

How to redraw or repaint surface in ExtJS5?

I define a drawing panel and some components which are connected each other with SVG paths. I need to redraw connection paths on surface when moving components.
there is my drawing panel
{
xtype : 'panel',
flex : 5,
split : true,
region : 'center',
plain : true,
itemId : 'idCenterRegion',
id : 'centerRegion',
border : 1,
layout : {
type : 'fit',
},
defaults : {
autoScroll : true
},
listeners : {
afterrender : 'setDDTarget'
},
items: [{
xtype : 'draw',
itemId : 'idDrawPanel',
renderTo:Ext.getCmp('centerRegion'),
}]
}
The floating windows are adding to centerregion with draw/drop. there is another controller to draw sprites on surface,
printPath : function(drawItem) {
var source=drawItem.source;
var target=drawItem.target;
var surface = Ext.getCmp('centerRegion').down('draw')
.getSurface('main');
var color = "#000";
var line1,line2;
var posSource=[];
var posTarget=[];
if(source.left<target.left){
posSource[0]=source.left+source.width;
posTarget[0]=target.left;
line1=15;
line2=-15;
}else{
posSource[0]=source.left;
posTarget[0]=target.left+target.width;
line1=-15;
line2=15;
}
posSource[1]=source.top+source.height/2;
posTarget[1]=target.top+target.height/2;
var path = [ "M", posSource[0],
posSource[1], "H",
posSource[0] + line1, "L",
posTarget[0] + line2, posTarget[1], "H",
posTarget[0] ].join(",");
surface.add({
type : 'path',
path : path,
stroke : color,
fill : 'none',
'stroke-width' : 2,
surface : surface,
}).show(true);
},
When connecting any items on this panel it draws sprites but not showing on browser. but if I re-size drawing panel or browser window, sprites are shown,
I couldn't find any reason why its happening.
should I refresh view by using a different way?
That is the result before re-sizing screen, but add sprite method completed successfully.
This screenshot is after re-size height of center region, as you see, sprite is visible now. But any event didn't fire manually on re-size action.
I solved the problem,
It looks like a trick but draw container is working well now.
I called manually draw container's resizeHandler on draw container's 'add' listener.
It fires only one time when adding child windows on centerRegion (at first adding).
There is my solution below, firstly give an 'add listener reference to draw container:
{
xtype : 'draw',
itemId : 'idDrawPanel',
renderTo:Ext.getCmp('centerRegion'),
listeners : {
add: 'addToDrawPanel'
},
}
function:
addToDrawPanel:function( d, component, index, eOpts ){
var s=d.getSize();
var rh= d.getResizeHandler();
rh.call(d,s);
}

HighStocks - Adding 2 charts on same page

Using HighStocks.js, I tried to add 2 identical graph on the same html page.
My code look like this:
function createGraph(placeHolderId, uniqueName, series) {
$(placeHolderId).highcharts(uniqueName, {
rangeSelector : { selected : 1 },
series : series
});
}
And I call it 2 times:
createGraph('#marketdata', 'StockChart', series1);
createGraph('#returns', 'Returns', series1);
Even if series are the same, 'market data' get created then for the second I get the error:
TypeError: Highcharts[constr] is not a constructor
chart = new Highcharts[constr](options, args[1]);
on line 1041 of highstock.src.js.
Why is the second failing ?
the name of the chart needs to be 'StockChart' which is the type of the chart and not a variable name.
$(placeHolderId).highcharts('StockChart', {
rangeSelector : { selected : 1 },
series : series
});

Highcharts points not cleared out in firefox

I'm using highcharts to draw chart dynamically on mouse over a table row. What i want is to clear out the chart out and hide the chart on mouse out.
I works fine in chrome but i get this strange behavior in firefox : The chart points remains there. I don't know if i'm clear enough. You can see this on http://dev.bluesquare.org/dev/data.
If you mouse over table with the title "National Quantities" you'll see a chart appearing on mouse over and disappearing on mouse out but leaving some dots on the table.
Is there anybody who can give me an idea about this problem.
Here is part of the code i'm using
$(function(){
$('#district-quantity table tbody tr').hover(function(){
var row_data = //get some data corresponding to the hovered row
var chartDiv = 'chart_div';
drawQuantityChart(row_data,chartDiv);
},function(){});
}
function drawQuantityChart(row_data,chartDiv) {
//call a function to parse and format the data for highcharts
var chartData = parseData(row_data);
var chart = new Highcharts.Chart({
chart : {
renderTo : chartDiv,
type : 'line',
height : 360
},
title : {
text : null
},
subtitle : {
text : null
},
xAxis : {
categories : chartData.periods
},
yAxis : {
title : {
text : null
},
gridLineWidth : 1,
min: 0
},
tooltip: {
followPointer: true
},
series : chartData.series
});
}
});
$('#district-quantity table tbody tr').hover(function(){
var row_data = //get some data corresponding to the hovered row
var chartDiv = 'chart_div';
drawQuantityChart(row_data,chartDiv);
},function(){
chart.destroy();
// Why don't you destroy your chart here? Make sure your chart variable is global.
});
}

Categories

Resources