Bar chart looks bad before change data - javascript

Hi here I set the data to the bar chart:
setDatosBarra: function(data){ //
var self = this;
var horaEstim = 0;
var horaReal = 0;
var horaTotal = 0;
if(data[0].horas_estim != '-'){
horaEstim = data[0].horas_estim;
}
if(data[0].horas_real != '-'){
horaReal = data[0].horas_real;
}
if(data[0].total_horas != '-'){
horaTotal = data[0].total_horas;
}
var datosBarra =[{data: [[0,horaEstim]], color: "#691717"}, {data: [[1,horaReal]], color: "#173D69"},{data: [[2,horaTotal]], color: "#176469"}];
self.flotLinea(datosBarra);
},
When all is ready I send the data to self.flotBar;
This is the flotBar function:
flotBar: function(datos){
var self = this;
if(datos == 0){
var data = [["SIN REGISTROS",0]];
}else{
var data = datos;
}
function getTooltip(label, x, y) {
return "<strong style='font-size:18px;'> " + y + " </strong> horas";
}
var plot = $.plot("#placeholder",data, {
series: {
bars: {
show: true,
barWidth: 0.3,
align: "center",
lineWidth: 0,
fill:.75
}
},
xaxis: {
ticks: [[0,"Horas estimadas"],[1,"Horas reales"],[2,"Total horas"]],
mode: "categories",
tickLength: 0
},
grid: {
hoverable: true,
clickable: true
},
tooltip: true,
tooltipOpts : {
content : getTooltip,
defaultTheme : false
},
});
},
Ok , and this is my problem, example:
I select a option in an dropDown:
And the bar chart looks like this:
If I select other option in the dropDown:
The bar chart looks like this:
And if I select again the first option "Correcion de errores", the bar chart looks like this:
So.. always the first time that I show the bar chart looks like in the first image , with the numbers in the line, but If I select other option looks good.
I need see good the bar chart always and no just when I select other option.
I'm using flot javascript library.
How can I fix this? sorry by my english

The main issue with the question as stated is that we do not have all the code. In essence, you should either provide all the code, or shrink down the problem to something that shows the issue and then, well, provide all the code. As far as I can guess, you have some other code somewhere else that is drawing the initial chart. The second and subsequent times? Drawn properly. To support my assertion, notice that in your initial image the captions for the x-axis tick markers (ditto the bars themselves) are right aligned not centered.
For fun, I wrote a quick jsFiddle that showed how to switch datasets using a button (much as you want to do with the drop-down) and redraw the chart:
drawChart = function(index) {
var chartData = getDataForChart(rawData[index]);
if (chart) {
chart.setData(chartData);
chart.draw();
}
else {
chart = $.plot("#barchart", chartData, chartOptions);
}
},
switchDataset = function() {
datasetIndex = (datasetIndex + 1) % datasetCount;
drawChart(datasetIndex);
};
$("#switchButton").on("click", switchDataset);
Because I decided to load new data into the chart rather than redraw it all from scratch (to be honest I saw no real difference either way), it meant that I had to pre-calculate the maximum value for the y-axis:
calcValueMax = function() {
var max = 0;
rawData.forEach(function(values) {
values.forEach(function(value) {
if (value > max) {
max = value;
}
});
});
return max;
},
// other code
chartOptions.yaxis.max = calcValueMax();
Hope that helps.

Related

How to rotate first and last x-axis label in Highcharts chart?

I would like to rotate only firt and last label in x-axis.
I have following formatter function:
formatter() {
if (this.isFirst || this.isLast) {
// First or last label here
var rotatedValue = this.value.doRotation(); // TODO here
return rotatedValue;
} else {
return this.axis.defaultLabelFormatter.call(this);
}
},
I did a research but nothing found (how call some rotation function).
I use a basic line chart.
You can set xAxis.labels.useHTML option to true and style these labels via CSS3:
xAxis: {
labels: {
useHTML: true
}
},
chart: {
events: {
load: function() {
var div = this.xAxis[0].labelGroup.div;
div.firstChild.style.transform = "rotate(30deg)";
div.lastChild.style.transform = "rotate(30deg)";
}
}
}
Live working demo: http://jsfiddle.net/kkulig/fepj1f5g/
API reference: http://api.highcharts.com/highcharts/xAxis.labels.useHTML

Dygraph dynamic update legend values disappear

