I am using chart-js v 3.6 together with ng2-charts in an Angular 12 Project.
The chart is a simple line chart but with multiple y axes. I was trying to implement the same kind of callback function as in this question or as shown in the official documents:
How to change the Y-axis values from numbers to strings in Chart.js?
https://www.chartjs.org/docs/3.2.1/axes/labelling.html#creating-custom-tick-formats
the final chartOptions look like this:
options: {
scales: {
x: {
offset: true
},
y1: {
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, values) {
return '$' + value;
}
}
}
}
It seems to work if you are not using multiple y axis with just 'y' however with 'y1' as key it does not do anything. The callback function is showing in the final chart object however no changes in template.
If somebody has a hint where I can find a way to implement or a working sample, which does include multiple y axis this would be great.
As I am working on that chart on a different environment, I cannot access or copy the code freely, so I cannot show the current way of implementation.
Related
I am using Apache ECharts to create a line chart with an Y Axis of type "value" and an X Axis of type "time". I am also implementing dataZoom on the X Axis, which is working correctly. The problem is that when I move the dataZoom a bit, this happens:
My data consist of series with actual Date objects for the X axis, like:
Then, I have the following config for the X Axis. As you can see, I have specified a formatter in the Axis to convert dates to strings, which also works correctly.
Finally, my DataZoom config is just:
{ dataZoom: [{}] }
I am setting the same config as other time charts in ECharts official examples, but I am still getting this error. Any ideas?
xAxis: {
axisLabel: {
hideOverlap: true,
}
}
This should solve the overlapping issue.
I am creating a parallel coordinates plot using d3.js, but am struggling to format axis labeling as I would like.
For instance, one of my axes, 'Buffer Concentration', is plotted on a log scale, which I've specified through the dimensions variable, like so.
var dimensions = [
...
{
key: "b.Conc",
description: "Buffer Concentration",
type: types["Number"],
scale: d3.scale.log().domain([.1, 100]).range([innerHeight, 0]),
tickValues: [.1,.2,.4,.6,.8,1,2,4,6,8,10,20,40,60],
tickFormat: d3.format(4,d3.format(",d"))
},
...
];
However, as you can see from the resulting plot below, my attempt to specify which tick labels are shown (through tickValues) and that they be shown as ordinary numbers rather than powers of 10 (through tickFormat) are not working. Additionally, the axis does not span the domain I specified in scale; it should be [0.1, 100], not [0.1, 60].
Why is this?
Code
The data.csv, index.html and style.css files for my plot can be found here. When opening locally, it [only] works in Firefox.
Thanks in advance for any help, and apologies if I'm missing something basic - I'm new to d3.
It seems that you forgot to apply custom ticks and tick values to generated scales in this line: https://gist.github.com/LThorburn/5f2ce7d9328496b5f4c123affee8672f#file-index-html-L189
Not sure, but smth like this should help.
if (d.tickValues) {
renderAxis.tickValues(d.tickValues);
}
if (d.tickFormat) {
renderAxis.tickFormat(d.tickFormat);
}
Marion's fiddle, which perfectly shows multiple distinct points for multiple series.
Following this, I'm trying to implement the same in my fiddle.
I have 2 Name fields PaidDataAxis and DeniedDataAxis
I'm returning series based on this only:
customizeSeries: function(seriesName) {
if (seriesName === 'PaidDataAxis') {
return {
axis: 'paid'
}
} else {
return {
axis: 'denied'
}
}
}
MarkerType which is a tagField is not required.
Both the series along with their points are getting rendered. However, I see that the points are overlapping.
How to avoid series points overlapping in dxChart in this case?
There's something stupid I'm doing, but unable to figure out where.
The solution in such case is to apply min on valueAxis and/or argumentAxis
valueType: 'numeric', //for staying safer
min: 0,
Without which, dxChart will try to automatically calculate axes' scale
I have a bar chart in c3js that uses category ticks on the x-axis.
The tick values I want to display are set upon loading the chart:
axis: {
x: {
tick:{
rotate: -35,
values: getTicks(displayData), //Return the tick values
multiline:false
},
type: 'categorized'
}
}
The reason for setting the ticks manually on load, is I need to update them later.
I need to allow users to update the x axis range dynamically, without loading new data, and I want the number of ticks displayed to remain the same, but with different values obviously.
To change the x axis range, I use this function:
chart.axis.range({min: {x: minRange}, max: {x: maxRange}});
There is no function called chart.axis.values.
Any ideas on how to change tick values dynamically?
EDIT -
To be really clear, I do not wish to update the chart's values. That includes the x and y axis values. I only wish to change what ticks are displayed.
Something like this should work.
axis: {
x: {
type: 'timeseries',
tick: {
values: function(x) { return customTicks(x) },
format: function(x) { return customFormat(x); },
}
}
}
customTicks() must return an array of Dates for this to work.
function customTicks(x) {
start = x[0];
end = x[1];
result = [];
for (var i = new Date(start); i <= end; i.setDate(i.getDate() + 1)) {
result.push(new Date(i));
}
return result;
}
customFormat() takes the date and returns the string for that date. This gives you the flexibility to customize the format as needed.
function customFormat(x) {
}
It may not be particularly elegant but does the job. One benefit of this approach is that you can use the same functions on more than one chart and they will all exhibit identical behavior always.
Problem #1 with this approach is that it seems to call customTicks() for every data point just as it does for customFormat().
Problem #2 is that it generates a lot of these errors:
d3.v3.min.js:1 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
This has already been flagged on Stackoverflow at Added non-passive event listener to a scroll-blocking 'touchstart' event
I am having the same difficulty updating the Y-Axis ticks values dynamically. I searched through the c3.js documents and was expecting to get something like chart.axis.values similar to chart.axis.range or chart.axis.max / chart.axis.min.
After digging into the Chart object on the console. I somehow managed to resolve my problem, but with a bit hacky way.
Please check the fiddle, I have played with the chart.internal which contains the chart's values on which graph is plotted. I changed those values and used chart.flush() method to redraw the chart.
According to https://github.com/c3js/c3/issues/827:
chart.internal.config.axis_x_tick_values = getTicks(displayData);
This works for me.
I am uisng tickPositioner to plot certain dates on X Axis.
xAxis: {
......
tickPositioner: function(min, max) {
// custom function which returns dates array.
return getDatesBetweenRange(min, max);
},
.....
}
using Highstock v1.2.5.
I also have Show/Hide series option in the Legend. It works fine no issues till here.
Now, When I hide any series from the chart.
I do not want to show those dates on x Axis who have no data as the series is hidden.
I was looking into source code at "getOffset:" method where Label is being created for each
Tick.
Is there any relation in API which returns all series points for this Tick ?
Or
Is there any relation in API that says that this tick pos (e.g. date) has no data visible ?
As I know, you can use a little different solution:
In tickPositioner you have access to all series for specific axis via this.series. Now, each of these series have xData which contains all x-values. All you need to do now is check if series is visible, and then compare your tick values (generated by getDatesBetweenrange()) with values in xData arrays - and return only these values which could be find there.