Highcharts donut chart is not accessible with screen readers - highcharts

I am trying to add accessibility to an donut chart created using Highcharts.
Html code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Donut highcahrt with accessibility</title>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
</head>
<body>
<figure>
<div id="chart-container"></div>
<p class="highcharts-description">Chart showing how 2020 has seen a massive growth in sales compared to 2019 and 2018. hahahaha!!!</p>
</figure>
</body>
</html>
JS code
// Create the chart
chart = new Highcharts.Chart({
chart: {
renderTo: 'chart-container',
type: 'pie'
},
title: {
text: 'Browser market share, April, 2011'
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
shadow: false
}
},
tooltip: {
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.y +' %';
}
},
series: [{
name: 'Browsers',
data: [["Firefox",6],["MSIE",4]],
size: '20%',
innerSize: '85%',color:['red','red'],
showInLegend:true,
dataLabels: {
enabled: false
}
}]
});
The JSFiddle.
When I use NVDA with Firefox(version 83) on Windows 7, the screen reader doesn't read the description specified in the HTML as specified in the documentation(https://www.highcharts.com/docs/accessibility/accessibility-module). Same is the case for JAWS on IE.

Related

Apache Zeppelin - Highcharts

I am trying Apache zeppelin . I wanted to have highcharts. So I thought of using %html interpreter. I have done this
print("%html <h3> Hello World!! </h3>")
It perfectly works. Know I have the code for highcharts
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.highcharts.com/js/highcharts.js"></script>
<script type="text/javascript" src="http://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript">
$(function () {
$('#container').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: 'Browser market shares at a specific website, 2010'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
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: 'Browser share',
data: [
['Firefox', 45.0],
['IE', 26.8],
{
name: 'Chrome',
y: 12.8,
sliced: true,
selected: true
},
['Safari', 8.5],
['Opera', 6.2],
['Others', 0.7]
]
}]
});
});
</script>
</head>
<body>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</body>
</html>
But How could I put both together. I tried searching for samples but no help. Kindly someone help.
using %angular should be the easiest.
One prerequisite is the highcharts.js should be loaded into the page.
It could loaded in the notebook with jQuery
It could be loaded by simple modification in Zeppelin
git clone https://github.com/apache/zeppelin.git
cd zeppelin
mvn clean package -DskipTests
cd zeppelin-web
bower install highcharts -S
mvn clean package -DskipTests
Though it is very straight forward to using %angular to create a static chart. While there is a gap to convert from Spark model to Highcharts.
So I create a project try to fill this gap. spark-highcharts can be used in Zeppelin, spark-shell, or other spark application.
%spark
import com.knockdata.spark.highcharts._
import com.knockdata.spark.highcharts.model._
highcharts(bank
.series("x" -> "age", "y" -> avg(col("balance")))
.orderBy(col("age")).plot()
And got a chart
Zeppelin also supports pluggable packages at run-time through the Helium framework. There are a handful of highcharts charts with published packages.

Trying to create Highcharts element in Polymer

I am trying to create a polymer custom element to display a Highchart and getting this error:
'Highcharts Error #13 Rendering div not found
This error occurs if the chart.renderTo option is misconfigured so that Highcharts is unable to find the HTML element to render the chart in.'
Can anyone please explain how to load the chart into the template div id="container"? Any links to working highcharts/polymer elements greatly appreciated :)
My code (I'm using polymer starter kit so linking to polymer/webcomponents from the elements.html and have in index.html):
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<dom-module id="my-chart">
<template>
<div id="container" style="max-width: 600px; height: 360px;"></div>
</template>
<script>
Polymer({
is: "my-chart",
ready: new Highcharts.Chart({
chart: {
type: 'bar',
renderTo: 'container'
},
title: {text: 'HI'},
xAxis: {
categories: ['London', 'Paris', 'Madrid']
},
yAxis: {
title: {
text: 'Sales'
}
},
series: [{
name: 'Cities',
data: [1000, 2500, 1500]
}]
})
});
</script>
</dom-module>
New code:
<dom-module id="my-chart">
<template>
<div id="container" style="max-width: 600px; height: 360px;"></div>
</template>
<script>
Polymer({
is: "my-chart",
ready: function() {
var el = new Highcharts.Chart
({
chart: {
type: 'bar',
// renderTo: 'container'
},
title: {text: 'HI'},
xAxis: {
categories: ['London', 'Paris', 'Madrid']
},
yAxis: {
title: {
text: 'Sales'
}
},
series: [{
name: 'Cities',
data: [1000, 2500, 1500]
}]
})
this.$.container.appendChild(el);
}
});
</script>
</dom-module>
Try, to use
ready: function() {
var el = new Highcharts.Chart({.....});
//selector for element with id container
this.$.container.appendChild(el);
}
I got the chart loading like this, thanks for help:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<dom-module id="bar-chart">
<template>
<div id="container" style="max-width: 600px; height: 360px;"></div>
</template>
<script>
Polymer({
is: "bar-chart",
ready: function () {
$(this.$.container).highcharts({
chart: {
type: 'bar',
renderTo: 'container'
},
title: {text: 'HI'},
xAxis: {
categories: ['London', 'Paris', 'Madrid']
},
yAxis: {
title: {
text: 'Sales'
}
},
series: [{
name: 'Cities',
data: [1000, 2500, 1500]
}]
})
}
});
</script>
</dom-module>
Hey you can use Highchart-Chart to do the same thing.
<!-------------------------------------|
Normal Import is done the way below:
<link rel="import" href="bower_components/highcharts-chart/highcharts-chart.html">
For the sake of a demo I will use a CDN
--------------------------------------->
<link rel="import" href="https://user-content-dot-custom-elements.appspot.com/avdaredevil/highcharts-chart/v2.0.1/highcharts-chart/highcharts-chart.html">
<highcharts-chart type="bar" x-axis='{"categories": ["London","Paris","Madrid"]}' title="Hi" x-label="Cities" data='[1000,2500,1500]' y-label="Sales"></highcharts-chart>
Click Run code snippet to see the chart!
That's it! There are more examples here with real-time data.
I'm adding this answer since I could not find this solution anywhere else and unfortunately the Highchart-Chart package with Polymer 1.x did not work for me either.
I noticed that the element was being created/rendered, but it wasn't being properly appended to the custom Polymer element (e.g. my-chart).
The only way that worked was to use this.appendChild(this.$.container); after creating the Highchart.
Your code would then be:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<dom-module id="my-chart">
<template>
<div id="container" style="max-width: 600px; height: 360px;"></div>
</template>
<script>
Polymer({
is: "my-chart",
ready: new Highcharts.Chart({
chart: {
type: 'bar',
renderTo: this.$.container // Renders to div#container in this module only
},
title: {text: 'HI'},
xAxis: {
categories: ['London', 'Paris', 'Madrid']
},
yAxis: {
title: {
text: 'Sales'
}
},
series: [{
name: 'Cities',
data: [1000, 2500, 1500]
}]
})
});
this.appendChild(this.$.container); // Add highcharts to Polymer element DOM
</script>
</dom-module>
NOTE: Highcharts.chart({...}) did not need to be stored to a variable.
This should avoid the param 1 is not Node error.

how do you create charts using highcharts javascript library

I am trying to use highcharts to build a charts. I have the below code:
my data.json file looks like this:
{"DATETIME":[1369540800,1369541700,1369542600,1369543500,1369544400,1369545300,1369546200,1369547100,1369548000,1369548900],"CPU":[14.84,13.6333333333333,14.7666666666667,13.5333333333333,17.8666666666667,15.9333333333333,14.2333333333333,13.3,10.8333333333333,9.76666666666667]}
HIGHTCHARTS
<style>
body
{
font: 10px arial;
}
</style>
<script src="jquery.min.js"></script>
<script src="js/highcharts.js"></script>
<script type="text/javascript">
$(function () {
$.getJSON('data.json', function(data) {
$('#container').highcharts({
chart: {
type: 'line'
},
title: {
text: 'CPU UTILIZATION'
},
xAxis: {
categories: ['Date']
},
yAxis: {
title: {
text: '% CPU Utilization'
}
},
series: [{
data: data,
}]
});
});
});
</script>
</head>
<body>
<div id="container" style="width:100%; height:400px;"></div>
</body>
I dont see any values, dada.json file is in the same directory as index.html file. Any ideas what I am missing here?
Your JSON should have data name instead of datetime. Morever I see only dates, not y values.
"DATETIME":
should be
"data":

Highcharts Scatter Plot Performance

I'm new to Highcharts and have been tinkering with it a bit on jsFiddle.
A fiddle independent example would look something like this:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Highcharts Example</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'scatter',
zoomType: 'xy'
},
xAxis: {
type: 'datetime'
},
series: [{
color: 'rgba(223, 83, 83, .5)',
data:
[[Date.UTC(2012,10,15,12,25,47), 90.7000],
// Many more data points here, see fiddle for complete list
[Date.UTC(2013,2,7,11,37,18), 199.5000],
[Date.UTC(2013,2,7,11,37,18), 199.5000]]
}]
});
});
});
</script>
</head>
<body>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="height: 300px"></div>
</body>
</html>
Anyways, I have a series that consists of a large set (~16k) of (datetime,float) Cartesian points that I wish to visualize on a scatter plot. I got what I wanted, but it appears to make my browser really sluggish. Particularly if I re-size the window or hover over tooltips. Looking for any advice or tips to optimize the performance or point out (no pun intended) something else I should be doing instead for this kind of visualization.
A couple of things you could do are to remove animation on the chart itself, and the tooltip. Also if you can get away with it, you could only render a tooltip for every 10th point.
http://jsfiddle.net/Jx5n2/3653/
chart: {
renderTo: 'container',
type: 'scatter',
zoomType: 'xy',
animation:false
},
tooltip:{
animation:false,
formatter:function(){
if(this.x % 10 != 0) return false;
return 'The value for <b>'+ this.x +
'</b> is <b>'+ this.y +'</b>';
}
},