I am using a dygraph to monitor a CSV file and use the dynamic update function. When I hover over the graph to show the values of the curves in the legend, they disappear as soon as the graph is updated, which is a bit annoying.
<html>
<head>
<script type="text/javascript" src="/static/dygraph-combined.js"></script></head>
<body>
<div id="psu"></div>
<script type="text/javascript">
g = new Dygraph(document.getElementById("psu"), "/data/psu",
{
legend: 'always',
hideOverlayOnMouseOut: false,
ylabel: 'current (A)',
height: 480,
width: 640,
sigFigs: 2,
title: 'power interface monitor',
xValueFormatter: Dygraph.dateString_,
xAxisLabelFormatter: Dygraph.dateString_,
xTicker: Dygraph.dateTicker
} );
window.intervalId = setInterval(function(){g.updateOptions( { 'file': "/data/psu" } ); }, 1000);
</script>
</html>
So the graph is all displaying correctly and the data is updated, only the legend values disappear after the graph is refreshed with g.updateOptions(). I was thinking maybe I can re-trigger some kind of "mouseover" event after g.updateOptions() so the values come back, but there might be a cleaner way of doing it.
Thanks.
I found a solution to my problem, but I am not sure how well it is implemented. I share it here so others might find it:
$(document).ready(function() {
var data = [];
var t = new Date();
for (var i = 10; i >= 0; i--) {
var x = new Date(t.getTime() - i * 1000);
data.push([x, Math.random()]);
}
var last_mousemove_evt = null;
var on_graph = false;
var g = new Dygraph(document.getElementById("div_g"), data, {
legend: 'always',
drawPoints: true,
showRoller: true,
valueRange: [0.0, 1.2],
labels: ['Time', 'Random'],
highlightCallback: function(e, x, pts, row) {
last_mousemove_evt = e;
on_graph = true
},
unhighlightCallback: function(e) {
on_graph = false;
}
});
// It sucks that these things aren't objects, and we need to store state in window.
window.intervalId = setInterval(function() {
var x = new Date(); // current time
var y = Math.random();
data.push([x, y]);
g.updateOptions({
'file': data
});
if (on_graph) {
g.mouseMove_(last_mousemove_evt);
}
}, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/1.1.1/dygraph-combined.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<div id="div_g" style="width:600px; height:300px;"></div>
So I end up using the highlightCallback and unhighlightCallback options so I can figure out the mouse position and after a dynamic update call then the dygraph.mouseMove_() function to redraw the legend values. Seems to work.
Please let me know if there is a nicer solution around. Might be good to include this functionality in the dygraph.updateOptions() by default, as it seems weird that the legend values disappear after an update.

Hide x-axis label in chartsjs [duplicate]

I want to hide labels on x-axis as i have a solution to set
$scope.labels = ['', '', '', '', '', '', ''];
but in that case labels are also getting hidden on tooltip. What i want is to show labels on bars hover but i don't want to show those labels on x-axis. As it also disturbs my UX as well because charts width is too low.
I did spend too much time on this but couldn't find a solution to get rid of x-axis labels. Please help me here....
I think that's something you can do it with options setting in the latest versions of chartjs:
options: {
scales: {
xAxes: [
{
ticks: {
display: false
}
}
];
}
}
You can extend the chart to do this, like so
Chart.types.Bar.extend({
name: "BarAlt",
initialize: function(data){
Chart.types.Bar.prototype.initialize.apply(this, arguments);
var xLabels = this.scale.xLabels;
for (var i = 0; i < xLabels.length; i++)
xLabels[i] = '';
}
});
and call it like so
var myBarChart = new Chart(ctx).BarAlt(data);
Fiddle - http://jsfiddle.net/kq3utvnu/
Thanks #Samuele for pointing this out! For really long labels, you'll need to set the labels to something shorter and then set it back to the original ones (in the chart elements) so that no space is taken up below the x axis for the labels.
Chart.types.Bar.extend({
name: "BarAlt",
initialize: function(data){
var originalLabels = data.labels;
data.labels = data.labels.map(function() { return '' });
Chart.types.Bar.prototype.initialize.apply(this, arguments);
this.datasets[0].bars.forEach(function(bar, i) {
bar.label = originalLabels[i];
});
var xLabels = this.scale.xLabels;
for (var i = 0; i < xLabels.length; i++)
xLabels[i] = '';
}
});
Fiddle - http://jsfiddle.net/nkbevuoe/
I was able to hide labels on the x-axis, while keeping the title in the tooltip by doing the following:
In chart data: labels: [""]
In chart options, add object.label = "ToolTipTitle"; before the line specifying the values that should be returned

chart is not rendering properly, canvasjs

I'm trying to render two dynamic charts using canvasJS, Chart one is rendering properly, in fact second chart is populating properly, please see the inspect element image, but it's not displaying on the page.
This is interface, just one chart is displaying
and here is inspect elem.
#adverts is rendering, but not displayed here.
.chartContainer{
height: 400px;
width: 100%;
}
PS I tried to commented out first chart rendering code, but not working at all, still displaying the first one only.
EDIT
Here is console log about what I'm getting back to render chart
here is snippet
function drawChart(obj, placeholder, From, To){
var legendFrom;
var legendTo;
if(From != 'undefined'){
legendFrom = From;
}
if(To != 'undefined'){
legendTo = To;
}
var dataPoints = [];
var from = [];
var to = [];
var advertFrom = [];
var advertTo = [];
for (var i = 0; i <= obj.length - 1; i++) {
if(obj[i].typeOf != 'undefined' || obj[i].typeOf != ''){
if(obj[i].typeOf == 'from'){
from.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
advertFrom.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:obj[i].adverts});
}else{
to.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
advertTo.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:obj[i].adverts});
}
}
else
from.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
}
var chart = new CanvasJS.Chart("chartContainer",
{
animationEnabled: true,
//theme: "theme1",
zoomEnabled: true,
title:{
text: placeholder
},
data: [
{
type: "spline", //change type to bar, line, area, pie, etc
showInLegend: true,
legendText: "From "+legendFrom,
dataPoints: from
},
{
type: "spline",
showInLegend: true,
legendText: "From "+legendTo,
dataPoints: to
}
],
legend: {
cursor: "pointer",
itemclick: function (e) {
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}
});
chart.render();
var adverts = new CanvasJS.Chart("adverts",
{
animationEnabled: true,
zoomEnabled: true,
title:{
text: placeholder
},
data: [
{
type: "column", //change type to bar, line, area, pie, etc
showInLegend: true,
legendText: "From "+legendFrom,
dataPoints: advertFrom
},
{
type: "column",
showInLegend: true,
legendText: "From "+legendTo,
dataPoints: advertTo
}
]
});
adverts.render();
}
I just replicated a canvasJS enviroment in JSFiddle
http://jsfiddle.net/fLbngdv9/1/
Make sure you are are using a new VAR for each chart.
var chart = new CanvasJS.Chart("chartContainer", {..});
chart.render();
var chart2 = new CanvasJS.Chart("chartContainer2", {..});
chart2.render();
Seems to work fine. If you can provide me with some code examples then perhaps I can help you find an answer.
Probably just a copy paste mistake but you have a syntax error at the very bottom.
...
adverts.render();
}
This should be
...
adverts.render();
Just remove the extra bracket. I updated the JS Fiddle to be more like your example... [here]
Edit:
I was able to replicate in my latest JSFiddle and I know this sounds crazy but when I changed the ID of your second div from adverts to chartContainer2 it worked fine.
Still investigating as to why this is but I would try renaming the ID on the div and also the reference for the graphs creation.
SEE HERE
Edit 2:
This appears to be a Chrome specific bug with the ID adverts. To replicate all you need to do is check out this link http://www.briangebel.com/test.html
(As you can see the div Adverts is hidden in Chrome but visible on FF,Opera,IE)
So what is happening..
Chrome's ADBlocker extension sees this ID and automatically adds an in page stylesheet.
This style sheet has the following Style
This only affects Chrome as it is caused by a specific extension. (I am attempting to contact the developer to see if he can resolve this but until then follow the below solution)
Solution
Simple don't use that ID. (You could simply disable AdBlocker but this extension is so widely used I would still recommend changing the ID)

