Stacked Highcharts- How to plot a given point and remove color from the stack block - angularjs

I need to plot users office timings (in and out time) of a day in a graph using Angular JS.
For example I have reached office at 10 and then gone out for lunch at 1, then again came at 2 and then gone out at 2:30 for some work and so on.....
So in graph, y axis should show time from 10 to 6 and it should plot time on graph, like 1st it should point at 10, then on 1, then on 2 and then on 2:30 and so on...
So my questions are:
1) Using which graph, this could be achieved in a single bar?
2) I am using stacked highchart, however since stacked chart add the points, I am sending difference between the two data, so first I am sending 10, another I want to point at 1, so I am sending 3 and so on..., however it fill the entire block with a color, like from 10-1 one color, 1-2 one color and so on..., what I need is, first it should point at 10 then at 1,then at 2...and so on it should not fill it with any color.
What I have achieved so far is :https://plnkr.co/edit/CgnFfTbJ3BkyjHzErQGk?p=preview
but what I want to achieve is something like this
Please help.
You could also check the code below:
<html>
<head>
<title>Highcharts Tutorial</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div id="container" style="width: 550px; height: 400px; margin: 0 auto"> </div>
<script language="JavaScript">
$(document).ready(function() {
var chart = {
type: 'column'
};
var title = {
text: 'Stacked column chart'
};
var xAxis = {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
};
var yAxis ={
min: 10,
max:18,
tickInterval:1,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: false,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
};
var legend = {
enabled:false
};
var tooltip = {
enabled:false
};
var plotOptions = {
column: {
stacking: 'normal',
dataLabels: {
enabled: false,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
}
}
}
};
var credits = {
enabled: false
};
var series= [
{ name: 'John',
data: [1]
},
{ name: 'John',
data: [0.5]
},
{ name: 'John',
data: [1]
},
{
name: 'Jane',
data: [3]
}, {
name: 'Joe',
data: [10]
}];
var json = {};
json.chart = chart;
json.title = title;
json.xAxis = xAxis;
json.yAxis = yAxis;
json.legend = legend;
json.tooltip = tooltip;
json.plotOptions = plotOptions;
json.credits = credits;
json.series = series;
$('#container').highcharts(json);
});
</script>
</body>
</html>
</script>
</body>
</html>

Here is a example using columnrange series.
Live example: https://jsfiddle.net/mzb3bpg2/
const options = {
chart: {
type: 'columnrange'
},
series: [{
name: 'Temperatures',
data: [{
borderWidth: 2,
borderColor: Highcharts.getOptions().colors[1],
color: 'rgba(0,0,0,0)',
x: 0,
low: 0,
high: 10
}, {
borderWidth: 2,
borderColor: Highcharts.getOptions().colors[1],
color: 'rgba(0,0,0,0)',
x: 0,
low: 10,
high: 16
}, {
borderWidth: 2,
borderColor: Highcharts.getOptions().colors[1],
color: 'rgba(0,0,0,0)',
x: 0,
low: 16,
high: 20
}]
}]
}
const chart = Highcharts.chart('container', options);
[EDIT]
More complete one:
Live example:
https://jsfiddle.net/fzv2jd3c/

Related

set different bar width for each bar using ECHARTS

