I have a highchart pie chart and a table to the right of the pie chart which displays the data in table form.
I would like to link the table with the pie chart so that when I hover over a row in the table it will be as if I am hovering over the pie chart segment.
I believe to do this I would need to add a class to the pie chart segment/path that I can then call using JS when hovering over the table row.
What would be the best way to either achieve this?
(I know it's possible to have a basic legend attached to the pie chart but because I need the table to be in a bootstrap column to the right along with some other data the legend isn't enough :) ).
Here is the current chart setup:
<!-- in Page JS -->
<script>
$(function () {
$('#results_donut').highcharts({
chart: {
type: 'pie'
},
title: {
text: false
},
credits: {
enabled: false
},
plotOptions: {
pie: {
dataLabels: {
enabled: false
},
shadow: false,
},
series: {
states: {
hover: {
enabled: false
}
},
point: {
events: {
mouseOver: function () {
this.options.oldColor = this.color;
this.graphic.attr("fill", "#F8464A");
},
mouseOut: function () {
this.graphic.attr("fill", this.options.oldColor);
}
}
},
}
},
tooltip: {
enabled: false,
formatter: function() {
return this.point.name + ': ' + this.y +' %';
},
style: {
fontFamily: 'Open Sans',
fontWeight: '300',
letterSpacing: '0.03em',
fontSize: '14px'
},
},
series: [{
name: 'Failure Reasons',
innerSize: '50%',
data: [["Brakes",74.6],["Seatbelts", 19.4]],
}],
});
});
</script>
And here is the view code:
<div class="row">
<div class="col-xs-12 col-sm-6">
<div id="results_donut"></div>
</div>
<div class="col-xs-12 col-sm-6 result-figures">
<div class="row failure-reasons">
<div class="col-xs-12">
<h4>Failure Reasons</h4>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<table class="table table-condensed table-hover">
<tbody>
<tr>
<td class="col-xs-6 text-uppercase failure-name">Brakes</td>
<td class="col-xs-2">74.6%</td>
<td class="col-xs-4 text-center">
<a class="transition" href="#">View Details</a>
</td>
</tr>
<tr>
<td class="col-xs-6 text-uppercase failure-name">Seatbelts</td>
<td class="col-xs-2">19.4%</td>
<td class="col-xs-4 text-center">
<a class="transition" href="#">View Details</a>
</td>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
Related
I'm trying to integrate datatable with chartjs, it works fine if i dont change the row numbers, or not do any filtration, from UI, when i change the row numbers for example, by default its 10, when i change it to 25, the charts also change, but when i move the mouse cursor to the chartjs canvas sometimes it shows the previous data(the 10 row data). how to fix it, or update the chartjs canvas data to the new
Here is my code:
$(document).ready(function(){
var list_daily_prices = document.getElementById('list_daily_prices')
if(list_daily_prices){
$('#list_daily_prices').DataTable({
"serverSide":true,
"processing":true,
"ordering": false,
"ajax":function(data,callback,settings){
$.get('/prices/daily/data',{
start:data.start,
limit:data.length,
filter:data.search.value,
},function(res){
callback({
recordsTotal:res.length,
recordsFiltered:res.length,
data:res.objects
});
},
);
},
"columns":[
{"data": "counter"},
{"data": function(data,type,dataToSet){
const date = new Date(data.day).toLocaleDateString('fr-CA')
return date
}},
{"data": "total_quantity"},
{"data": "total_price"},
{"data": "income"},
],
"drawCallback":function(settings){
var daily_date = []
var qnt = []
var total_price = []
var income = []
for(counter=0;counter<settings.aoData.length;counter++){
daily_date.push(new Date(settings.aoData[counter]._aData['day']).toLocaleDateString('fr-CA'))
qnt.push(settings.aoData[counter]._aData['total_quantity'])
total_price.push(parseFloat(settings.aoData[counter]._aData['total_price']).toFixed(2))
income.push(parseFloat(settings.aoData[counter]._aData['income']).toFixed(2))
}
var dailyPriceCanvas = $('#list_daily_prices_charts').get(0).getContext('2d')
var dailyPriceData = {
labels: daily_date,
datasets: [
{
label:'quantity',
data: qnt,
backgroundColor : '#9D0CA6',
},
{
label:'total price',
data: total_price,
backgroundColor : '#1392BE',
},
{
label:'income',
data: income,
backgroundColor : '#00a65a',
},
]
}
var dailyPriceOptions = {
responsive : true,
maintainAspectRatio : false,
datasetFill : false,
legend: { display: true },
title:{
display:true,
text:'total daily prices'
},
}
var dailyPriceChart = new Chart(dailyPriceCanvas, {
type: 'bar',
data: dailyPriceData,
options: dailyPriceOptions
})
},
"language":{
search:'',
searchPlaceholder: 'search ',
"paginate":{
'previous':'previous page',
'next':'next page',
},
"lengthMenu": "_MENU_",
"info": "showing _START_ to _END_ total _TOTAL_",
infoFiltered: "",
zeroRecords: "nothing found",
infoEmpty:""
},
dom: 'lBfrtip',
buttons: [
{
extend: 'excelHtml5',
exportOptions: {
columns: ':visible'
},
text:'excel',
},
],
})
}
})
<div class="card">
<section class="content">
<div class="container-fluid">
<div class="row">
<!-- /.col (LEFT) -->
<div class="col-md-12">
<!-- LINE CHART -->
<div class="card card-info">
<div class="card-header">
<h3 class="card-title">chart</h3>
</div>
<div class="card-body">
<div class="chart">
<canvas id="list_daily_prices_charts" style="height:400px; min-height:450px;"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- /.card-header -->
<div class="card-body table-responsive">
<table class="table table-bordered table-striped text-center" id="list_daily_prices" style='width:100%'>
<thead>
<tr>
<th class="">id</th>
<th class="col-2">date</th>
<th class="col-1">quantity</th>
<th class="col-1">price</th>
<th class="col-1">income</th>
</tr>
</thead>
<tbody>
</tbody>
</tfoot>
</table>
</div>
</div>
thank you for your help
I have a dynamically created table and on click of view button in each row a modal opens that have the pie chart with no of leaves taken by people till date in categories like sick, vacation, maternity, paternity for the particular year.on click of 1st button the pie chart shows up https://imgur.com/a/wpNa3 but but if I click on any button other than 1st then I get a blank page.https://imgur.com/a/jcZjE .Why blank page is appearing??please help me.
<td>
<button type="button" class="btn btn-default btn-sm view" data-toggle="modal" data-target="#{{pl.id}}_3"><i class="fa fa-eye" aria-hidden="true" style="color:black"></i></button>
<!-- Modal -->
<div class="modal fade" id= "{{pl.id}}_3" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><b>{{pl.employee.emp_name|title }}</b> Leave Details</h4>
</div>
<div class="modal-body">
<p>Applied leave from {{pl.start_date}} to {{pl.end_date}} for {{ pl.end_date|timeuntil:pl.start_date }} </p>
<p>Leave applied on : {{pl.date_created}}</p>
<p><div id="container" class="container" style="min-width: 310px; height: 400px; max-width: 600px; margin: 0 auto"></div></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</td>
My jquery Code:
$(document).on('click','.view', function(e){
Highcharts.chart('container', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Total number of leaves applied till now'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
}
}
},
series: [{
name: 'Brands',
colorByPoint: true,
data: [{
name: 'Sick Leaves',
y: 56.33
}, {
name: 'Casual Leaves',
y: 24.03,
sliced: true,
selected: true
}, {
name: 'Vacation Leaves',
y: 10.3
}, {
name: 'Maternity Leaves',
y: 4.77
}, {
name: 'Paternity Leaves',
y: 0.91
}]
}]
});
});
I am using classname on click due to duplicacy in Id's but still its not workin g..Where am I doing wrong?
I have a dynamically created table and on click of view button in each row a modal opens that have the pie chart with no of leaves taken by people till date in categories like sick, vacation, maternity, paternity for the particular year.Please help me how to take data from database..and on click of 1st button the pie chart shows up
but if I click on any button other than 1st then I get a blank page.
<td>
<button type="button" class="btn btn-default btn-sm view" data-toggle="modal" data-target="#{{pl.id}}_3"><i class="fa fa-eye" aria-hidden="true" style="color:black"></i></button>
<!-- Modal -->
<div class="modal fade" id= "{{pl.id}}_3" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><b>{{pl.employee.emp_name|title }}</b> Leave Details</h4>
</div>
<div class="modal-body">
<p>Applied leave from {{pl.start_date}} to {{pl.end_date}} for {{ pl.end_date|timeuntil:pl.start_date }} </p>
<p>Leave applied on : {{pl.date_created}}</p>
<p><div id="container" class="container" style="min-width: 310px; height: 400px; max-width: 600px; margin: 0 auto"></div></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</td>
My jquery Code:
$(document).on('click','.view', function(e){
Highcharts.chart('container', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Total number of leaves applied till now'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
}
}
},
series: [{
name: 'Brands',
colorByPoint: true,
data: [{
name: 'Sick Leaves',
y: 56.33
}, {
name: 'Casual Leaves',
y: 24.03,
sliced: true,
selected: true
}, {
name: 'Vacation Leaves',
y: 10.3
}, {
name: 'Maternity Leaves',
y: 4.77
}, {
name: 'Paternity Leaves',
y: 0.91
}]
}]
});
});
Modal fade has some time delay so you have to call your function by using set time out
create a new function and call it setTimeout(function(){ myFunc(); }, 500); This will work on your modal.
I have this 2 data tables below as you can see one of them is overlapping the data table and the other one is need to edit the width. I try to add width but don't have any effect on my first data table. Any suggestion about this two problems?.
HTML
<div class="row">
<div class="col-lg-6">
<div class="panel panel-primary">
<div class="panel-heading">
<div class="row">
<div class="col-lg-6">
<i class="fa fa-list fa-fw"></i>Borrower Name
</div>
</div>
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<div class="dataTable_wrapper">
<div class="col-lg-6">
<table class="table table-striped table-bordered table-hover table-responsive nowrap"
role="grid" style="width: 100%;" id="dtBorrowerName">
</table>
</div>
</div>
</div>
</div>
</div>
#*</div>
<div class="row">*#
<div class="col-lg-6">
<div class="panel panel-primary">
<div class="panel-heading">
<div class="row">
<div class="col-lg-6">
<i class="fa fa-list fa-fw"></i>Book
</div>
</div>
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<div class="dataTable_wrapper">
<div class="col-lg-6">
<table class="table table-striped table-bordered table-hover table-responsive nowrap"
role="grid" style="width: 10%;" id="dtBook">
</table>
</div>
</div>
</div>
</div>
</div>
</div>
JS CODE
var dtBorrowerName = $('#dtBorrowerName').DataTable({
responsive: true,
processing: true,
info: true,
search: true,
stateSave: true,
order: [[1, "desc"]],
lengthMenu: [[5, 10, 20, -1], [5, 10, 20, "All"]],
ajax: { "url": "/LS/GetBorrower" },
columns:
[
{ data: "BorrowerID", title: "", visible: false, searchable: false },
{ data: "IDNo", title: "ID Number" },
{ data: "Name", title: "Complete Name", sClass: "alignRight", width: " 100px" },
{ data: "BookTransactionHdrID", title: "BookTransactionHdrID", visible: false, searchable: false }
]
});
function GetStudentBook(getId) {
if (getId != 0 || getId != undefined || getId != "") {
dtStudBook = $('#dtBook').DataTable({
responsive: true,
processing: true,
info: true,
retrieve: true,
destroy: true,
search: true,
stateSave: true,
lengthMenu: [[5, 10, 20, -1], [5, 10, 20, "All"]],
ajax: {
"url": "/LS/GetStudentBook",
"data": function (d) {
d.BookTransactionDtlID = getId;
}
},
columns:
[
{ data: "BookId", title: "", visible: false, searchable: false },
//{ data: "Barcode", title: "Barcode", searchable: false },
{ data: "Author", title: "Author" }
// { data: "Title", title: "Title", sClass: "alignRight" },
// { data: "DatePublish", title: "Date Publish", sClass: "alignRight" },
// { data: "PlacePublish", title: "Place Publish" },
// { data: "NameOfPublisher", title: "Name Of Publisher"},
// { data: "ISBN", title: "ISBN"},
// { data: "BookTransactionDtlID", title: "", visible: false }
]
});
}
else {
//do nothing..
}
}
I hit this problem. It is caused by the length of the table headers and the padding around them. (I am assuming that it looks OK if the panel is wide?).
The solution is to write complicated JS to split words like "Publisher" or (as I did in the end) use Bootstrap visibility to show normal words on larger screens and use abbreviations on smaller screens (I found I had to write extra media queries to clean this up).
You may need a tooltip or whatever to explain your abbreviations. You are rather trying to fit a quart into a pint pot (that is a lot of headings for a small panel if you want them orderable etc) I think it will take quite a bit of hand crafting with very specific media queries.
Hope that helps.
I'm trying to create some charts using highcharts, and doing so with dynamic div's.
It's successful on the first chart, but the rest are blank. Viewing the html source I would assume everything is ok.
Here are my dynamically created div's:
<!-- Break Down of all Signature names in each class -->
<% n = 0 %>
<% #sig_class_name_info.each do |scn_chart| %>
<div>
<%= scn_chart[:sig_class_name] %>
</div>
<table class="table">
<tr>
<td style='width:100%'>
<div class="panel panel-warning well">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div id="alert_name_bar_chart<%=+n%>" class="panel-body text-center">
</div>
</div>
</td>
</tr>
</table>
<%n = n+1%>
<% end %>
This is the html source created:
<!-- Break Down of all Signature names in each class -->
<div>
web-application-attack
</div>
<table class="table">
<tr>
<td style='width:100%'>
<div class="panel panel-warning well">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div id="alert_name_bar_chart0" class="panel-body text-center">
</div>
</div>
</td>
</tr>
</table>
<div>
attempted-admin
</div>
<table class="table">
<tr>
<td style='width:100%'>
<div class="panel panel-warning well">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div id="alert_name_bar_chart1" class="panel-body text-center">
</div>
</div>
</td>
</tr>
</table>
<div>
misc-attack
</div>
<table class="table">
<tr>
<td style='width:100%'>
<div class="panel panel-warning well">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div id="alert_name_bar_chart2" class="panel-body text-center">
</div>
</div>
</td>
</tr>
</table>
<div>
policy-violation
</div>
<table class="table">
<tr>
<td style='width:100%'>
<div class="panel panel-warning well">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div id="alert_name_bar_chart3" class="panel-body text-center">
</div>
</div>
</td>
</tr>
</table>
Here is the highcharts script:
<script type="text/javascript">
var charts = [];
$(function () {
var getChartConfig = function(renderId, title, data, x_axis) {
var config = {};
config.chart = {
renderTo: renderId,
defaultSeriesType: 'column',
margin: [50, 50, 100, 80]
};
new Highcharts.Chart ({
chart: {
type: 'bar',
renderTo: renderId
},
title: {
text: title,
style: {
color: '#52508d'
}
},
xAxis: {
categories: x_axis
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
location.href = this.series.options.url;
}
}
}
}
},
series: [{
data: data,
showInLegend: false,
name: 'Alerts',
url: '/ips_alert_classes?query=',
color: '#2a2874'
}]
});
}
<% n = 0%>
<% #sig_class_name_info.each do |i| %>
charts.push(new Highcharts.Chart(
getChartConfig("alert_name_bar_chart<%=+n%>",<%= raw i[:sig_class_name].to_json.html_safe %>,<%= raw i[:event_name_count].to_json.html_safe %>,<%= raw i[:event_name].to_json.html_safe %>)
))
<% n = n+1%>
<% end %>
});
</script>
Here is the html source from this highcharts script:
<script type="text/javascript">
var charts = [];
$(function () {
var getChartConfig = function(renderId, title, data, x_axis) {
var config = {};
config.chart = {
renderTo: renderId,
defaultSeriesType: 'column',
margin: [50, 50, 100, 80]
};
new Highcharts.Chart ({
chart: {
type: 'bar',
renderTo: renderId
},
title: {
text: title,
style: {
color: '#52508d'
}
},
xAxis: {
categories: x_axis
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
location.href = this.series.options.url;
}
}
}
}
},
series: [{
data: data,
showInLegend: false,
name: 'Alerts',
url: '/ips_alert_classes?query=',
color: '#2a2874'
}]
});
}
charts.push(new Highcharts.Chart(
getChartConfig("alert_name_bar_chart0", "web-application-attack", [919,1,1,1], ["drop - WP-Admin attempt","Snort Alert [1:16431:5]","Snort Alert [1:19438:9]","drop - SQL use of concat function with select - likely SQL injection"])
))
charts.push(new Highcharts.Chart(
getChartConfig("alert_name_bar_chart1", "attempted-admin", [1,10,4], ["Snort Alert [1:31976:4]","drop - SERVER-OTHER Wordpress linenity theme LFI attempt","drop - OS-OTHER Bash CGI environment variable injection attempt"])
))
charts.push(new Highcharts.Chart(
getChartConfig("alert_name_bar_chart2", "misc-attack", [1], ["drop - SQL union select - possible sql injection attempt - GET parameter"])
))
charts.push(new Highcharts.Chart(
getChartConfig("alert_name_bar_chart3", "policy-violation", [2], ["drop - POLICY-OTHER Adobe ColdFusion admin interface access attempt"])
))
});
</script>
As you can see the charts.push(new Highcharts.Chart() script seems to be working as expected.
What would cause the first chart to display just fine, but the rest be blank?
UPDATE:
This is the working HighCharts setup.
<script type="text/javascript">
var charts = [];
$(function () {
var getChartConfig = function (renderId, title, data, x_axis) {
var config = {
chart: {
renderTo: renderId,
defaultSeriesType: 'bar'
},
title: {
text: title,
style: {
color: '#52508d'
}
},
xAxis: {
categories: x_axis
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
//location.href = this.series.options.url;
}
}
}
}
},
series: [{
data: data,
showInLegend: false,
name: 'Alerts',
url: '/signatures?query=',
color: '#2a2874'
}]
};
return config;
}
<% n = 0%>
<% #sig_class_name_info.each do |i| %>
charts.push(new Highcharts.Chart(
getChartConfig("alert_name_bar_chart<%=n%>"
,<%= raw i[:sig_class_name].to_json.html_safe %>
,<%= raw i[:event_name_count].to_json.html_safe %>
,<%= raw i[:event_name].to_json.html_safe %>)
))
<% n = n+1%>
<% end %>
});
</script>
One important thing: you create every chart twice, first time when calling getChartConfig and second time before pushing to the charts array. So what I suggest to change:
Push chart only:
charts.push(getChartConfig(...))
and in getChartConfig method, return created chart:
return new Highcharts.Chart ({ ... });