External variable in the title of the chart

I'm working in a school project and i'm getting the data from a php file to show in the gauge.
I using this javascript code to update de chart every second:
function requestData() {
$.getJSON('values.php', function(data) {
var new_value = data;
var point = $('#ta').highcharts().series[0].points[0];
point.update(new_value);
setTimeout(requestData, 500)
}
)
}
With this code i'm able to update the chart, the problem is, i need to show the numeric value too, in another part of the chart. Here is what i try:
yAxis: {
title: {
text: '<div id="tav">'+new_value+'V</div>',
useHTML: true,
y: 80
}
When i put "new_value" the chart stop working and i can't see nothing. If a leave the "new_value" from this part of the chart it works perfectly.
Can someone help me?
Thanks
To update y-axis title you have to use the code like:
$('#container').highcharts().yAxis[0].update({
title:{
text:"My text"
}
});
I have created a wroking demo of how to dynamically update y-axis title on button click: DEMO
JS code section to dynamically update chart title on a button click:
var chart = $('#container').highcharts();
$('#my_btn').click(function(){
//alert('hey');
chart.yAxis[0].update({
title:{
text:"My text"
}
});
alert('Y-axis title changed to "My text" !');
});
The problem is that new_value is localy defined. You could define the variable as an object's property:
var obj = {};
function requestData() {
$.getJSON('values.php', function(data) {
obj.new_value = data;
var point = $('#ta').highcharts().series[0].points[0];
point.update(new_value);
setTimeout(requestData, 500)
}
)
}
and
yAxis: {
title: {
text: '<div id="tav">'+obj.new_value+'V</div>',
useHTML: true,
y: 80
}
Use indeed Axis.setTitle() method, see:
function requestData() {
$.getJSON('values.php', function (data) {
var new_value = data;
var chart = $('#ta').highcharts()
var point = chart.series[0].points[0];
var yAxis = chart.yAxis[0];
yAxis.setTitle({text: new_value });
point.update(new_value);
setTimeout(requestData, 500);
})
}

Categories