gpt4 book ai didi

Adding Minor Gridlines in Logarithmic Chart in Charts.Js v2.9.4(在图表中的对数图中添加次要网格线。Js v2.9.4)

转载 作者:bug小助手 更新时间:2023-10-25 11:16:46 29 4
gpt4 key购买 nike



I want to draw minor gridlines in the chart drawn by the following below to get the result similar to x-axis in following image (except instead of tick value shown in simple number instead of power i.e. instead 10^0 it should show 1 and instead of 10^1 it should show 10 and so on. Image is os meant to show just the gridlines on x-axis):

我想在下面绘制的图表中绘制次要的网格线,以获得与下图中的x轴类似的结果(除了用简单的数字而不是幂表示的刻度值,即10^0应该显示1,而不是10^1,应该显示10等等)。图像仅用于显示x轴上的网格线):


Log Gridline Image




<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html>
<head>
<title>Chart</title>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=Edge'>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-colorschemes"></script>
<style>
body { margin: 0; padding: 0; }
#container { width: 100%; }
</style>
</head>
<body>
<div id='container'>
<canvas id='myChart'></canvas>
</div>
<script>
Chart.defaults.global.animation.duration = 1000;
Chart.defaults.global.animation.easing = 'linear';
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['10','2000','30000','50000','60000','700000',],
datasets: [
{label: 'ABC' ,
fill: true ,
data: [
{ x: '10', y: 2 },
{ x: '2000', y: 4 },
{ x: '30000', y: 7 },
{ x: '50000', y: 8 },
{ x: '60000', y: 8.5 },
{ x: '700000', y: 9 }
],
borderWidth: 1},
]
},
options: {
aspectRatio: 1.6,
title: {
display: true,
position: 'top',
text: 'Ref Data'
},
legend: {
display: true,
position: 'right',
},
scales: {
yAxes: [{
id: 'first-y-Axis',
display: true,
scaleLabel: {
display: true,
labelString: 'Demo y-axis'
}
}],
xAxes: [{
id: 'first-x-Axis',
display: true,
type: 'logarithmic',
scaleLabel: {
display: true,
labelString: 'Demo x-axis'
},
ticks: {
//min: 0 ,
//max: 700000
callback: function (value, index, values) {
if (Math.log10(value) % 1 === 0) { return value; }
}
}
}]
},
plugins: {
colorschemes: {
scheme: 'brewer.Paired12'
}
}
}
});
</script>
</body>
</html>




Similar solution is also discussed in the post linked here but the code used in that post is very complex and I am unable to understand and make it work in my code as I don't know much about JavaScript. Just trying to make this graph for ine application. I'll thankful if someone here can modify my code or help me modify the code to get minor gridlines like the image or in the post linked above (except minor gridlines are created for y-axis in the post but I want for x-axis).

在这里链接的帖子中也讨论了类似的解决方案,但帖子中使用的代码非常复杂,我无法理解并在我的代码中使其工作,因为我对JavaScript了解不多。我只是想把这张图画出来,供我们应用。如果有人能修改我的代码或帮我修改代码,以获得像上面链接的图像或帖子中的次要网格线,我将非常感激(除了次要网格线是为帖子中的y轴创建的,但我想要的是x轴)。


Best Regards

诚挚的问候


更多回答

As stated at very beginning of the post you linked to, you don't have to do anything to have minor grid lines other than make sure your ticks callback returns "" (an empty string), for those ticks that don't have a label. The code in that post was about styling the minor lines and filtering the occasional unwanted grid line at such values as 15 or 150.

正如你链接到的帖子的开头所说的,除了确保你的ticks回调为那些没有标签的ticks返回“”(一个空字符串)之外,你不需要做任何事情来拥有次要的网格线。这篇文章中的代码是关于设置次要线条的样式,并以15或150等值过滤偶尔不需要的网格线。

I also want to make to make minute gridlines thinner (and dashed) than the major one. I didn't lot of time we to copy paste the code from the linked post and tried to adjust it at various locations in my code but none worked. Can you help me in that too.

我还想让微小的网格线比主要的网格线更细(和虚线)。我没有花很多时间从链接的帖子中复制粘贴代码,并试图在我的代码中的不同位置调整它,但都没有奏效。你也能在这方面帮我吗?

优秀答案推荐

