I am using Vue Js and Echarts library to build some graphs. I have a situation where I need to calculate the Standard Deviation and average for some data. The series are the average. I would like to add the error bar like the following screenshots to show the STD DEV in the graph.
Is there anyway to add the error bar to the Echart? I appreciate your effort and help !
Could this be what you want?
var categoryData = [];
var errorData = [];
var barData = [];
var dataCount = 50;
for (var i = 0; i < dataCount; i++) {
var val = Math.random() * 1000;
categoryData.push('category' + i);
errorData.push([
i,
echarts.number.round(Math.max(0, val - Math.random() * 100)),
echarts.number.round(val + Math.random() * 80)
]);
barData.push(echarts.number.round(val, 2));
}
function renderItem(params, api) {
var xValue = api.value(0);
var highPoint = api.coord([xValue, api.value(1)]);
var lowPoint = api.coord([xValue, api.value(2)]);
var halfWidth = api.size([1, 0])[0] * 0.1;
var style = api.style({
stroke: api.visual('color'),
fill: null
});
return {
type: 'group',
children: [{
type: 'line',
shape: {
x1: highPoint[0] - halfWidth, y1: highPoint[1],
x2: highPoint[0] + halfWidth, y2: highPoint[1]
},
style: style
}, {
type: 'line',
shape: {
x1: highPoint[0], y1: highPoint[1],
x2: lowPoint[0], y2: lowPoint[1]
},
style: style
}, {
type: 'line',
shape: {
x1: lowPoint[0] - halfWidth, y1: lowPoint[1],
x2: lowPoint[0] + halfWidth, y2: lowPoint[1]
},
style: style
}]
};
}
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
title: {
text: 'Avg/Error chart'
},
legend: {
data: ['avg', 'error']
},
dataZoom: [{
type: 'slider',
start: 50,
end: 70
}, {
type: 'inside',
start: 50,
end: 70
}],
xAxis: {
data: categoryData
},
yAxis: {},
series: [{
type: 'scatter',
name: 'avg',
data: barData,
itemStyle: {
color: '#77bef7'
}
}, {
type: 'custom',
name: 'error',
itemStyle: {
normal: {
borderWidth: 1.5
}
},
renderItem: renderItem,
encode: {
x: 0,
y: [1, 2]
},
data: errorData,
}]
};
reworked from here
I'm not sure I understood correctly but you need to add new series with error data and change symbol to circle. Something like this: https://echarts.apache.org/examples/en/editor.html?c=boxplot-light-velocity
How did you try to do this? Please show you code.
Related
I got stuck somewhere and there I want your help. I want a Pie chart data-label feature into the variable Pie chart. which is like the data should stay in the centre of the chart piece.
I tried so many ways but not fit in the centre like the data label indication line.
Please check the code and design below and help me to fix my issue...
This's the design reference for the Output
This's the current output of my code
This's the link for the current output...
<script>
Highcharts.setOptions({
colors: ['#2B2E33', '#4D5566', '#8590A6', '#B8C3D9', '#02D42E']
});
Highcharts.chart('container', {
chart: {
type: 'variablepie',
style: {
fontFamily: "'Montserrat-Regular', 'sans-serif'",
letterSpacing: '0.5px',
},
events: {
load: function() {
var series = this.series[0],
distance = series.points[0].shapeArgs.r / 2;
series.update({
dataLabels: {
distance: -distance
}
});
}
}
},
title: {
text: ' '
},
tooltip: {
headerFormat: '',
pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {point.name}</b> {point.y}<br/>'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
legend: {
symbolRadius: 0,
itemStyle: {
fontWeight: 'bold',
color:'#8590A6',
textOverflow: 'clip'
}
},
plotOptions: {
variablepie: {
allowPointSelect: true,
cursor: 'pointer',
//showInLegend: true,
dataLabels: {
enabled: true,
alignTo: 'center',
format: '{point.percentage:.1f} %',
distance: -10,
style:{
textOutline: 'none',
fontSize: 15,
lineHeight: 0,
color:'white',
fontWeight: 'bold',
},
filter: {
property: 'percentage',
operator: '>',
value: 2
}
}
}
},
series: [{
innerSize: '40%',
zMin: 0,
name: 'countries',
data: [{
name: 'Google',
y: 25,
z: 100,
}, {
name: 'Facebook',
y: 14,
z: 115
}, {
name: 'Pinterest',
y: 11,
z: 85
}, {
name: 'Yelp',
y: 10,
z: 90
}, {
name: 'Local Services',
y: 40,
z: 140
}]
}]
}, function (chart) {
$legend = $('#customLegend');
$.each(chart.series[0].data, function (j, data) {
$legend.append('<div class="item"><div class="symbol" style="background-color:'+data.color+'"></div><div class="serieName" id="">' + data.name + '</div><div class="value" id="">' + data.y + '</div></div>');
});
$('#customLegend .item').click(function(){
var inx = $(this).index(),
point = chart.series[0].data[inx];
if(point.visible)
point.setVisible(false);
else
point.setVisible(true);
});
});
You can add some extra info to your serie in order to position you label correctly.
For instance:
{
name: 'Pinterest',
y: 11,
z: 85,
dataLabels: {
distance: -30,
x: -20
}
}, {
name: 'Yelp',
y: 10,
z: 90,
dataLabels: {
distance: -30,
x: 30
}
This may help for static charts.
I prepared a demo where the center of the arc point is calculated and used as translate function coordinates to center the data label.
events: {
render: function() {
const series = this.series[0];
series.points.forEach(p => {
const dataLabel = p.dataLabel;
const args = p.shapeArgs;
const angle = (args.start + args.end) / 2;
const r = (args.innerR + args.r) / 2;
const x = args.x + (r * Math.cos(angle)) - dataLabel.bBox.width / 2;
const y = args.y + (r * Math.sin(angle)) - dataLabel.bBox.height / 2;
dataLabel.translate(x, y)
})
}
}
Demo: https://jsfiddle.net/BlackLabel/c3wf85g7/
I'm adding data points to a bubble graph. However, since the value for r is very small I can barely see the points on the graph. I tried to use the radius property to expand the radius, but it seems to be overwritten by the r data property. How can I increase the radius for each bubble? For example, how can I set them to 10x the actual r value?
This is the code that I have so far:
this.managers.forEach(manager => {
const newDataPoint = {
label: [manager.SecurityName],
backgroundColor: this.getRandomRGB(),
borderColor: this.getRandomRGB(),
data: [{
x: +manager[this.selectedX],
y: +manager[this.selectedY],
r: +manager[this.selectedR]
}],
radius: (+manager[this.selectedR] * 10)
};
this.chartDataSet.push(newDataPoint);
});
I've managed to change the size by multiplying the r property directly, but that changes the actual value that shows up when hovered, which I want to avoid. How can I keep the r property the same but still increase the radius?
This can be done with the Plugin Core API. The API offers different hooks that may be used for executing custom code. In your case, you could use the afterDatasetUpdate hook to increase the radius of the points in the dataset's metadata.
plugins:[{
afterDatasetUpdate: chart => {
chart.getDatasetMeta(0).data.forEach(v => {
v._model.radius *= 10;
v._options.hoverRadius = v._model.radius;
})
}
}],
new Chart('canvas', {
type: 'bubble',
plugins: [{
afterDatasetUpdate: chart => {
chart.getDatasetMeta(0).data.forEach(v => {
v._model.radius *= 10;
v._options.hoverRadius = v._model.radius;
})
}
}],
data: {
datasets: [{
label: 'First Dataset',
data: [
{x: 10, y: 20, r: 1 },
{x: 20, y: 10, r: 2 }
],
backgroundColor: 'rgb(255, 99, 132)'
}]
},
options: {
scales: {
xAxes: [{
ticks: {
min: 5,
max: 25
}
}],
yAxes: [{
ticks: {
min: 5,
max: 25
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="canvas" height="90"></canvas>
For developers using version 3.9.1 it is like this:
const pixelValue = (scale, v) => {
const val = scale.getValueForPixel(v)
return Math.trunc(isNaN(val) ? v * 6 : 3)
}
const $chart = document.getElementById("chart");
const chart = new Chart($chart, {
type: "bubble",
data: {
datasets: [{
label: "scaled radius",
backgroundColor: 'rgb(255, 99, 132)',
data: [{
x: 10,
y: 11,
size: 1
},
{
x: 20,
y: 5,
size: 3
}
],
radius: context => {
const scale = context.chart.scales.y
const size = context.dataset.data[context.dataIndex].size
const value = Math.abs(pixelValue(scale, size))
return value
},
}]
},
options: {
maintainAspectRatio: false,
scales: {
x: {
min: 0,
max: 30
},
y: {
min: 2,
max: 14
}
}
}
})
.wrapper {
max-width: 800px;
max-height: 180px;
}
canvas {
user-select: none;
}
<div class="wrapper" style="height: 180px; width: 600px">
<canvas id="chart"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js" integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
I'm trying to plot a scatter plot using the Highcharts library. I get some results from my database and format them in front end level using javascript (transformGraph2Data function in the following code does this work - I don't include the code of this function here to keep the question clear and short). More specifically I have the following piece of code:
<script type="text/javascript">
var graph2dataa;
function plotGraph2() {
graph2dataa = transformGraph2Data(<%=graph2data%>);
console.log(graph2dataa);
console.log(typeof graph2dataa);
Highcharts.chart('graphDiv2', {
chart: {
type: 'scatter',
zoomType: 'xy',
events: {
click: function (e) {
var x = e.xAxis[0].value,
y = e.yAxis[0].value,
series = this.series[0];
series.addPoint([x, y]);
}
}
},
xAxis: {
title: {
enabled: true,
text: '<b><%=graph2XaxisTitle%></b>'
},
startOnTick: true,
endOnTick: true,
showLastLabel: true,
plotLines: [{
value: 0,
color: 'red',
dashStyle: 'shortdash',
width: 2
}]
},
yAxis: {
title: {
text: '<b><%=graph2YaxisTitle%></b>',
style: {
fontWeight: 'normal'
}
},
plotLines: [{
value: 0,
color: 'red',
dashStyle: 'shortdash',
width: 2
}]
},
plotOptions: {
series: {
cursor: 'pointer',
turboThreshold: 0
},
scatter: {
marker: {
radius: 2,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
}
}
},
graph2dataa //THIS VARIABLE HOLDS THE ACTUAL DATA I'D LIKE TO PLOT
});
}
</script>
The graph2dataa variable gets the following string value:
series: [{ name: "22h - 4h", color: "#000000", data: [{ name: "HACD3", x: 0.417666669, y: 1.841010179 }, { name: "VPS53", x: 0.113499999, y: 0.153579771 }, { name: "IPO11", x: -0.300000004, y: 0.734065117 }, { name: "FIP1L1", x: 0.067000012, y: 0.165934747 }, { name: "HSPE1", x: 0.186666687, y: 0.407514478 }] }] which is valid and can be plotted if I hardcode it. The problem occurs when I try to pass that value using the graph2dataa variable.
Any ideas what am I doing wrong?
Highcharts require a specific series structure and it should be an array of object, not a string. Your transformGraph2Data function should return the correct structure, which looks this way:
var graph2dataa = [{
name: "22h - 4h",
color: "#000000",
data: [{
name: "HACD3",
x: 0.417666669,
y: 1.841010179
}, {
name: "VPS53",
x: 0.113499999,
y: 0.153579771
}, {
name: "IPO11",
x: -0.300000004,
y: 0.734065117
}, {
name: "FIP1L1",
x: 0.067000012,
y: 0.165934747
}, {
name: "HSPE1",
x: 0.186666687,
y: 0.407514478
}]
}]
Live demo: http://jsfiddle.net/BlackLabel/4ath23yo/
I am using Highchart library but very disappointed after using the same. Highchart call back function formatter not working for me for any of the chart.
I am using Highchart API, It return image of the chart. but with wrong x-axis value. I want value to be "hello1, hello2, hello3 etc." but it only gives me number 1, 2, 3...
Please help me.
Link Of Js Fiddle : https://jsfiddle.net/stjk38rz/
Code is
var categories = ['Conflict', 'Identity', 'Role', 'Attitude', 'Agility', 'Fairness'],
count = 0;
var options = {
exporting: {
url: 'https://export.highcharts.com/'
},
chart: {
polar: true,
renderTo: 'container',
zoomType: 'x'
},
pane: {
startAngle: 45,
},
title: {
text: 'Highcharts Polar Chart'
},
xAxis: {
tickInterval: 1,
min: 0,
max: 6,
labels: {
enabled: true,
formatter: function () {
if(this.value.toString().substring(0, 6) == 0)
{
return "hello1";
}
if(this.value.toString().substring(0, 6) == 1)
{
return "hello2";
}
if(this.value.toString().substring(0, 6) == 2)
{
return "hello3";
}
if(this.value.toString().substring(0, 6) == 3)
{
return "hello4";
}
if(this.value.toString().substring(0, 6) == 4)
{
return "hello5";
}
if(this.value.toString().substring(0, 6) == 5)
{
return "hello6";
}
}
}
},
tooltip: {
formatter: function () {
return '<b>' + categories[Highcharts.numberFormat(this.x, 0) - 1] + '</b><br/>' + 'value: ' + this.y;
}
},
yAxis: {
labels: {
enabled: false
},
min: 0,
tickInterval: 10,
tickPositions: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
minorTickInterval: 0
},
plotOptions: {
series: {
pointStart: 0.5,
pointInterval: 1
},
column: {
pointPadding: 0,
groupPadding: 0
}
},
series: [{
type: 'column',
name: 'test data',
data: [{
y: 9.5,
color: '#0FCCD9'
}, {
y: 1,
color: '#ED1334'
}, {
y: 3,
color: '#EDCC13'
}, {
y: 4,
color: '#34ED13'
}, {
y: 5,
color: '#34ED13'
}, {
y: 6,
color: '#34ED13'
}]
}]
};
var obj = {},
exportUrl = options.exporting.url;
obj.options = JSON.stringify(options);
obj.type = 'image/png';
obj.async = true;
$.ajax({
type: 'post',
url: exportUrl,
data: obj,
success: function (data) {
var imgContainer = $("#imgContainer");
$('<img>').attr('src', exportUrl + data).attr('width', '250px').appendTo(imgContainer);
$('<a>or Download Here</a>').attr('href', exportUrl + data).appendTo(imgContainer);
}
});
It appears that formatter isn't being called at all.
This could be because it's a polar chart or possibly there's some other conflict in your code overriding this?
As long as you only want text, you can pass the text in as categories, ie:
var categories = ['Conflict', 'Identity', 'Role', 'Attitude', 'Agility', 'Fairness']
xAxis: {
categories: categories
}
Updated fiddle
The live graph stops when the mouse pointer is put inside the graph area. I need to have a live graph that displays values continuously irrespective of mouse movement.Please help me out.
The code is as follows.Please use " jsfiddle.net "
HTML:
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
JAVASCRIPT :
$(function () {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$('#container').highcharts({
chart: {
type: 'areaspline',
animation: true, // don't animate in old IE
marginRight: 10,
events: {
load: function() {
// set up the updating of the chart each second
var seriesa = this.series[0];
var seriesb = this.series[1];
setInterval(function() {
var x1 = (new Date()).getTime(); // current time
var y1 = Math.random();
var x2 = (new Date()).getTime();
var y2 = Math.random();
seriesa.addPoint([x1, y1], true, true);
seriesb.addPoint([x2, y2], true, true);
}, 1000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
title: {
text: 'Time'
},
tickWidth: 1 ,
// tickWidth: 2,
type: 'datetime',
labels:
{
enabled:false
},
tickColor: '#F00',
},
yAxis: {
title: {
text: 'speed'
},
labels: {
formatter: function()
{
if(this.value < 1000)
{
return this.value +'kbps';
}
else
{
var thisvalue = this.value;
thisvalue = thisvalue/1000;
thisvalue = thisvalue.toFixed(1);
return thisvalue +' mbps';
}
},
style:{
color: '#a6a6a6',
font: '10px Arial'
}
},
plotLines: [{
value: 50,
width: 1,
color: '#808080'
}]
},
tooltip: {//WE need shared tooltip
formatter: function() {
var s = '<br>'+ this.x +'</br>';
$.each(this.points, function(i, point) {
s += '<br/>'+ point.series[i].name +': '+
point.y +'<m>';
});
return s;
},
shared: true
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'download data',
color: '#037472',
lineWidth:2,
fillOpacity: 1,
fillColor:
{
linearGradient: [0, 0, 0, 180],
stops:
[
[0, 'rgba(123, 195, 194,1)'],
[1, 'rgba(123, 195, 194,0)'],
]
},
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -30; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
},
//2nd graph plotting
{
name: 'Upload Speed',
color: '#068cca',
lineWidth:2,
fillOpacity: 1,
fillColor: {
linearGradient: [0, 0, 0, 180],
stops:
[
[0, 'rgba(99, 204, 255,1)'],
[1, 'rgba(99, 204, 255,0)']
]
},
data:(function(){
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -30; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()*3000
});
}
return data;
})()
}
]
}); //containers end highcharts ends
});
});
It doesn't work, because in the tooltip you referr to incorrect object, like point.series[i].name, which doesn't exist.