I have two functions. FunctionToChangeBarChart and getPreviousDayValues. I want to draw jqPlot barchart in each function. So i wrote code for drawing bar chart in a fuction LoadBarChart and called this function both FunctionToChangeBarChart and getPreviousDayValues functoins. The problem is that the bar chart redraws, one over another, in each function call.
how can i refresh the bar chart?
FunctionToChangeBarChart = function(event){
var totalNoUsers = 10;
var tempStart = 4;
var pendingTaskCount = 7;
var completedTaskCount = 2;
LoadBarChart(totalNoUsers,tempStart,pendingTaskCount,completedTaskCount);
});
getPreviousDayValues = function(Event){
var totalUsers = 20;
var tempStart = 4;
var pendingTaskCount = 9;
var completedTaskCount = 3;
LoadBarChart(totalUsers,tempStart,pendingTaskCount,completedTaskCount);
}
function LoadBarChart(total,start,pending,complete,todayVal){
var s1 = [total, start, pending, complete];
var ticks = ['total', 'started', 'pending','completed' ];
plot1 = $.jqplot('chart1', [s1], {
animate: !$.jqplot.use_excanvas,
seriesDefaults:{
renderer:$.jqplot.BarRenderer,
rendererOptions: {barMargin: 0 , varyBarColor : true},
pointLabels: { show: true }
},
title:{text:"Task Status and Users"},
grid: {
background: 'transparent', // CSS color spec for background color of grid.
drawBorder:false,
drawGridlines:false,
shadow:false
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks,
tickOptions : {
// showGridline : false
}
},
yaxis: {
tickOptions : {
// showGridline : false
},
// label:'Status',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
}
},
seriesColors: [ "#000", "#ccc", "red","green"],
highlighter: { show: false }
});
$('#chart1').bind('jqplotDataClick',
function (ev, seriesIndex, pointIndex, data) {$('#info1').html('series: '+seriesIndex+', point: '+pointIndex+', data: '+data);
});
}
Related
I recently came across this really nice example: https://jsfiddle.net/BlackLabel/7t59w4po/
Basically, what it does is that it synchronizes the drag of a line in one graph in all the other graphs.
I was wondering if someone could help me out to reproduce the same example, but instead of one vertical line, I would like to have two. Is this possible?
Thank you!
JS Code:
/*
The purpose of this demo is to demonstrate how multiple charts on the same page
can be linked through DOM and Highcharts events and API methods. It takes a
standard Highcharts config with a small variation for each data set, and a
mouse/touch event handler to bind the charts together.
*/
/**
* In order to synchronize tooltips and crosshairs, override the
* built-in events with handlers defined on the parent element.
*/
['mousemove', 'touchmove', 'touchstart'].forEach(function(eventType) {
document.getElementById('container').addEventListener(
eventType,
function(e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
// Find coordinates within the chart
event = chart.pointer.normalize(e);
// Get the hovered point
point = chart.series[0].searchPoint(event, true);
if (point) {
point.highlight(e);
}
}
}
);
});
/**
* Override the reset function, we don't need to hide the tooltips and
* crosshairs.
*/
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
/**
* Highlight a point by showing tooltip, setting hover state and draw crosshair
*/
Highcharts.Point.prototype.highlight = function(event) {
event = this.series.chart.pointer.normalize(event);
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
/**
* Synchronize zooming through the setExtremes event handler.
*/
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function(chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(
e.min,
e.max,
undefined,
false, {
trigger: 'syncExtremes'
}
);
}
}
});
}
}
/**
* Synchronize annotations drag&drop
*/
function syncAnnotations(e) {
var thisChart = this.chart;
var newX = this.options.shapes[0].points[0].x
if (e.type !== 'afterUpdate') {
Highcharts.each(Highcharts.charts, function(chart) {
if (chart !== thisChart) {
chart.annotations[0].update({
labels: [{
point: {
x: newX
}
}],
shapes: [{
points: [{
x: newX,
xAxis: 0,
y: 0
}, {
x: newX,
xAxis: 0,
y: 1000
}]
}]
});
}
});
}
}
// Get the data. The contents of the data file can be viewed at
Highcharts.ajax({
url: 'https://cdn.jsdelivr.net/gh/highcharts/highcharts#v7.0.0/samples/data/activity.json',
dataType: 'text',
success: function(activity) {
activity = JSON.parse(activity);
activity.datasets.forEach(function(dataset, i) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function(val, j) {
return [activity.xData[j], val];
});
var chartDiv = document.createElement('div');
chartDiv.className = 'chart';
document.getElementById('container').appendChild(chartDiv);
Highcharts.chart(chartDiv, {
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
crosshair: true,
events: {
setExtremes: syncExtremes
},
labels: {
format: '{value} km'
}
},
yAxis: {
title: {
text: null
}
},
annotations: [{
draggable: 'x',
animation: {
defer: false
},
events: {
drag: syncAnnotations,
afterUpdate: syncAnnotations
},
shapes: [{
strokeWidth: 3,
type: 'path',
points: [{
x: 3,
y: 0,
xAxis: 0
}, {
x: 3,
y: 1000,
xAxis: 0
}]
}],
labels: [{
point: {
x: 3,
y: 30,
xAxis: 0
},
shape: 'rect',
formatter: function(e) {
// Use shape options because value is available there. Label use translation only
return this.target.annotation.shapes[0].options.points[0].x.toFixed(3);
}
}]
}],
tooltip: {
positioner: function() {
return {
// right aligned
x: this.chart.chartWidth - this.label.width,
y: 10 // align to title
};
},
borderWidth: 0,
backgroundColor: 'none',
pointFormat: '{point.y}',
headerFormat: '',
shadow: false,
style: {
fontSize: '18px'
},
valueDecimals: dataset.valueDecimals
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
fillOpacity: 0.3,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
}]
});
});
}
});
You only need to add another annotation:
annotations: [{
...,
{
...
}],
And improve the syncAnnotations function a little bit:
function syncAnnotations(e) {
var thisChart = this.chart;
var newX = this.options.shapes[0].points[0].x
var index = this.chart.annotations.indexOf(this);
if (e.type !== 'afterUpdate') {
Highcharts.each(Highcharts.charts, function(chart) {
if (chart !== thisChart) {
chart.annotations[index].update({
...
});
}
});
}
}
Live demo: https://jsfiddle.net/BlackLabel/jwtLc379/
API Reference: https://api.highcharts.com/highcharts/annotations
I'm using ChartJs library in my project and i was trying to show the tooltip of a pie chart both on slice hover or on legend hover, by default the library shows only tooltip on slice hover,
i was trying to do the following onHover function
onHover: function (event, legendItem) {
var index = legendItem.datasetIndex;
var label = this.chart.data.datasets[index].label
return label;
}
But the following function still had no effects..
The whole code of the chart config is the following:
optionsPagamenti = {
maintainAspectRatio: false,
legend: {
display: true,
position: "right",
labels: {
usePointStyle: true,
boxWidth: 6
},
onHover: function (event, legendItem) {
var index = legendItem.datasetIndex;
var label = this.chart.data.datasets[index].label
return label;
}
},
tooltips: {
backgroundColor: '#f5f5f5',
titleFontColor: '#333',
bodyFontColor: '#666',
bodySpacing: 4,
xPadding: 12,
intersect: 1,
displayColors: false,
callbacks: {
title: function (tooltipItem, data) {
return data['labels'][tooltipItem[0]['index']];
},
label: function (tooltipItem, data) {
return "€" + data['datasets'][0]['data'][tooltipItem['index']].toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/[,.]/g, m => (m === ',' ? '.' : ','));
}
}
},
responsive: true,
};
So how could i show the tooltip on legend hover?
Solved with the following method:
onHover: function (event, legendItem) {
var chart = this.chart;
var index = legendItem.index;
var segment = chart.getDatasetMeta(0).data[index];
chart.tooltip._active = [segment]
chart.tooltip.update()
chart.draw()
}
And i've also added a onLeave method to toggle off the tooltip
onLeave: function (event, legendItem) {
var chart = this.chart;
var index = legendItem.index;
chart.tooltip._active = []
chart.tooltip.update()
chart.draw()
}
Hi I am using the following scatter chart code
https://www.tutorialspoint.com/highcharts/highcharts_scatter_basic.htm
In this I need no negative values. when I pass only positive values data it is solved.
I need to make my y axis value reversed. That is Y axis should start with zero.
x axis same.
Kindly help me to do it. My code is as below
<html>
<head>
<title>User Interaction </title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="ourgraph.js"></script>
</head>
<body>
<div id="container" style="width: 550px; height: 400px; margin: 0 auto"></div>
<script language="JavaScript">
var edata;
var i;
//a = new Array();
$(document).ready(function() {
var chart = {
type: 'scatter',
zoomType: 'xy'
};
var title = {
text: 'User Interaction Touch points'
};
var subtitle = {
text: 'Source: charmboard database'
};
var xAxis = {
//range = [0,320]
title: {
enabled: true,
text: 'Height (px)'
},
startOnTick: true,
endOnTick: true,
showLastLabel: true
};
var yAxis = {
//range = [0,180]
title: {
text: 'Width (px)'
}
};
var legend = {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 70,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF',
borderWidth: 0.1
}
var plotOptions = {
scatter: {
marker: {
radius: 0.5,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
states: {
hover: {
marker: {
enabled: false
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '{point.x} x-px, {point.y} y-px'
}
}
};
// http call for data
$.ajax({
url: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
type: 'GET',
context: document.body,
success: function(data){
//console.log(data[0]);
//console.log(data[1]);
//console.log(data);
// http call for end
//writeing a data to file starts with removed time slot colum, negatvie values , x axis 0-320 ,y axis 0-180 alone
// data.forEach(function(i)
//{
// if (i[0]> 0 && i[0] < 320 && i[1] >0 && i[1] <180)
// {
//
// edata = data.slice(2);
//}
//});
//writeing a data to file ends with removed time slot colum, negatvie values , x axis 0-320 ,y axis 0-180 alone
var series= [{
name: 'Touches',
color: 'rgba(223, 83, 83, .5)',
data: data
}
];
var json = {};
json.chart = chart;
json.title = title;
json.subtitle = subtitle;
json.legend = legend;
json.xAxis = xAxis;
json.yAxis = yAxis;
json.series = series;
json.plotOptions = plotOptions;
$('#container').highcharts(json);
}
});
});
</script>
</body>
</html>
Since the tutorial is using HighCharts it would be good idea to open there docs.
As for answer you need to change this:
var yAxis = {
title: {
text: 'Weight (kg)'
}
};
To this:
var yAxis = {
title: {
text: 'Weight (kg)'
},
min: 0 // Make sure you add this.
};
Hope that helps!
I have two bar charts, one of them shows top ten categories, the other one shows min ten categories.
There is no problem with top ten bar chart, but I use the very same code to draw min ten bar chart that I used in top ten bar chart, but here is the result.
This is top ten:
And this is min ten:
As you can see above image, min ten chart's bars look like damaged and labels below the bars can't be seen.
And here is the codes that produce these results:
MinTen produced html which feeds the bar chart:
var initCatMinTenBarChart = function ()
{
var dataMin = new Array();
var ticks = [[0, 'Kozmetik'],[1, 'Ev&Yaşam'],[2, 'Cep Telefonu'],[3, 'Ayakkabı'],[4, 'Bilgisayar'],[5, 'Beyaz Eşya']];var labels = ['Kozmetik','Ev&Yaşam','Cep Telefonu','Ayakkabı','Bilgisayar','Beyaz Eşya'];var minTenCat_d1 = 18;var minTenCat_d2 = 12;var minTenCat_d3 = 8;var minTenCat_d4 = 7;var minTenCat_d5 = 6;var minTenCat_d6 = 4;
var isempty = false;
var d_min_ten_cat_bar = [[0,18],[1,12],[2,8],[3,7],[4,6],[5,4]];
dataMin.push({
label: labels,
data: d_min_ten_cat_bar,
bars: {
show: true,
barWidth: 0.2,
order: 1
}
});
if (!isempty) {
$.plot("#MinTenCatBarChart", dataMin, $.extend(true, {}, Plugins.getFlotDefaults(), {
legend: {
show: false
},
series: {
lines: { show: false },
points: { show: false }
},
grid: {
hoverable: true,
clickable: true
},
tooltip: true,
tooltipOpts: {
content: function (label, x, y) { return 'İçerik Sayısı: ' + y; }
},
bars: {
align: "center",
barWidth: 0.1
},
xaxis: {
align: "center",
ticks: ticks
},
yaxis: {
tickLength: 0
}
}));
}
}
TopTen produced html data which feeds the bar chart:
var initCatTopTenBarChart = function ()
{
var dataTop = new Array();
var ticks = [[0, 'Kozmetik'],[1, 'Ev&Yaşam'],[2, 'Cep Telefonu'],[3, 'Ayakkabı'],[4, 'Bilgisayar'],[5, 'Beyaz Eşya']];var labels = ['Kozmetik','Ev&Yaşam','Cep Telefonu','Ayakkabı','Bilgisayar','Beyaz Eşya'];var topTenCat_d1 = 18;var topTenCat_d2 = 12;var topTenCat_d3 = 8;var topTenCat_d4 = 7;var topTenCat_d5 = 6;var topTenCat_d6 = 4;
var isempty = false;
var d_top_ten_cat_bar = [[0,18],[1,12],[2,8],[3,7],[4,6],[5,4]];
dataTop.push({
label: labels,
data: d_top_ten_cat_bar,
bars: {
show: true,
barWidth: 0.2,
order: 1
}
});
if (!isempty) {
$.plot("#TopTenCatBarChart", dataTop, $.extend(true, {}, Plugins.getFlotDefaults(), {
legend: {
show: false
},
series: {
lines: { show: false },
points: { show: false }
},
grid: {
hoverable: true,
clickable: true
},
tooltip: true,
tooltipOpts: {
content: function (label, x, y) { return 'İçerik Sayısı: ' + y; }
},
bars: {
align: "center",
barWidth: 0.1
},
xaxis: {
align: "center",
ticks: ticks
},
yaxis: {
tickLength: 0
}
// tick olasyına bak 0,10 arası işlemez burda max-min şeyapmak lazım
}));
}
}
Maybe the positioning is off because of when the chart is being rendered? Try drawing the charts only once their corresponding tab is selected and visible.
I´m building a dynamic 6 series bar graph with jqPlot. In my implementation, the user will choose which data will go into each serie and the system will load data according to his choice. The function `GetDataFromSeries() loads the series data given a serie number and the available ticks (as categories - it gets all ticks from all series and builds an unique category array).
If the user choose to load all series, everything runs fine. The problem is if the user decide not to load one series (that´s possible). In that case, I will not load that data in GetDataFromSeries() and jqPlot gives me error.
I´m trying several ways to do it, but I´m being successfull. In the code the way it is, I´m getting Uncaught Error: No data specified if the user decides not to load one of the series. I have tried to put dummy data (null or zero) in case one of the series are empty, but doing so the bars are moved and shrinked as If I have more bars to be shown.
Don´t know how to solve that. Appreciate very much any kind of help.
Rds.
[CODE]
function GeneratePlot() {
var tickAxis = new Array();
var data0 = new Array();
var data1 = new Array();
var data2 = new Array();
var data3 = new Array();
var data4 = new Array();
var data5 = new Array();
///
/// Convert series into meaningfull data
///
tickAxis = GetTickAxisFromSeries();
data0 = GetDataFromSeries(0, tickAxis);
data1 = GetDataFromSeries(1, tickAxis);
data2 = GetDataFromSeries(2, tickAxis);
data3 = GetDataFromSeries(3, tickAxis);
data4 = GetDataFromSeries(4, tickAxis);
data5 = GetDataFromSeries(5, tickAxis);
var options = {
title: 'Evolution Plot',
height: 500,
series: [
{ show: (data0.length != 0) },
{ show: (data1.length != 0) },
{ show: (data2.length != 0) },
{ show: (data3.length != 0) },
{ show: (data4.length != 0) },
{ show: (data5.length != 0) }
],
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: tickAxis,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: {
angle: -90,
fontSize: '8pt',
formatter: $.jqplot.DateTickFormatter
}
},
yaxis: {
pad: 1.05,
tickOptions: {
formatString: '%d',
fontSize: '8pt'
}
}
},
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
rendererOptions: {
fillToZero: true
}
},
highlighter: {
show: true,
sizeAdjust: 7.5
},
cirsor: {
show: false
}
}
var plot = $.jqplot('chart', [data0, data1, data2, data3, data4, data5], options).replot();
}
I think this would solve your problem:
function GeneratePlot() {
var tickAxis = new Array();
var data = new Array();
var tempData = [];
///
/// Convert series into meaningfull data
///
tickAxis = GetTickAxisFromSeries();
for(var i = 0; i < 6; i++){
tempData = GetDataFromSeries(i, tickAxis);
if(tempData.length > 0){
data.push(tempData);
}
}
var options = {
title: 'Evolution Plot',
height: 500,
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: tickAxis,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: {
angle: -90,
fontSize: '8pt',
formatter: $.jqplot.DateTickFormatter
}
},
yaxis: {
pad: 1.05,
tickOptions: {
formatString: '%d',
fontSize: '8pt'
}
}
},
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
rendererOptions: {
fillToZero: true
}
},
highlighter: {
show: true,
sizeAdjust: 7.5
},
cirsor: {
show: false
}
}
var plot = $.jqplot('chart', data, options).replot();
}