As was the case in the OP linked post (which was designed for the latest chart.js v4), it is still valid for chart.js v2+ that minor grid lines are created if ticks.callback returns an empty string instead of null or undefined (or if there's no ticks.callback).

与OP链接的POST(它是为最新的chart.js v4设计的)中的情况一样,如果ticks.allback返回空字符串而不是NULL或未定义(或者如果没有ticks.allback),则创建次要网格线对于chart.js v2+仍然有效。


However, there are differences in the way one may style the minor grid lines to differentiate them from major ones. In chart.js v2.9.4 scales' gridLines options are not scriptable. This calls for a different approach, one that might in some cases be useful for newer versions: using indexable options,
which means that one has to create an array with a (different) value for each item - in this case for each grid line. Since the ticks are only known at runtime, one can create that array in an axis callback, e.g., in afterBuildTicks:

但是,为将次要轴网线与主要轴网线区分开来而设置次要轴网线样式的方式存在差异。在chart.js v2.9.4中,scales的gridLines选项不可脚本化。这需要一种不同的方法,在某些情况下可能对较新的版本有用:使用可索引选项,这意味着必须为每个项目创建一个(不同)值的数组-在这种情况下为每个网格线。由于刻度只在运行时才知道,因此可以在轴回调中创建该数组,例如,在afterBuildTicks中:


afterBuildTicks(scale){
const nTicks = scale.ticks.length,
isMajor = scale.ticks.map(value => ('' + value).replace(/0+$/, '') === '1');
scale.options.gridLines.lineWidth =
Array.from({length: nTicks}, (_, i) => isMajor[i] ? 1.2 : 0.5);
scale.options.gridLines.color =
Array.from({length: nTicks}, (_, i) => isMajor[i] ? '#000' : '#ddd');
//scale.options.gridLines.borderDash - can't be set as an array of arrays
}

Unfortunately, this approach doesn't seem to work for borderDash.

不幸的是,这种方法似乎不适用于borderDash。




I'll give some details about what exactly how this function works: using an indexable option, let's say gridLines.lineWidth, means we set its value as an array:

我将详细介绍该函数的具体工作方式:使用可索引选项,比如gridLines.lineWidth,这意味着我们将其值设置为数组:


gridLines:{
lineWidth: [1.2, 0.5, 0.5, 0.5, 0.5, 1.2, 0.5, .......]
}

The problem is that the ticks are built by chart.js from the data, we don't know beforehand how many ticks there are in total and how many and where are the major ones. So we have to wait for chart.js to build those ticks and then, in the handler automatically called immediately after the ticks are built, afterBuildTicks, we set the grid line properties, based on the actual tick values. This makes sense, since the gridlines are drawn after the ticks were built.

问题是,tick是由chart.js根据数据构建的,我们事先不知道总共有多少tick,主要的tick有多少和在哪里。因此,我们必须等待chart.js构建这些刻度,然后,在构建刻度之后立即自动调用的处理程序中,在BuildTicks之后,我们根据实际的刻度值设置网格线属性。这是有意义的,因为网格线是在创建记号之后绘制的。


The function afterBuildTicks receives as an argument the scale object, from which we extract the ticks as scale.ticks. Then we decide which ticks will be "major" - to be drawn with a thicker line - the definition I used is that the string representation is a 1 fallowed by 0s. An alternative, mathematical formulation can be devised, using Math.log10.

BuildTicks之后的函数接收Scale对象作为参数,我们从该对象中提取tick作为scale.ticks。然后我们决定哪些刻度将是“主要的”-用更粗的线绘制-我使用的定义是字符串表示是0允许的1。使用Math.log10可以设计出另一种数学公式。


Now, we know how many ticks there are and where are the major ones so we can build the array introduced above for gridLines.lineWidth. The function Array.from is used; alternatively, we could have used isMajor.map with the same functions.

现在,我们知道有多少个记号,主要的记号在哪里,这样我们就可以构建上面介绍的GridLines.lineWidth数组。使用函数Array.from;或者,我们可以使用具有相同函数的isMajor.map。




Code snippet:

代码片段:




Chart.defaults.global.animation.duration = 1000;
Chart.defaults.global.animation.easing = 'linear';
const ctx = document.getElementById('myChart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: ['10', '2000', '30000', '50000', '60000', '700000',],
datasets: [{
label: 'ABC',
fill: true,
data: [{
x: '10',
y: 2
},
{
x: '2000',
y: 4
},
{
x: '30000',
y: 7
},
{
x: '50000',
y: 8
},
{
x: '60000',
y: 8.5
},
{
x: '700000',
y: 9
}
],
borderWidth: 1
},]
},
options: {
aspectRatio: 1.6,
title: {
display: true,
position: 'top',
text: 'Ref Data'
},
legend: {
display: true,
position: 'right',
},
scales: {
yAxes: [{
id: 'first-y-Axis',
display: true,
scaleLabel: {
display: true,
labelString: 'Demo y-axis'
}
}],
xAxes: [{
id: 'first-x-Axis',
display: true,
type: 'logarithmic',
scaleLabel: {
display: true,
labelString: 'Demo x-axis'
},
gridLines: {
borderDash: [10, 3],
drawTicks: false,
drawBorder: false
},
afterBuildTicks(scale){
const nTicks = scale.ticks.length,
isMajor = scale.ticks.map(value => ('' + value).charAt(0) === '1');
scale.options.gridLines.lineWidth = Array.from({length: nTicks}, (_, i) => isMajor[i] ? 1.2 : 0.5);
scale.options.gridLines.color = Array.from({length: nTicks}, (_, i) => isMajor[i] ? '#000' : '#ddd');
//scale.options.gridLines.borderDash - can't be set as an array of arrays
},
ticks: {
padding: 5,
autoSkip: false,
maxRotation: 0,
callback: function(value, index, values){
if(Math.log10(value) % 1 === 0){
return value;
}
return '';
}
}
}]
},
plugins: {
colorschemes: {
scheme: 'brewer.Paired12'
}
}
}
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"
integrity="sha512-SuxO9djzjML6b9w9/I07IWnLnQhgyYVSpHZx0JV97kGBfTIsUYlWflyuW4ypnvhBrslz1yJ3R+S14fdCWmSmSA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-colorschemes"></script>
<div style="min-height: 60vh">
<canvas id="myChart">
</canvas>
</div>






Per request, a version that should work in Internet Explorer and older browsers:

根据请求,应提供一个可在Internet Explorer和更早版本的浏览器中使用的版本:


afterBuildTicks: function(scale){
var nTicks = scale.ticks.length,
isMajor = scale.ticks.map(function(value){return ('' + value).replace(/0+$/, '') === '1';});
scale.options.gridLines.lineWidth =
isMajor.map(function(_, i){return isMajor[i] ? 1.2 : 0.5;})
scale.options.gridLines.color =
isMajor.map(function(_, i){return isMajor[i] ? '#000' : '#ddd';});
//scale.options.gridLines.borderDash - can't be set as an array of arrays
}

and the full code in jsFiddle

和jsFidel中的完整代码


更多回答

if want to do the same then xScale will be changed to yScale in the above code? Can you share some guide link on which I can understand how this code is functioning to make think/thin major/minor grids so that I can learn it?

如果想做同样的事情,那么在上面的代码中,xScale将被更改为yScale?你能分享一些指南链接,让我了解这段代码是如何运作的,使思考/瘦主要/次要网格,这样我就可以学习它?

Yes, it should work the same, just use the afterBuildTicks function for the other axis. I'll try to write another paragraph explaining what it's doing.

是的,它应该是一样的,只需对另一个轴使用After BuildTicks函数即可。我会试着写另一段话来解释它在做什么。

The code above was working fine in run code snippet but when I made html file of this code and run in internet explorer, it don't run and in the debugging, it says expected ':' line xx:colxx (ie. right after word afterBuildTicks. I need it for internet explorer because I am using this code to generate chart in Microsoft Access webBrowser control that actually IE11. Can you help me make this compatible with IE11. Sorry for sharing this info late because I didn't know that time that would make any difference.

上面的代码在运行代码片段中运行得很好,但当我将此代码制作为html文件并在Internet Explorer中运行时,它没有运行,并且在调试中,它显示预期的xx:colxx(即.就在BuildTicks之后的单词之后。我需要它的IE浏览器,因为我正在使用这段代码来生成图表在Microsoft Access WebBrowser控件,实际上是IE11。你能帮我使它与IE11兼容吗?很抱歉这么晚才分享这个信息,因为我不知道那个时间会有什么不同。

I was using newer syntax for functions inside objects; to cover IE and other browsers replace afterBuildTicks(scale){ with afterBuildTicks: function(scale){. Also, Array.from and arrow functions might not work. I added a version for IE and older browsers, please let me know if it works, I don't have a windows machine to test it in IE.

我对对象内部的函数使用了较新的语法;为了涵盖IE和其他浏览器,将After BuildTicks(Scale){替换为After BuildTicks:Function(Scale){。此外,Array.From和Arrow函数可能不起作用。我为IE和更老的浏览器添加了一个版本,请让我知道它是否有效,我没有Windows机器来在IE中测试它。

I have tried now and it is working. It was my mistake, I left Math.log10 function that was not supported by IE too there which was causing issue. I used the code from jsfiddle and replace Math.log10 function with my custom function and now it is working fine. Thanks a lot.

我已经试过了,它正在工作。这是我的错误,我离开了Math.log10函数,IE也不支持,这导致了问题。我使用了jsfiddle的代码,并将Math.log10函数替换为我的自定义函数,现在它工作得很好。非常感谢.

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com