Im using the e-charts libary for creating a bar chart for my data .
like so :
option.series = [
{
name: 'buy',
type: 'bar',
stack: 'one',
data: Object.values(chartData?.data || {}).map(elem => -elem.buy?.total),
color: colors.bought,
label: {
show: true,
position: "bottom",
formatter: (value) => Math.round(Math.abs(value.data))
},
tooltip: {
formatter: (data) => Math.abs(data.value).toString()
},
// barWidth:this.data
},
{
name: 'sell',
type: 'bar',
stack: 'one',
data: Object.values(chartData?.data || {}).map(elem =>elem.sell?.total),
color: colors.sold,
label: {
show: true,
position: "top",
formatter: (value) => Math.round(Math.abs(value.data))
},
tooltip: {
formatter: (data) => Math.abs(data.value).toString()
},
},
{
name: 'profite',
type: 'bar',
stack: 'two',
barGap: '-100%',
z: 100,
data: Object.values(chartData?.data || {}).map(elem => elem.sell?.profit),
color: colors.profit,
label: {
show: true,
position: "insideTop",
textBorderWidth: -1,
offset: [0, -20],
formatter: (value) => Math.round(Math.abs(value.data))
},
tooltip: {
formatter: (data) => Math.abs(data.value).toString()
},
},
]
im trying to set a different width for each bar depending on the value of each bar .
on data property i get a list of numbers rendering .
When i try to add a barWidth property all i can do is change all of the bars in the same chrts like so for example:
barWidth: ${getBarWidth((Object.values(chartData?.data || {}).map((elem) => elem.sell?.amount)))}%
so i returne a different value of my data each time but it didnt changed each bar according to its value (either buy, sell and so on).
Thanks in adavance.
As you pointed out, barWidth sets the width of all the bars of a bar series. And I don't think there is a way to set the width of each bar in the same bar series.
What you should use instead is a custom series.
Custom series have a parameter called renderItem, where you write the render logic of the chart. It's where you'll be able to display custom shapes (custom sized bar in your case), using graphics.
Here is an example I found on their website, doing pretty much what you're looking for.
var container = document.getElementById('main');
var chart = echarts.init(container);
const colorList = [
'#4f81bd',
'#c0504d',
'#9bbb59',
'#604a7b',
'#948a54',
'#e46c0b'
];
const data = [
[10, 16, 3, 'A'],
[16, 18, 15, 'B'],
[18, 26, 12, 'C'],
[26, 32, 22, 'D'],
[32, 56, 7, 'E'],
[56, 62, 17, 'F']
].map(function (item, index) {
return {
value: item,
itemStyle: {
color: colorList[index]
}
};
});
chart.setOption({
title: {
text: 'Profit',
left: 'center'
},
tooltip: {},
xAxis: {
scale: true
},
yAxis: {},
series: [
{
type: 'custom',
renderItem: function (params, api) {
var yValue = api.value(2);
var start = api.coord([api.value(0), yValue]);
var size = api.size([api.value(1) - api.value(0), yValue]);
var style = api.style();
return {
type: 'rect',
shape: {
x: start[0],
y: start[1],
width: size[0],
height: size[1]
},
style: style
};
},
label: {
show: true,
position: 'top'
},
dimensions: ['from', 'to', 'profit'],
encode: {
x: [0, 1],
y: 2,
tooltip: [0, 1, 2],
itemName: 3
},
data: data
}
]
});
#main {
width: 600px;
height: 400px;
}
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.2/echarts.min.js"></script>
<div id="main"></div>
</body>
</html>

React chart2js Line chart with multiple datasets overlapping

