I have a project to recreate a Parametric EQ and am using Angular and Chartjs (angular-chart) to do so. Most of it's working, but, I have a need for two different line types in the same graph. Most of the filter types have lines connecting the points, but one of the filter types (band stop) should show a gap at the frequency. I can plot the X/Y of the points, but how do I get the span gaps to only apply to the one data set (and not the other 9)?
Thank you for your help!
//I think the relevant data:
$scope.data = [
[{x:-100,y:-90},{x:-60,y:-10},{x:-50,y:0}],
[{x:-100,y:-80},{x:-50,y:-20},{x:0,y:0}],
[{x:-100,y:-70},{x:-40,y:-30},{x:0,y:0}],
[{x:-100,y:-60},{x:-30,y:-40},{x:0,y:0}],
[{x:-100,y:-50},{x:-20,y:-50},{x:0,y:0}],
[{x:-100,y:-40},{x:-30,y:-60},{x:0,y:0}],
[{x:-100,y:-30},{x:-40,y:-70},{x:0,y:0}],
[{x:-100,y:-20},{x:-50,y:-80},{x:0,y:0}],
[{x:-100,y:-10},{x:-60,y:-90},{x:0,y:0}],
[{x:-100,y:0},{x:-70,y:-100},{x:0,y:0}]
];
$scope.options = {
tooltips:{enabled:false},
elements:{
point:{
radius:0
},
line:{
tension:.25,
fill:false
}
},
scales: {
xAxes:[{
type:'logarithmic',
display:true,
ticks:{
min:10,
max:10000,
callback: function(...args) {
const value = Chart.Ticks.formatters.logarithmic.call(this, ...args);
if (value.length) {
return Number(value).toLocaleString()
}
return value;
}
},
}],
yAxes: [
{
id: 'y-axis-1',
ticks:{min:-20,max:20,stepSize:10},
type: 'linear',
display: true,
position: 'left'
}
]
}
};
Seems like you can add it in the specific dataset as an option in which you want it:
https://www.chartjs.org/docs/latest/charts/line.html?h=spangaps
Related
I have a chart.js graph that looks like this:
What I'm trying to do is remove this counter of the y-axis:
I read through the documentation and searched for it here on Stack Overflow, but I can't seem to find what I'm looking for.
Thank you in advance.
You can set the ticks display to false in the options object like this:
options: {
scales: {
yAxes: [{
ticks: {
display: false
}
}]
}
}
Will give this result:
You can also use the callback to return an ampty string as tick which as side effect also removes the horizontal grid lines like this
options: {
scales: {
yAxes: [{
ticks: {
callback: () => ('')
}
}]
}
}
result:
I'm trying to create a chart using chart.js like this one (for example):
https://thebreadoflifeblog.files.wordpress.com/2013/01/uk-age-pyramid.png
I tried multiple possibilities and so far, the best one I found is using a simple trick of merging two horizontalBar charts:
But there are actually some problems.
As I said, this is actually two different charts. I would like to have only one object.
I removed the yAxis. I could leave one to display the yAxis labels, but in that case, one of the two graphics will be smaller than the other one. I would like the labels to be displayed between both charts.
The chart on the left is using negative value to achieve the right to left bars. Is there a way to 'revert' an axis ? I saw there is a 'Scale' method, but it seems complicated for just reverting the axis...
I would like to know if there is something I can do to create such chart easier and, most important, as one unique chart.
I ran up against the same problems as you, and managed to fix it using React ChartJS' HorizontalBarChart: but only one ;-)
Try stacking the yAxis and adding two datasets, using the options property
const populationPyramidOptions = {
scales: {
yAxes: [{
stacked: true
}],
xAxes: [{
stacked: false
}]
}
<HorizontalBar data={chartData} options={populationPyramidOptions} />
You can get a pretty good result:
if you use directly chartjs check about the solution here:
https://github.com/nknganda/pyramid_chart_example
The syntax for the options is not compatible with chartjs > 3.x
Below the updated code:
options = {
plugins: {
tooltip: {
intersect: true,
callbacks: {
label: function(context) {
var label = context.dataset.label || '';
var value = context.formattedValue;
var positiveOnly = value < 0 ? -value : value;
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += positiveOnly
}
return label;
},
},
},
legend: {
position: "bottom",
},
},
responsive: true,
scales: {
x: {
stacked: false,
ticks: {
beginAtZero: true,
callback: (v) => {
return v < 0 ? -v : v;
},
},
},
y: {
stacked: true,
ticks: {
beginAtZero: true,
},
position: "left",
},
},
indexAxis: 'y'
}
Note that tooltips is now tooltip and inside plugins, alongside with legend.
xAxies and yAxies are x and y and no more a list.
You may find more in the official chartjs doc.
Dataset don't change as you only need to make your values negative.
I'm trying to figure out how to approach drawing this chart.
It looks like a stacked horizontal bar chart, but I'm having troubles with defining a datasets format for duration intervals. I still haven't found the right way to structure the data source to achieve this result.
Another option could be a line/scatter chart. And the final one is writing custom plugin and drawing this on a canvas manually, shape by shape. I would like to avoid this though :)
Any idea would be really helpful.
Thanks!
I found the way to work this out with the help of #John Go-Soco. Some very key pieces of the graph config are bellow. In short, each line is a separate dataset with two data points defining a start date and the end date.
const yMap = [ 'amlodipine', 'simvastatin', 'lisinopril' ];
const mapDataPoint = function(xValue, yValue) {
return {
x: xValue,
y: yMap.indexOf(yValue)
};
};
const config = {
type: 'line',
data: {
datasets: [
{
//other dataset config options here
data: [
mapDataPoint('1/1/2007', 'simvastatin'),
mapDataPoint('6/1/2010', 'simvastatin'),
]
},
{
//other dataset config options here
data: [
mapDataPoint('9/1/2010', 'simvastatin'),
mapDataPoint('11/1/2018', 'simvastatin'),
]
},
{
//other dataset config options here
data: [
mapDataPoint('1/1/2007', 'lisinopril'),
mapDataPoint('9/1/2015', 'lisinopril'),
]
},
{
//other dataset config options here
data: [
mapDataPoint('1/1/2014', 'amlodipine'),
mapDataPoint('11/1/2022', 'amlodipine'),
]
},
]
},
options: {
//other chart config options here
scales: {
xAxes: [
{
type: 'time',
time: {
unit: 'year',
round: 'day',
displayFormats: {
year: 'YYYY'
},
min: moment('2006', 'YYYY'),
max: moment('2019', 'YYYY')
},
}
],
yAxes: [
{
ticks: {
min: -1,
max: yMap.length,
//setting custom labels on the Y-axes
callback: function(value) {
return yMap[ value ];
}
}
}
]
}
},
};
const ctx = 'reference to your ctx here';
const chart = new Chart(ctx, config)
I've been having a hard time finding documentation that will show me all the possible features on how to control/customize a chart and it's properties.
I wanted to know if i am displaying data in a horizontalBar chart is there a way to get the long label text to wrap? My graph size is affected by that feature and i can't find a way that will allow me to wrap label text.
I also wanted to know is there a property so that i can control the actual width of the graph with bars and not affecting the vertical label width. So i can give more room for the vertical label text and less space for the graph part.
Here is how i am currently rendering my graph:
barChartOptions: any = {
scaleShowVerticalLines: false,
responsive: true,
scales: {
xAxes: [{
ticks: {
beginAtZero:true,
max: 100
}
}],
yAxes: [{
ticks: {
}
}]
},
tooltips:{
mode: 'point'
}
};
barChartLabels: string[] = [];
barChartType: string = 'horizontalBar';
barChartLegend: boolean = false;
barChartData: any[] = [];
data: any;
colorsOverride: Array<Color> = [{
backgroundColor: '#6aaf6a',
hoverBackgroundColor: 'purple'
}];
getChartData(link:string){
this.service.getQuery(link).subscribe(
data => {
this.data = data;
this.barChartLabels = this.data.map(x => x.display);
this.chartData = this.data.map(x => x.value);
this.barChartData = [{data: this.chartData, label:'sample' }];
}
);
}
I have a Bar Chart with this Option
scales: {
yAxes: [{
ticks: {
display:false,
beginAtZero:true,
max: 1150
}
}]
}
now i change the values of my only dataset
barChartData.datasets[0].data = newData;
and update the chart
window.myBar.update();
How can i also update the max scale of the yAxes??
I have to use a max scale so i cant use suggestedMax.
found the Solution myself.
to change any options of the chart:
myBar.config.options
in my case
myBar.config.options.scales.yAxes[0].ticks.max = newValue
after this you have to call
window.myBar.update();
This is my solution for Line Chart.
You can use 'beforeFit' callback function that you can find here in the docs http://www.chartjs.org/docs/latest/axes/
In scale.chart.config.data.datasets you have the chart dataset
You must set the scale.options.ticks.max
Example:
scales: {
yAxes: [{
beforeFit: function (scale) {
// See what you can set in scale parameter
console.log(scale)
// Find max value in your dataset
let maxValue = 0
if (scale.chart.config && scale.chart.config.data && scale.chart.config.data.datasets) {
scale.chart.config.data.datasets.forEach(dataset => {
if (dataset && dataset.data) {
dataset.data.forEach(value => {
if (value > maxValue) {
maxValue = value
}
})
}
})
}
// After, set max option !!!
scale.options.ticks.max = maxValue
}
}
I hope I've been helpful.
The link https://www.chartjs.org/docs/latest/developers/updates.html has pretty up to date information.
the keey is to recognise what the chart object is. :)
I struggled for half a day reading various pages until i found the right way
use the baseChartDirective to access the chart directly by doing this -> this.chart
To update scales do this:
var barChartOptions = {
legend: { display: true },
scales: { yAxes: [{ id: 'yaxis', type: 'linear', position: 'left', ticks: { min: 0, max: maxScale } }]} };
this.chart.chart.options = barChartOptions;
then update the chart:
this.chart.chart.update();
you can pretty much update everything. Just need to realise what the chart object means in this page: https://www.chartjs.org/docs/latest/developers/updates.html
:)