Google Charts LineChart Custom Points - angularjs

Is it possible to add a custom point shape to a line chart?
Google's Customizing Points Documentation doesn't mention anything about adding shapes they don't already offer.
I did find this similar question with a good answer, but I don't think I can do that using angular-google-chart. Even if it is possible, I'm hoping there is a more strait forward solution.
I don't need to add a complex shape, I just need a hollow circle and an X.
I tried adding the hollow circle using stroke-color and stroke-width as a column style, but I can't even get that to work.
Here is a jsFiddle with a working hollow circle but I'm using the Javascript Literal way of adding data and can't get the following code to work:
chartData.data.cols = [
{
id: "someid",
label: "Some Label",
type: "number",
p: {
style: 'point {stroke-width: 4; stroke-color: #000000',
},
},
];
I'd rather add it to to options.series[0].strokeWidth but it doesn't look like that is an option.
So, if you can help with either hollow circle points or Xs that be awesome!

Basically: when you want to apply a custom style you must use a style-column, the style will be set via the value of the column.
Example using the object-literal:
google.setOnLoadCallback(drawChart);
function drawChart() {
var chartData = {
data: {
cols: [{
label: "X",
type: "number"
}, {
label: 'Y',
type: "number"
}, {
role: 'style',
type: "string"
}
],
rows: [{
c: [{
v: 1
}, {
v: 5
}, {
v: 'point { stroke-width: 4; fill-color: transparent; stroke-color: red;}'
}]
}, {
c: [{
v: 2
}, {
v: 1
}, {
v: 'point { stroke-width: 4; fill-color: transparent; stroke-color: red;}'
}]
}, {
c: [{
v: 3
}, {
v: 3
}, {
v: 'point { stroke-width: 4; fill-color: transparent; stroke-color: red;}'
}]
}]
}
};
var options = {
legend: 'none',
curveType: 'function',
pointSize: 7
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(new google.visualization.DataTable(chartData.data), options);
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['corechart']}]}"></script>
<div id="chart_div"></div>
If you're using multiple vaxes then add the column with role: 'style' immediately after the column you want to style.
Another solution:
set the style of the circles via CSS:
google.setOnLoadCallback(drawChart);
function drawChart() {
var chartData = {
data: {
cols: [{
label: "X",
type: "number"
}, {
label: 'Y',
type: "number"
}, {
label: 'Y',
type: "number"
}
],
rows: [
{c:[{v:1}, {v:5}, {v:4}]},
{c:[{v:2}, {v:1}, {v:2}]},
{c:[{v:3}, {v:3}, {v:5}]}
]
}
};
var options = {
curveType: 'function',
pointSize: 7,
series: {
//set unique colors for the series when you must set
//different points for mmultiple series
0: {
color: 'ff0000'
},
1: {
color: '#0000ff'
}
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(new google.visualization.DataTable(chartData.data), options);
}
#chart_div circle {
stroke-width: 4px !important;
fill: none !important;
}
#chart_div circle[fill="#ff0000"] {
stroke: #ff0000 !important;
}
#chart_div circle[fill="#0000ff"] {
stroke: #0000ff !important;
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['corechart']}]}"></script>
<div id="chart_div" ></div>

Dr. Molle's answer seemed to work for getting a hollow circle, although the point doesn't match the legend.
I figured out a workaround for an X shapped point. I used options.pointshape to give a star 4 sides, rotated it by 45 degrees and decreased the dent:
pointShape: {
type: 'star',
sides: 4,
dent: 0.1,
rotation: 45,
},
Hopefully there is a better way, but Dr. Molle's and this answer work for now.

For whoever is using Dr.Molle's brilliant CSS solution and is experiencing an issue where the second data series points disappear just make the second color the default color:
#chart_div circle {
stroke-width: 4px !important;
fill: #ffffff !important; // note that i'm not using transparent
stroke: #0000ff !important; // second color moved to be default
}
#chart_div circle[fill="#ff0000"] {
stroke: #ff0000 !important;
}
#chart_div circle[fill="#0000ff"] {
/*stroke: #0000ff !important;*/
}
**note: couldn't write this as a comment to Dr.Molle's answer due to not having enough reputation at the time.

Related

How to use a static color for Chart.js bar chart's legend, when using an array of background colors [duplicate]