chart
const data = {
labels: Array(coordinates.length).fill("l"),
datasets: buildDataset(),
options: {
animation: false,
scales: {
// ???????
},
legend: {
display: false
},
tooltips: {
callbacks: {
label: function(tooltipItem) {
return tooltipItem.yLabel;
}
}
},
maintainAspectRatio: false,
scales: {
myScale: {
position: 'left',
}
},
elements: {
point:{
radius: 0
}
}
}
}
return (
<Chart>
<Line
data={data}
width={50}
height={20}
options={data.options}>
</Line>
</Chart>
)
// ~~~~~
let obj = {
label: stops[0].miles == 0 ? index : index + 1,
data: points,
backgroundColor: colors[index],
tension: 0.4,
fill: true
}
These charts are built from an array of obj objects. The points variable that data refers is an array of object like: [{x: 0, y: 10257}, {x: 1, y: 10245}]
How do I get my line chart to display these different datasets side by side? I assume it has something to do with the scales parameter but wasn't able to find anything that worked in the docs.
Thanks!
For the object notation to work chart.js needs values to plot them against (not the index in the array) so you cant just provide an array containing only the value l.
You can either provide a labels array containing increasing numbers to which you match it or remove it and set your x scale to linear.
Labels example:
var options = {
type: 'line',
data: {
labels: [0, 1, 2, 3],
datasets: [{
label: '# of Votes',
data: [{
x: 0,
y: 4
}, {
x: 1,
y: 6
}, {
x: 2,
y: 2
}],
borderColor: 'pink'
},
{
label: '# of Points',
data: [{
x: 2,
y: 2
}, {
x: 3,
y: 3
}],
borderColor: 'blue'
}
]
},
options: {
scales: {}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.js"></script>
</body>
Linear example:
var options = {
type: 'line',
data: {
datasets: [{
label: '# of Votes',
data: [{
x: 0,
y: 4
}, {
x: 1,
y: 6
}, {
x: 2,
y: 2
}],
borderColor: 'pink'
},
{
label: '# of Points',
data: [{
x: 2,
y: 2
}, {
x: 3,
y: 3
}],
borderColor: 'blue'
}
]
},
options: {
scales: {
x: {
type: 'linear'
}
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.js"></script>
</body>

Adding tooltip to legend in highcharts

I am trying to add a tooltip to the legend in highcharts. I am using a pie chart. Using angular js framework.
The legend code is as below
legend: {
useHTML: true,
layout: 'vertical',
align: 'left',
itemMarginTop: 10,
itemMarginBottom: 15,
title: {
style: {
fontSize: "14px",
fontWeight: "600",
color: "#404040"
}
},
itemStyle: {
fontWeight: 'normal',
color: '#404040',
fontSize: '14px'
},
//x : 70,
//y: 110,
labelFormatter: function() {
return ` <md-icon>
<md-tooltip md-direction="top">Hello</md-tooltip>
<i class="material-icons help_icon">info_outline</i>
</md-icon>`
}
},
I do not get the expected results. it just displays the letter H and no icon. If i use a standalone icon like
<i class="material-icons help_icon">info_outline</i>
It just displays the icon. But I am unable to add any tooltip. I searched online and found a solution using the jquery UI plugin. Is there any other way without the plugin and using the angular material icons? Please suggest.
Ps: I have also tried with single quotes / double quotes instead of inverted ticks.
Unfortunately, tooltip in a legend is not supported. However, you can create it using Highcharts.SVGRenderer. Check code and demo posted below.
Code:
var chart = Highcharts.chart('container', {
chart: {
type: 'column',
events: {
load: function() {
var chart = this,
legend = chart.legend,
legendItems = legend.allItems,
group,
rectElem,
textElem,
box,
i;
group = chart.renderer.g('legend-tooltip').attr({
transform: 'translate(-9999, -9999)',
zIndex: 99
}).add();
textElem = chart.renderer.text().attr({
class: 'legend-tooltip-text',
zIndex: 7
}).add(group);
rectElem = chart.renderer.rect().attr({
'class': 'legend-tooltip',
'stroke-width': 1,
'stroke': '#c5c5c5',
'fill': 'rgba(245, 245, 245, 0.95)',
}).add(group);
for (i = 0; i < legendItems.length; i++) {
(function(i) {
var item = legend.allItems[i].legendItem.parentGroup;
item.on('mouseover', function(e) {
// Define legend-tooltip text
var str = chart.series[i].userOptions.fullName;
textElem.element.innerHTML = str;
// Adjust rect size to text
box = textElem.getBBox()
rectElem.attr({
x: box.x - 8,
y: box.y - 5,
width: box.width + 15,
height: box.height + 10
});
// Show tooltip
group.attr({
transform: `translate(${e.clientX + 7}, ${e.clientY + 7})`
})
}).on('mouseout', function(e) {
// Hide tooltip
group.attr({
transform: 'translate(-9999,-9999)'
})
});
})(i);
}
}
}
},
series: [{
data: [10, 12, 5],
fullName: 'Series 1 tooltip'
}, {
data: [6, 10, 7],
fullName: 'Series 2 tooltip'
}]
});
Demo:
https://jsfiddle.net/BlackLabel/3cbpe0mn/
API reference:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer
https://api.highcharts.com/class-reference/Highcharts.SVGElement#on

nvd3 AngularJS date format issue - non-epoch

I am using nvd3 chart in AngularJS. I am getting the data like series of [{"09/01/2015", 5},...]. i.e. [{mm/dd/yyyy, decimal}]. After checking NVD3 tutorial looks like date needs to be in epoch format, which is not possible for my case. I dont see any reference for that. How can make a line chart with Y axis some decimal values and X axis month-year or complete date without converting to epoch format.
Any reference or tutorial also would be a great help. Thanks in advance...
My Code:
var appCntrl = angular.module("AppCntrl",['nvd3']);
appCntrl.controller("QPBDController", function($scope){
$scope.score = {
"data":[7.97,8.93,6.53,4.87,4.98,4.56],
"term":["09/01/2015","10/01/2015","11/01/2015","12/01/2015","01/01/2016","02/01/2016"]
};
$scope.options = {
chart: {
type: 'lineChart',
height: 450,
margin : {
top: 20,
right: 20,
bottom: 40,
left: 55
},
x: function(d){ return d.x; },
y: function(d){ return d.y; },
useInteractiveGuideline: true,
dispatch: {
stateChange: function(e){ console.log("stateChange"); },
changeState: function(e){ console.log("changeState"); },
tooltipShow: function(e){ console.log("tooltipShow"); },
tooltipHide: function(e){ console.log("tooltipHide"); }
},
xAxis: {
tickFormat: function(d) {return d3.time.format("%b %d, %Y")(d);}
},
yAxis: {
axisLabel: 'Voltage (v)',
tickFormat: function(d){
return d3.format('.02f')(d);
},
axisLabelDistance: -10
},
callback: function(chart){
console.log("!!! lineChart callback !!!");
}
},
title: {
enable: true,
text: 'Title for Line Chart'
},
subtitle: {
enable: true,
text: 'Subtitle for simple line chart.',
css: {
'text-align': 'center',
'margin': '10px 13px 0px 7px'
}
},
caption: {
enable: true,
html: '<b>Figure 1.</b> .',
css: {
'text-align': 'justify',
'margin': '10px 13px 0px 7px'
}
}
};
$scope.data = sinAndCos();
var str = ["s"];
/*Random Data Generator */
function sinAndCos() {
var sin = [],sin2 = [],
cos = [];
//Data is represented as an array of {x,y} pairs.
for (var i = 0; i < $scope.score.term.length; i++) {
sin.push({x: $scope.score.term[i], y: $scope.score.data[i]});
sin2.push({x: $scope.score.term[i], y: $scope.score.data[i]});
cos.push({x: $scope.score.term[i], y: $scope.score.data[i]});
}
console.log(sin);
//Line chart data should be sent as an array of series objects.
return [
{
values: sin, //values - represents the array of {x,y} data points
key: 'Sine Wave', //key - the name of the series.
color: '#ff7f0e', //color - optional: choose your own line color.
strokeWidth: 2,
classed: 'dashed'
},
{
values: cos,
key: 'Cosine Wave',
color: '#2ca02c'
},
{
values: sin2,
key: 'Another sine wave',
color: '#7777ff',
area: true //area - set to true if you want this line to turn into a filled area chart.
}
];
};
});
index.html:
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="css/app.css" rel="stylesheet">
<script src="node_modules/angular/angular.min.js"></script>
<script src="node_modules/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="node_modules/d3/d3.min.js"></script>
<script src="node_modules/nvd3/build/nv.d3.min.js"></script>
<script src="node_modules/angular-nvd3/dist/angular-nvd3.min.js"></script>
<link href="node_modules/nvd3/build/nv.d3.min.css" rel="stylesheet">
<script src="bizkpi.js"></script>
<script src="js/controllers.js"></script>
<nvd3 options="options" data="data"></nvd3>
The above code shows an error in console like below and nothing comes up in GUI
TypeError: n.getMonth is not a function
at Yn.A.b (d3.min.js:1)
at t (d3.min.js:1)
at SVGTextElement.$scope.options.chart.xAxis.tickFormat (controllers.js:29)
at SVGTextElement.arguments.length.each.function.n.textContent (d3.min.js:3)
at d3.min.js:3
at Y (d3.min.js:1)
at Array.Co.each (d3.min.js:3)
at Array.Co.text (d3.min.js:3)
at SVGGElement.<anonymous> (d3.min.js:5)
you will have to format the date as follows:
vm.chart.options.chart.xAxis.tickFormat = function(d) {return d3.time.format("%b %d, %Y")(d);};
in your options.chart you should have :
lines: {
xScale: d3.time.scale(),
},
I think you should set the ticks and tickValues as well for example..
vm.chart.options.chart.xAxis.ticks = d3.time.monday;
vm.chart.options.chart.xAxis.tickValues = function(d) {return d3.time.monday.range(from, to, 2);};
};

Visualization: Pie Chart Legend Text color based on Value

I'm using ng-google-chart (Google Chart Api Directive Module for AngularJS version 0.0.11) with Google Pie charts and I'm trying to display Legend Text in the same color as slices color.
Pie Chart View
Is there any way to place slices colors into the legend.textStyle option?
Pie Chart Options
drvPie.options = {
pieHole: 0.9,
pieSliceText: 'value',
pieSliceTextStyle: {
'fontSize': '25'
},
slices: {
0: { color: 'green' },
1: { color: 'orange' },
2: { color: 'red' }
},
height: '100%',
chartArea: {'width': '100%', 'height': '70%'},
legend: {
"textStyle": {
color: 'blue',
fontSize: 15
},
labeledValueText: 'value',
"position": "labeled"
}
};
Unfortunately it is not supported to specify a separate legend style per item, but you could consider the following solution that demonstrates how to customize legend labels:
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Task Status', 'Count'],
['At work', 22],
['Terminated', 3],
['Not working', 13]
]);
var options = {
pieHole: 0.9,
pieSliceText: 'value',
pieSliceTextStyle: {
'fontSize': '25'
},
slices: {
0: { color: 'green' },
1: { color: 'orange' },
2: { color: 'red' }
},
height: '100%',
chartArea: { 'width': '100%', 'height': '70%' },
legend: {
"textStyle": {
fontSize: 15
},
labeledValueText: 'value',
"position": "labeled"
}
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
google.visualization.events.addOneTimeListener(chart, 'ready', function(){
configureLegendLabel(data,options);
});
google.visualization.events.addListener(chart, 'onmouseover', function (e) {
configureLegendLabel(data,options);
});
google.visualization.events.addListener(chart, 'onmouseout', function (e) {
configureLegendLabel(data,options);
});
chart.draw(data, options);
}
function configureLegendLabel(data,options)
{
for(var key in options.slices){
var labelText = data.getValue(parseInt(key),0);
var label = $("text:contains('" + labelText + "')");
label.attr('fill',options.slices[key].color);
}
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['corechart']}]}"></script>
<div id="piechart" style="width: 900px; height: 500px;"></div>

Resources