How to open highcharts in new window? [duplicate]

I use highcharts to display a chart in my page.
It works fine, but some times data in graph is too "condensed" so I should find a way to see the graph in a greater size.
I read several posts over internet on this subject:
- in general they suggest to use highslide, but i don't want to, as my page is already overlaoded by scripts
-somebody tries to pop up the content in a popup, it could fit to me but I didn't succeed
- the only quasi-working example which fits to me seems to be the following:
(inside the options object I add this properties).
exporting: {
buttons: {
popUpBtn: {
symbol: 'square',
_titleKey: 'FullScreenButtonTitle',
x: -60,
symbolSize:18,
symbolFill: '#B5C9DF',
hoverSymbolFill: '#779ABF',
onclick: function () {
var win=window.open('','','location=0,titlebar=0,status=0,width=780,height=350');
win.focus();
var divtag = win.document.createElement("div");
divtag.id = "div1";
win.document.body.appendChild(divtag);
win.document.write('<script type="text/javascript" src="script/highcharts/js/highcharts.js"></script>\
<script type="text/javascript" src="script/highcharts/js/modules/exporting.js"></script>');
this.options.renderTo=divtag;
var chart = new Highcharts.Chart(this.options);
win.document.close();
}
},
exportButton: {
enabled: true
},
printButton: {
enabled: true
}
}
}
However it is not working, as the div tag is not inserted and all i get is this
<html>
<head>
<script type="text/javascript" src="script/highcharts/js/highcharts.js"> </script>
<script type="text/javascript" src="script/highcharts/js/modules/exporting.js"></script>
</head></html>
I can't understand the error.
I know it should be something simple but I can't get out alone.
--EDIT ---
I finally understood which could be a working strategy: create a "chartpopup.html" page, and passing it the parameters needed to build the copy of the graph I visualize.
So now I have:
index.html:
chartOptions = {
series: [
{
name: 'example',
data: [83.6, 78.8, 98.5, 93.4, 106.0]
}]
//// CUT SOME CODE
exporting: {
buttons: {
popUpBtn: {
enabled:true,
symbol: 'square',
_titleKey: 'FullScreenButtonTitle',
x: -60,
symbolSize:18,
symbolFill: '#B5C9DF',
hoverSymbolFill: '#779ABF',
onclick: function () {
look this!--------> generalPurposeGlobalVar = this;
var win=window.open('./chartpopup.html','Full Size Chart','location=0,titlebar=0,status=0,width=780,height=650');
}
},
exportButton: {
enabled: true
},
printButton: {
enabled: true
}
}
}
};
this.highChart=new Highcharts.Chart(this.chartOptions);
and chartpopup.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chart full Size</title>
<script type="text/javascript" src="script/jquery-1.7.1-min.js"></script>
<script type="text/javascript" src="script/highcharts/js/highcharts.js"></script>
<script type="text/javascript" src="script/highcharts/js/modules/exporting.js"> </script>
</head>
<body>
<div id="container" style="min-width: 400px; height: 650; margin: 0 auto"></div>
<script>
var chart;
$(document).ready(function() {
var mychart=window.opener.generalPurposeGlobalVar;
mychart.options.chart.renderTo= 'container';
chart = new Highcharts.Chart(mychart.options);
});
</script>
</body>
</html>
This two pages are actually working ONLY with the default graph. If I modify and re-render the graph, I'm not able to reproduce it on the popup page!
The code I use to modify the graph is basically this:
this.chartOptions.series=[{name:field.split('_').join('\n')}];
this.highChart.destroy();
this.highChart=new Highcharts.Chart(this.chartOptions);
this.highChart.xAxis[0].setCategories(_.isEmpty(mygroups) ? [] : mygroups);
this.highChart.series[0].setData([]);
this.highChart.setTitle({text: this.highChart.title.text},{text:(field.split('_').join(' ')), });
this.highChart.redraw();//
[...]
self.highChart.series[0].addPoint(result);//it's a point I calculated before
Here is an Highcharts exemple working with an "oldschool" popup :
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>highcharts foobar</title>
</head>
<body>
Open Chart Popup
<script>
function open_chart_popup() {
window.open('popup.html', 'chart popup title', 'width=1680px height=1050px');
}
</script>
</body>
</html>
popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>highcharts foobar</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
<script>
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +': '+ this.y +'°C';
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'Tokyo',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}, {
name: 'New York',
data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
}, {
name: 'Berlin',
data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
}, {
name: 'London',
data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
}]
});
});
</script>
</body>
</html>
If this solution doesn't fit to you, could you tell us which JavaScript libraries you use (this example relies on jQuery). As the documentation says, highcharts requires either jQuery, Mootools or Prototype : http://www.highcharts.com/documentation/how-to-use
If you are able to use jQuery, you can replace that popup by using some cooler effects like those ones : http://jqueryui.com/demos/dialog/
Despite of that, if you want assistance for your script, could you consider making a jsfiddle, i'm not able to reproduce your error.
EDIT :
Okay, so you have all the stuff to deal with that.
I see two options :
You send the user input series JSON data to your server by an AJAX request. Then your server send you back a view or a bunch of html/js containing your highchart with the user datas. Back to the client, you do wathever you want with that (like triggering a popup containing the graph). I'm not too comfortable with backbone but i'm sure you can generate a template and render it back (this may help http://japhr.blogspot.fr/2011/08/getting-started-with-backbonejs-view.html)
The other solution would be to directly set your template (containing the graph) to the view but hidding him by default. Then, when the series are correctly setted by the user, you simply display the template (in a popup for example). This solution avoid a server call, so I would suggest that.
EDIT 2 :
So, I've made a jsFiddle showing a basic example on how to update a chart based on a user input : http://jsfiddle.net/MxtkM/
The example updates the last value of all the series on the graph, here is how :
$('#december_value').bind('keyup', function() {
var user_input_value = parseFloat($(this).val()); // cast to float
for (var s in chart.series) { // loop through the series
var old_data = chart.series[s].data;
var new_data = [];
for (var d in old_data ) { // loop through data objects
new_data.push(old_data[d].config); // config property contains the y value
}
new_data[new_data.length - 1] = user_input_value; // update the last value
chart.series[s].setData(new_data); // use setData method to refresh the datas of the serie
}
});
This example use the method setData by providing a new data array.
If this doesn't fit your needs, there is an another method to refresh your graph in whitch you rerender all the graph by doing var chart = new Highcharts.Chart(options);. (This is explained in the links above).
This two links are also a good read :
Reload chart data via JSON with Highcharts
http://www.highcharts.com/documentation/how-to-use (part 3 and 4)
Now you shoud be able to do whatever you want with your graph based on a user input.
After wandering around and asking questions, I found out that the best way to do it is to make fullscreen the div that contains the chart.
It's a very simple solution but it works.
This post is very helpful How do I make a div full screen?
A function like the following should do the trick on a "#graph" div:
function fullscr() {
$('#graph').css({
width: $(window).width(),
height: $(window).height()
});
}
Hope this help.
The Best solution will be HTML5 Fullscreen API for fullscreen
function fullScreen(){
var elem = document.getElementById("highchart_div_id");
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen();
} else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen();
}
}
However, this piece of code only works in New Generation Browsers and I have hands on working output from Google chrome and Mozilla Firefox
Good Day

Resources