I have a bar chart that always shows 4 bars. The bars are coloured dynamically. It looks like the coloured box takes its colour from the first data. I would like to use the colour from the 4th (last) data value. Maybe the options:plugins:legend:label:sort function helps but I don't understand what it does.
options
const options = {
scales: {
x: {
grid: {
display: false,
color: 'rgba(0,0,0)'
}
},
y: {
display: false,
min: 0,
max: 4
},
},
plugins: {
legend: {
position: 'bottom'
}
}
}
So I don't know if I can change the data that the box color comes from, or if there is a config option somewhere where I can change it manually.
You can use the generateLabels function as described here.
Please take a look at below runnable sample code and see how it works.
new Chart('myChart', {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow'],
datasets: [{
label: 'My Dataset',
data: [300, 50, 100],
backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56']
}]
},
options: {
responsive: false,
plugins: {
legend: {
labels: {
generateLabels: chart => {
let ds = chart.data.datasets[0];
let color = ds.backgroundColor[ds.backgroundColor.length - 1];
return [{
datasetIndex: 0,
text: ds.label,
fillStyle: color,
strokeStyle: color
}];
}
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart" height="180"></canvas>
Following up with #uminder's answer, if you want to keep the hide/show chart and the line-through style after clicking on the legend, you can add the following line:
options: {
responsive: false,
plugins: {
legend: {
labels: {
generateLabels: chart => {
let ds = chart.data.datasets[0];
let color = ds.backgroundColor[ds.backgroundColor.length - 1];
return [{
datasetIndex: 0,
text: ds.label,
fillStyle: color,
strokeStyle: color,
+ hidden: !chart.isDatasetVisible(0)
}];
}
}
}
}
}

Chart.js how to highlight a part of a label

i am trying to highlight part of a label from the axis labels based on what the user has searched for.
However the label is being rendered as text so the html tags are shown like plain text. any ideas on how to achieve this?
You can use the Plugin Core API. It offers different hooks that may be used for executing custom code. In below code snippet, I use the afterDraw hook to draw text of different styles underneath each bar.
When drawing your own tick labels, probably want to define the text rotation. Further you need to instruct Chart.js not to display the default labels. This can be done through the following definition inside the chart options.
scales: {
xAxes: [{
ticks: {
display: false,
rotation: 40
}
}],
You also need to define some padding for the bottom of the chart, otherwise you won't see your custom tick labels.
layout: {
padding: {
bottom: 60
}
},
Please take a look at below code sample and see how it works. Tick labels that need to be drawn with two different styles are separated with a semicolon inside data.labels.
new Chart(document.getElementById('myChart'), {
type: 'bar',
plugins: [{
afterDraw: chart => {
let ctx = chart.chart.ctx;
let xAxis = chart.scales['x-axis-0'];
let yAxis = chart.scales['y-axis-0'];
chart.data.labels.forEach((l, i) => {
let labelTokens = l.split(';');
let rotation = xAxis.options.ticks.rotation * -Math.PI / 180;
let x = xAxis.getPixelForValue(l);
if (labelTokens.length == 2) {
ctx.save();
let width = ctx.measureText(labelTokens.join(' ')).width;
ctx.translate(x, yAxis.bottom + 10);
ctx.rotate(rotation);
ctx.font = 'italic 12px Arial';
ctx.fillStyle = 'blue';
ctx.fillText(labelTokens[0], -width, 0);
ctx.restore();
}
ctx.save();
let labelEnd = labelTokens[labelTokens.length - 1];
let width = ctx.measureText(labelEnd).width;
ctx.translate(x, yAxis.bottom + 10);
ctx.rotate(rotation);
ctx.font = '12px Arial';
ctx.fillText(labelEnd, -width, 0);
ctx.restore();
});
}
}],
data: {
labels: ['NASTY!!;Errors', 'Warnings'],
datasets: [{
label: 'Result',
data: [30, 59],
fill: false,
backgroundColor: ['rgba(255, 99, 132, 0.2)', 'rgba(255, 159, 64, 0.2)'],
borderColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)'],
borderWidth: 1
}]
},
options: {
layout: {
padding: {
bottom: 60
}
},
legend: {
display: false
},
tooltips: {
callbacks: {
title: tooltipItem => tooltipItem[0].xLabel.split(';').join(' ')
}
},
scales: {
xAxes: [{
ticks: {
display: false,
rotation: 40
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
canvas {
max-width: 250px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" width="10" height="8"></canvas>

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

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/

Get generated bar colour dynamically

Is there any way to generate bar colours dynamically in ZingChart?
in screen-shot there is two colours generated in bar chart, i want to get list of colors used in bar chart.
html file
<zingchart id="timesheet-bar-chart" zc-values="barValues" zc- json="myObj"></zingchart>
controller
$scope.myObj = {
"type": "bar",
"plot":{
"stacked":true,
"stack-type":"normal" /* Optional specification */
},
"scale-x":{
"transform":{
"type":"date",
"all":"%d %M",
"item": {
"visible":false
}
},
"values":$scope.bar_x_axis,
},
};
and barValues is a list of integer values.
Since your question is asking how to get the bar colors, not set the bar colors. I thought my answer would be appropriate as well.
You can use the API to getobjectinfo from the chart.
demo here
$scope.myRender = {
events : {
complete : function(p) {
var info1 = zingchart.exec(p.id, 'getobjectinfo', {
object : 'plot',
plotindex: 0
});
var info2 = zingchart.exec(p.id, 'getobjectinfo', {
object : 'plot',
plotindex: 1
});
console.log(info1, info2);
}
}
}
If youre confused on the $scope.myRender variable you can read up more on the angular directive here.
You can set the colors like this,
$scope.myJson = {
'plot': {
'styles': ['#yellow', 'red', 'blue']
},
'scale-x': {
'values': ['white', 'red', 'pink']
},
'type': 'bar',
'series': [{
'text': 'Product History Color',
'values': [2, 6, 8]
}]
}
DEMO
You can specify the colors, fonts etc by yourself.
e.g.
scaleX: {
labels: ['Facebook','Apple', 'Microsoft', 'Intel','Google', 'Amazon'],
item: {
fontFamily: "Roboto",
fontSize: 14
},
lineColor: "#DDD",
tick:{
visible: false
}
},

Customizing Bar Chart using ng-google-chart

I am using Angular google chart (ng-google-chart) for drawing the graph.
I drew the Bar graph using the sample provided in http://bouil.github.io/angular-google-chart/#/generic/ColumnChart.
I am able the draw the Bar Chart.
But I would like to dynamically add the colors to the Bar based on the values.
I am not able to achieve this using https://github.com/bouil/angular-google-chart.
Below is my code sample :
$scope.arrVal2 = [22,31,90,50,80,25,15];
$scope.chartObj1 = [];
$scope.chartObj2 = [];
$scope.createChartObj = function()
{
for(var m=0; m < $scope.arrVal2.length; m++)
{
console.log('val of m ----- '+m);
$scope.chartObj2.push({c:[{v:m+1},{v:$scope.arrVal2[m]}
]})
}
}
$scope.chartObject2.data = {"cols": [
{id: "day", label: "Day", type: "string"},
{id: "events", label: "Event", type: "number"}
], "rows": $scope.chartObj2
};
$scope.chartObject2.type = 'ColumnChart';
$scope.chartObject2.options = {
'title': 'PREVIOUS 7 WEEKS',
'titleTextStyle': {color: '#FFFFFF', fontSize: 13,bold: false},
'backgroundColor': '#555555',
legend: 'none',
series: {
0: { color: '#e2431e' },
1: { color: '#e7711b' },
2: { color: '#f1ca3a' },
3: { color: '#6f9654' },
4: { color: '#1c91c0' },
5: { color: '#43459d' },
6: { color: '#43459d' }
},
colors: ['#6EAF19', '#E2B400', '#DF0000','#DF0000','#DF0000','#DF0000','#DF0000'],
is3D:true,
animation:{
duration: 3000,
easing: 'out',
},
hAxis: {
gridlines: {color: 'transparent'},
textPosition: 'none'
},
vAxis:{
minValue:0,
maxValue:100,
baselineColor: 'none',
gridlineColor: 'none',
gridlines: {color: 'transparent'},
textPosition: 'none'
}
}
Have tried adding using Series, tried adding colors: ['black','blue','white','blue','blue','blue','blue'] in options :( Only the first color in the series is getting applied.
Can any one please help me in this.
Thanks IN ADVANCE:)
Normally, the charts color data by data series (that is, DataTable column); if you want to color individual bars, you need to use a "style" role column to set the colors:
$scope.chartObject2.data = {
"cols": [
{id: "day", label: "Day", type: "string"},
{id: "events", label: "Event", type: "number"},
{role: "style", type: "string"}
],
"rows": $scope.chartObj2
};
when building your rows, add in the color:
$scope.chartObj2.push({c:[{v:m+1},{v:$scope.arrVal2[m]},{v:'#e2431e'}]});

Resources