I use EnhancedLegendRenderer plugin for my jqPlot charts, however I am unable to get it working for Pie charts.
If I click on the legend labels, they don't show or hide series. Here is jsFiddle example.
legend: {
renderer: $.jqplot.EnhancedLegendRenderer,
rendererOptions: {
numberColumns: 3,
seriesToggle: true
},
show: true
}
Has anybody came across and found a solution?
The answer of Merrily somehow correct, ZingChart looks good and have such functionality out of the box, but jqPlot is free and open source.
I rewrote jqPlot Pie Chart plugins and now the Pie chart from your example will work. Here is my blog post with explanation what I changed.
Download these 2 files:
extendedPieRenderer.js (it replaces jqplot.pieRenderer.js)
enhancedPieLegendRenderer.js (it replaces
jqplot.enhancedLegendRenderer.js)
And use them like this code:
<script type="text/javascript" src="jquery.jqplot.js"></script>
<script type="text/javascript" src="extendedPieRenderer.js"></script>
<script type="text/javascript" src="enhancedPieLegendRenderer.js"></script>
<script type="text/javascript">
...
var plot = $.jqplot('chart', data, {
seriesDefaults: {
renderer: $.jqplot.PieRenderer
},
legend: {
renderer: $.jqplot.EnhancedPieLegendRenderer
}
});
...
</script>
I also created this jsFiddle which you can open and verify that showing and hiding works: http://jsfiddle.net/19vzL5h2/1/
I'm not sure how tied to jqPlot you are, but many libraries have this sort of option baked in. Highcharts has it (and is free in most cases if that is your concern) and I saw it in AmCharts recently too.
It is also available through the ZingChart JavaScript charting library. I've made a demo with the toggle legend for you to try.
<html>
<head>
<script src="https://blog.pint.com/include_files/zingchart-html5-min.js"></script>
<script src="http://cdn.zingchart.com/zingchart-core.min.js"></script>
<script>zingchart.MODULESDIR="http://cdn.zingchart.com/modules/";</script>
<meta charset="utf-8">
<title>Pie chart with legend</title>
</head>
<div id="zc"></div>
<script>
var piedemo ={
"type":"pie",
"plot":{
"value-box":{
"text":"%v"
}
},
"series":[
{
"text":"Apples",
"values":[5]
},
{
"text":"Oranges",
"values":[8]
},
{
"text":"Bananas",
"values":[22]
},
{
"text":"Grapes",
"values":[16]
}
],
"legend":{
"header":{
"text":"Click an item to toggle"
},
"layout":"x4",
"marker":{
"type":"circle",
"size":4,
"border-color":"#333"
}
}
};
zingchart.render({
id: 'zc',
data: piedemo,
height: 400,
width: 400
});
</script>
</body>
</html>
I'm on the ZingChart team so if you have any questions on this demo, please feel free to reach out.
Related
I've got a piechart that works perfectly fine on desktop. It retrieves data from an AJAX request and stores the data/json it gets. Selected data is then pushed into the chart. I am using Thymeleaf & Spring in but thats not relevant here I believe.
Everything is rendered fine on my page when I access it through Safari or chrome on mobile, however the graph is not present.
I've tried changing responsive true/false, maintaingAspectRatio false/true, playing with other options provided in the chart.js documentation. Changed the viewport, set my width on the container of the canvas rather than the canvas it self and a whole bunch of other stuff.
Could it be due to the load order? i.e the page is loaded before it can actually get the information from the request? However, that would mean that it shouldn't be working on desktop either.
Here is some code
myGraph.js
$(document).ready(function () {
var id = $.url(2);
$.ajax({
url: "hosturl/a/b/" + id + "/c/d",
type: "GET",
dataType: "json",
success: function (data) {
console.log(data);
var count = [];
var days = [];
for (var i in data) {
days.push(data[i][1]);
count.push(data[i][0]);
}
var chartdata = {
labels: days,
datasets: [
{
label: "By day",
backgroundColor: "#4dc3ff",
borderWidth: 2,
hoverBackgroundColor: "#009",
hoverBorderColor: "#099",
hoverBorderWidth: 5,
data: count
}
]
};
var ctx = $("#daysGraph");
var pieChart = new Chart(ctx, {
type: 'pie',
data: chartdata,
options: {
responsive: true,
legend: {
display: true,
position: 'right',
labels: {
fontColor: "#000"
}
}
}
});
},
error: function (data) {
}
});
graph.html (most of the other html is cut out out, but this on its own doesn't work)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-
scale=1,maximum-scale=7"/>
<title>Hmm</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"/>
<script src="../../javascript/Chart.min.js" th:href="#{/Chart.min.js}"/>
<script src="../../javascript/js-url-2.5.0/url.js" th:href="#{/url.js}" ></script >
<link rel="stylesheet" href="../static/css/graph.css" th:href="#{/css/graph.css}"/>
<script src="../../javascript/myGraph.js" th:href="#{/myGraph.js}" />
</head>
<body>
<div class="chart-container">
<canvas id="daysGraph" ></canvas>
</div>
</body>
</html>
graph.css
.chart-container {
position: relative;
margin: auto;
height: 80vh;
width: 80vw;
}
On the live server it looks like this
Any advice is welcome
Turned out there was something wrong with the api-route on mobile vs dektop relating to localhost. Therefore my data wasn't being fetched from the api and thus wouldn't populate the chart which is why it is not displaying on mobile. In other words, I was looking in the wrong places for an answer.
I've had similar problems myself, I resolved my issue by playing around with the borderWidth in order to get it working across all devices. Try changing it several times to see if it has any impact at all.
I need to know how can with jquery maybe show a better pie chart with morris.js...with jquery flot the library I can hide the result with per example less than 100 coincidences but with morris I don't know how?
Here the capture:
and I want to show it like this one:
here is the jquery i use:
<script type='text/javascript' charset='utf-8'>
$(function () {
var pie = {
element: 'pie',
hideHover: 'auto',
resize: true,
data: <?php include('graficas6.php'); ?>,
colors: [
'#1424b8',
'#0aa623',
'#940f3f',
'#148585',
'#098215',
'#b86c14',
'#b83214'
],
formatter: function (y) {
return y + " "
}
}
donut1 = Morris.Donut(pie)
});
</script>
I would suggest if you have the large data then you should use pagination ,so that data will be shown on each of the different pages.
There are many benefits if you look into these website.
https://demo.aheadmetrics.com/#UIJGJX6MIQ
I am currently making my ecommerce sales report . Once it gets love i will put that link over here
I am having trouble creating multiple bars with flot. There is a plugin that can be downloaded here: http://www.benjaminbuffet.com/public/js/jquery.flot.orderBars.js that makes graphs with multiple bars per x category like this: http://www.pikemere.co.uk/blog/tutorial-flot-how-to-create-bar-charts/ (see under the customized bar charts). However, his example is a bit different in that it uses the time function rather than categories.
Here is my code:
<!doctype html>
<head>
<script language="javascript" type="text/javascript" src="/flot/jquery.js"></script>
<script language="javascript" type="text/javascript" src="/flot/jquery.flot.js"> </script>
<script language="javascript" type="text/javascript" src="/flot/jquery.flot.categories.js"></script>
<script language="javascript" type="text/javascript" src="/flot/jquery.flot.orderBars.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var data1 = [
{
label: "Male" ,
data: [["True", 1],["False", 2]] ,
bars: {
show: true,
barWidth: 0.13,
order: 1
}
},
{
label: "Female" ,
data: [["True", 3],["False", 4]],
bars: {
show: true,
barWidth: 0.13,
order: 2
}
}
];
$.plot($("#placeholder"), data1, {
xaxis: {
mode: "categories"
},
});
});
</script>
<title>Test</title>
</head>
<body>
<div id="placeholder" style="width:600px;height:300px"></div>
</body>
</html>
With the above code, the graph displays, but without any bars. If I remove the order:1 and order:2, it displays correctly, except with the bars overlapping each other rather than being offset by each other (I think it just ignores the orderbars plugin).
This is a very simplified example of what I really want to do, but if someone knows how I can get it to do what I want fairly simply, I would be very much appreciative.
To sum up, what I want is to have two sets of two bars. The first set with "True" under them and the second second set with "False" under them. I do not want to use numbers to represent the values, if possible as it will greatly complicate my more complex situation. But if I must, I would still like to know how to do it that way.
change the function getAxeMinMaxValues in orderBars.js
function getAxeMinMaxValues(series, AxeIdx) {
var minMaxValues = new Array();
for (var i = 0; i < series.length; i++) {
series[i].data[series[i].data.length - 1][AxeIdx];
minMaxValues[0] = 0;
minMaxValues[1] = series[i].data.length - 1;
}
return minMaxValues;
}
hope this will help
I have a Kendo UI Datavis Bar Chart for which I wish to show the pointer (hand) cursor when hovering over the bars in the chart and labels for those bars. When moving off the bars in the chart the cursor should return to the standard arrow pointer.
I noticed that the cursor turned into the text cursor when hovering over the axis labels (left, right, and bottom) and on the legend. So in addition to the above I would like the cursor to remain the standard cursor (arrow) when hovering over the axis labels and legend (since you cannot edit these). I would also like the cursor to switch to the pointer cursor when hovering over the x-axis (bottom) labels.
I can easily show a pointer cursor for the entire chart when hovering anywhere over the chart but that is not desired.
I have tried various strategies using the seriesHover event but so far nothing has worked.
How do I achieve the above?
Thomas your answer almost has me there. However, I need one additional piece of information:
How would I use the technique you show in your answer below within a CSS file. I have several Kendo UI charts some for which I need this behavior and some for which I do not. I have both ids and classes associated with the divs that contain the kendo UI charts (one div per chart). The actual charts are created using JavaScript code at load time. I tried to add the following, to the CSS within the CSS file but this had no effect:
#barChart {
/*cursor: pointer;*/
(svg > path):last-child {cusror: pointer;}
}
where #barChart is the Id of the div containing the KendoUI chart within the HTML
<div id="barChart" class="bargraph"></div>
Is there a way to do what you have shown below for charts that are created at load time within predefined divs? Does this have to be done by hooking into the charts hover event?
Just tried styling the Kendo UI bar chart demo with CSS; both turning the cursor into a hand and leaving it the default cursor on text works quite well. I just had to add two lines of CSS (and change the script/CSS URLs):
<html>
<head>
<title></title>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script src="http://cdn.kendostatic.com/2012.3.1114/js/kendo.all.min.js"></script>
<link href="http://cdn.kendostatic.com/2012.3.1114/styles/kendo.common.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2012.3.1114/styles/kendo.default.min.css" rel="stylesheet" />
<style type="text/css">
/* When hovering over a bar, Kendo dynamically adds
a bar as the last child of the SVG element that
works as an overlay. So, effectively, we're
hovering over the last (dynamically added) child */
svg > path:last-child {cursor:pointer;}
svg {cursor:default}
</style>
</head>
<body>
<div id="example" class="k-content">
<div class="chart-wrapper">
<div id="chart" style="background: center no-repeat url('../../content/shared/styles/world-map.png');"></div>
</div>
<script>
function createChart() {
$("#chart").kendoChart({
theme: $(document).data("kendoSkin") || "default",
title: {
text: "Internet Users"
},
legend: {
position: "bottom"
},
chartArea: {
background: ""
},
seriesDefaults: {
type: "bar"
},
series: [{
name: "World",
data: [15.7, 16.7, 20, 23.5, 26.6]
}, {
name: "United States",
data: [67.96, 68.93, 75, 74, 78]
}],
valueAxis: {
labels: {
format: "{0}%"
}
},
categoryAxis: {
categories: [2005, 2006, 2007, 2008, 2009]
},
tooltip: {
visible: true,
format: "{0}%"
}
});
}
$(document).ready(function() {
setTimeout(function() {
// Initialize the chart with a delay to make sure
// the initial animation is visible
createChart();
$("#example").bind("kendo:skinChange", function(e) {
createChart();
});
}, 400);
});
</script>
</div>
<script type="text/javascript">
console.log("hi")
document.addEventListener("click",function(e){document.write(e.target)},false)
</script>
</body>
</html>
If you have multiple charts and want this behavior only for some charts, I'd suggest using classes, like
<div id="barChart" class="bargraph cursorPointer"></div>
And change the CSS like
.cursorPointer svg > path:last-child {cursor:pointer;}
.cursorPointer svg {cursor:default}
(If you want the arrow cursor on text of all graphs, omit the .cursorPointer on the second line.)
If you want to change the cursor only in those labels where you have defined axisLabelClick event. You can do this:
var chart = $("#chart").data("kendoChart");
In my case, I just handle the first label, so I only want the pointer cursor in there:
var idLabel = chart._plotArea.axisY.children[0].options.id;
$('#' + idLabel).css('cursor', 'pointer');
Interestingly enough this worked for me perfectly (Only Bar Chart Kendo 2016):
svg > g g g g g g {cursor:pointer;}
svg {cursor:default}
Since this isn't a setting in Kendo yet, as #ThomasW, wrote you need to find a way to target the overlay path that gets shown when you hover over the graph elements.
In my case I noticed that all of those overlays have fill-opacity="0.2" and this did the trick:
.kendo-chart-wrapper [fill-opacity="0.2"] {
cursor: pointer;
}
I've found a few posts on this but none that have helped me solve the situation. I'll try to explain the best I can.
My HighCharts example code works fine when I put it in an ASP.NET user control and simply browse to a page that contains my user control, as it is simply the same example that comes with the highcharts package. The following code is therefore in an asp.net web user control.
<!-- 1. Add these JavaScript inclusions in the head of your page -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="/js/highcharts.js"></script>
<!-- 1a) Optional: add a theme file -->
<!--
<script type="text/javascript" src="/js/themes/gray.js"></script>
-->
<!-- 1b) Optional: the exporting module -->
<script type="text/javascript" src="/js/modules/exporting.js"></script>
<!-- 2. Add the JavaScript to initialize the chart on document ready -->
<script type="text/javascript">
var chart;
$(document).ready(function () {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: 'Under / Over 2.5 Goals'
},
tooltip: {
formatter: function () {
return '<b>' + this.point.name + '</b>: ' + this.percentage + ' %';
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function () {
return '<b>' + this.point.name + '</b>: ' + this.percentage + ' %';
}
}
}
},
series: [{
type: 'pie',
name: 'Under / Over 2.5 Goals',
data: [
['Under', 33.0],
['Over', 67.0]
]
}]
});
});
</script>
<!-- 3. Add the container -->
<div id="container" style="width: 800px; height: 400px; margin: 0 auto">
</div>
When however I am loading this same user control into my page dynamically using AJAX the chart is not rendering and I am getting an empty white as per the inline styling. I am presuming that this is because the JS code is executing when the document is ready and this will not work when I am loading the control dynamically.
The following code resides in an external .js file
Service.GetChartData(OnGetChartDataSuccess, OnGetChartDataFailure);
function OnGetChartDataSuccess(result) {
$get('ChartDataContent').style.display = 'none';
Sys.UI.DomElement.removeCssClass($get('ChartDataContent'), 'loading');
$get('ChartDataContent').innerHTML = result;
$('#ChartDataContent').fadeIn(500);
}
function OnGetChartDataFailure(result) {
alert('Error loading control data');
}
Now at the point where the Ajax call to the service has succeeded I need to be able to get the chart to do its rendering etc to the container.
As it stands this is just using the example and there is no need for me to be using Ajax, but in practice there will be some long running calculations that need to take place before the chart is rendered.
If I need to add more information to this then please say and Ill do my best to explain further.
Thanks in advance
The simplest option you have is to use the Highcharts .Net library from codeplex that acts as a wrapper around the Highcharts js library, allowing you to create the charts using only C#.
However, if you so not want to go that way, you can always use a helper function to load the series into the chart as shown in the example here