使用 dygraphs 时如何反转图例项的顺序?
How to reverse the order of legend Items when using dygraphs?
我有一系列的 5 个面积图要绘制在一个图中。我正在为此使用 dygraphs。
我希望图例以相反的顺序显示,但我不想更改我的 .csv 文件。我没有在 dygraphs 文档页面中找到任何解决此问题的方法。
请帮我出路。
代码如下所示:
<script type="text/javascript" src="dygraph.js"></script>
<link rel="stylesheet" src="dygraph.css" />
<div id="graphdiv3" style="width:1000px; height:300px;"></div>
<div id="status", class="status"></div>
<script>
var g3 = new Dygraph(
document.getElementById("graphdiv3"),
"data/area.csv",
{labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
}
)
您可以使用 flex
并反转 flex-direction
:
var csv = btoa(`Year-month,class1,class2,class3,class5,class6
1982-01-01,0.617100372,2.669144981,6.43866171,17.15241636,30.49070632
1982-02-01,0.081784387,1.278810409,3.955390335,12.29739777,24.58736059
1982-03-01,0.104089219,0.996282528,3.568773234,11.98513011,21.81412639
1982-04-01,0.022304833,0.505576208,2.453531599,9.56133829,19.97769517
1982-05-01,0.215613383,2.066914498,7.152416357,18.47583643,31.21189591
1982-06-01,0.133828996,1.144981413,4.29739777,15.53159851,29.40520446
1982-07-01,3.910780669,8.505576208,16.69144981,35.10037175,48.4535316
1982-08-01,0.609665428,3.353159851,8.698884758,21.0260223,31.81412639
1982-09-01,2.579925651,6.059479554,12.95910781,29.91821561,43.04089219
1982-10-01,4.661710037,10.73605948,20.92193309,39.18215613,52.46096654
1982-11-01,0.713754647,2.750929368,7.420074349,17.23420074,27.67286245
1982-12-01,0.795539033,2.788104089,7.31598513,18.04460967,29.76951673`);
var g3 = new Dygraph(
document.getElementById("graphdiv3"),
'data:application/text+csv;base64,' + csv, {
labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
}
)
#status {display:flex; flex-direction:column-reverse}
#status span {order:-1}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.css" rel="stylesheet" />
<div id="graphdiv3" style="width:1000px; height:300px;"></div>
<div id="status" class="status"></div>
legendFormatter
选项可让您根据自己的喜好自定义图例格式。在这种情况下,您可以调用默认格式化程序,然后反转这些行。您需要注意在可见时将 x 轴标签保持在顶部(假设这是所需的行为):
function legendFormatter(data, ...args) {
const html = Dygraph.Plugins.Legend.defaultFormatter(data, ...args);
let lines = html.split(/<br\/?>/);
if (data.x == null) {
lines.reverse();
} else {
lines = [lines[0], ...lines.slice(1).reverse()];
}
return lines.join('<br>');
}
var csv = btoa(`Year-month,class1,class2,class3,class5,class6
1982-01-01,0.617100372,2.669144981,6.43866171,17.15241636,30.49070632
1982-02-01,0.081784387,1.278810409,3.955390335,12.29739777,24.58736059
1982-03-01,0.104089219,0.996282528,3.568773234,11.98513011,21.81412639
1982-04-01,0.022304833,0.505576208,2.453531599,9.56133829,19.97769517
1982-05-01,0.215613383,2.066914498,7.152416357,18.47583643,31.21189591
1982-06-01,0.133828996,1.144981413,4.29739777,15.53159851,29.40520446
1982-07-01,3.910780669,8.505576208,16.69144981,35.10037175,48.4535316
1982-08-01,0.609665428,3.353159851,8.698884758,21.0260223,31.81412639
1982-09-01,2.579925651,6.059479554,12.95910781,29.91821561,43.04089219
1982-10-01,4.661710037,10.73605948,20.92193309,39.18215613,52.46096654
1982-11-01,0.713754647,2.750929368,7.420074349,17.23420074,27.67286245
1982-12-01,0.795539033,2.788104089,7.31598513,18.04460967,29.76951673`);
var g3 = new Dygraph(
document.getElementById("graphdiv3"),
'data:application/text+csv;base64,' + csv, {
labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
legendFormatter: legendFormatter
}
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.css" rel="stylesheet" />
<div id="graphdiv3" style="width:1000px; height:300px;"></div>
<div id="status" class="status"></div>
对于更复杂的转换,您最好建设性地构建 HTML。查看 legendFormatter demo 上的源代码以获取示例。
您可以提供自己的自定义图例渲染器,但 Kosh 的 CSS 改动要简单得多。
无论如何,如果你看一下 Dygraph 源代码,你会注意到在静态 Legend.generateLegendHTML
函数的最后,有一个选项检查:g.getOption('legendFormatter')
。
这意味着您可以提供自己的 Legend.defaultFormatter
版本。
我所做的只是更改引用 data.series
的两个位置并改为调用 data.series.reverse()
。另外,我让它变得更活泼一点,让它对 ES6 更友好。
{
legendFormatter: reverseLegendFormatter
}
const csv = btoa(`Year-month,class1,class2,class3,class5,class6
1982-01-01,0.617100372,2.669144981,6.43866171,17.15241636,30.49070632
1982-02-01,0.081784387,1.278810409,3.955390335,12.29739777,24.58736059
1982-03-01,0.104089219,0.996282528,3.568773234,11.98513011,21.81412639
1982-04-01,0.022304833,0.505576208,2.453531599,9.56133829,19.97769517
1982-05-01,0.215613383,2.066914498,7.152416357,18.47583643,31.21189591
1982-06-01,0.133828996,1.144981413,4.29739777,15.53159851,29.40520446
1982-07-01,3.910780669,8.505576208,16.69144981,35.10037175,48.4535316
1982-08-01,0.609665428,3.353159851,8.698884758,21.0260223,31.81412639
1982-09-01,2.579925651,6.059479554,12.95910781,29.91821561,43.04089219
1982-10-01,4.661710037,10.73605948,20.92193309,39.18215613,52.46096654
1982-11-01,0.713754647,2.750929368,7.420074349,17.23420074,27.67286245
1982-12-01,0.795539033,2.788104089,7.31598513,18.04460967,29.76951673`);
const g3 = new Dygraph(
document.getElementById("graphdiv3"),
'data:application/text+csv;base64,' + csv, {
labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
legendFormatter: reverseLegendFormatter
}
)
function reverseLegendFormatter(data) {
let g = data.dygraph;
if (g.getOption('showLabelsOnHighlight') !== true) return '';
let sepLines = g.getOption('labelsSeparateLines'), htmlLines = [];
if (typeof data.x === 'undefined') {
if (g.getOption('legend') != 'always') return '';
data.series.reverse()
.filter(series => series.isVisible)
.forEach(series => {
htmlLines.push(`
<span style="font-weight:bold; color:${series.color}">
${series.dashHTML} ${series.labelHTML}
</span>
`);
});
} else {
htmlLines.push(`${data.xHTML}:`);
data.series.reverse()
.filter(series => series.isVisible)
.forEach(series => {
htmlLines.push(`
<span${ series.isHighlighted ? ' class="highlight"' : '' }>
<b><span style="color: ${series.color}">${series.labelHTML}</span></b>:
 ${series.yHTML}
</span>
`);
});
}
return htmlLines.join(sepLines ? '<br />' : '');
}
演示
const csv = btoa(`Year-month,class1,class2,class3,class5,class6
1982-01-01,0.617100372,2.669144981,6.43866171,17.15241636,30.49070632
1982-02-01,0.081784387,1.278810409,3.955390335,12.29739777,24.58736059
1982-03-01,0.104089219,0.996282528,3.568773234,11.98513011,21.81412639
1982-04-01,0.022304833,0.505576208,2.453531599,9.56133829,19.97769517
1982-05-01,0.215613383,2.066914498,7.152416357,18.47583643,31.21189591
1982-06-01,0.133828996,1.144981413,4.29739777,15.53159851,29.40520446
1982-07-01,3.910780669,8.505576208,16.69144981,35.10037175,48.4535316
1982-08-01,0.609665428,3.353159851,8.698884758,21.0260223,31.81412639
1982-09-01,2.579925651,6.059479554,12.95910781,29.91821561,43.04089219
1982-10-01,4.661710037,10.73605948,20.92193309,39.18215613,52.46096654
1982-11-01,0.713754647,2.750929368,7.420074349,17.23420074,27.67286245
1982-12-01,0.795539033,2.788104089,7.31598513,18.04460967,29.76951673`);
const g3 = new Dygraph(
document.getElementById("graphdiv3"),
'data:application/text+csv;base64,' + csv, {
labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
legendFormatter: reverseLegendFormatter,
labelsSeparateLines: false // Really shines here!
}
)
function reverseLegendFormatter(data) {
let g = data.dygraph;
if (g.getOption('showLabelsOnHighlight') !== true) return '';
let sepLines = g.getOption('labelsSeparateLines'), htmlLines = [];
if (typeof data.x === 'undefined') {
if (g.getOption('legend') != 'always') return '';
data.series.reverse()
.filter(series => series.isVisible)
.forEach(series => {
htmlLines.push(`
<span style="font-weight:bold; color:${series.color}">
${series.dashHTML} ${series.labelHTML}
</span>
`);
});
} else {
htmlLines.push(`${data.xHTML}:`);
data.series.reverse()
.filter(series => series.isVisible)
.forEach(series => {
htmlLines.push(`
<span${ series.isHighlighted ? ' class="highlight"' : '' }>
<b><span style="color: ${series.color}">${series.labelHTML}</span></b>:
 ${series.yHTML}
</span>
`);
});
}
return htmlLines.join(sepLines ? '<br />' : '');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.css" rel="stylesheet" />
<div id="graphdiv3" style="width:1000px; height:300px;"></div>
<div id="status" class="status"></div>
我有一系列的 5 个面积图要绘制在一个图中。我正在为此使用 dygraphs。
我希望图例以相反的顺序显示,但我不想更改我的 .csv 文件。我没有在 dygraphs 文档页面中找到任何解决此问题的方法。
请帮我出路。
代码如下所示:
<script type="text/javascript" src="dygraph.js"></script>
<link rel="stylesheet" src="dygraph.css" />
<div id="graphdiv3" style="width:1000px; height:300px;"></div>
<div id="status", class="status"></div>
<script>
var g3 = new Dygraph(
document.getElementById("graphdiv3"),
"data/area.csv",
{labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
}
)
您可以使用 flex
并反转 flex-direction
:
var csv = btoa(`Year-month,class1,class2,class3,class5,class6
1982-01-01,0.617100372,2.669144981,6.43866171,17.15241636,30.49070632
1982-02-01,0.081784387,1.278810409,3.955390335,12.29739777,24.58736059
1982-03-01,0.104089219,0.996282528,3.568773234,11.98513011,21.81412639
1982-04-01,0.022304833,0.505576208,2.453531599,9.56133829,19.97769517
1982-05-01,0.215613383,2.066914498,7.152416357,18.47583643,31.21189591
1982-06-01,0.133828996,1.144981413,4.29739777,15.53159851,29.40520446
1982-07-01,3.910780669,8.505576208,16.69144981,35.10037175,48.4535316
1982-08-01,0.609665428,3.353159851,8.698884758,21.0260223,31.81412639
1982-09-01,2.579925651,6.059479554,12.95910781,29.91821561,43.04089219
1982-10-01,4.661710037,10.73605948,20.92193309,39.18215613,52.46096654
1982-11-01,0.713754647,2.750929368,7.420074349,17.23420074,27.67286245
1982-12-01,0.795539033,2.788104089,7.31598513,18.04460967,29.76951673`);
var g3 = new Dygraph(
document.getElementById("graphdiv3"),
'data:application/text+csv;base64,' + csv, {
labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
}
)
#status {display:flex; flex-direction:column-reverse}
#status span {order:-1}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.css" rel="stylesheet" />
<div id="graphdiv3" style="width:1000px; height:300px;"></div>
<div id="status" class="status"></div>
legendFormatter
选项可让您根据自己的喜好自定义图例格式。在这种情况下,您可以调用默认格式化程序,然后反转这些行。您需要注意在可见时将 x 轴标签保持在顶部(假设这是所需的行为):
function legendFormatter(data, ...args) {
const html = Dygraph.Plugins.Legend.defaultFormatter(data, ...args);
let lines = html.split(/<br\/?>/);
if (data.x == null) {
lines.reverse();
} else {
lines = [lines[0], ...lines.slice(1).reverse()];
}
return lines.join('<br>');
}
var csv = btoa(`Year-month,class1,class2,class3,class5,class6
1982-01-01,0.617100372,2.669144981,6.43866171,17.15241636,30.49070632
1982-02-01,0.081784387,1.278810409,3.955390335,12.29739777,24.58736059
1982-03-01,0.104089219,0.996282528,3.568773234,11.98513011,21.81412639
1982-04-01,0.022304833,0.505576208,2.453531599,9.56133829,19.97769517
1982-05-01,0.215613383,2.066914498,7.152416357,18.47583643,31.21189591
1982-06-01,0.133828996,1.144981413,4.29739777,15.53159851,29.40520446
1982-07-01,3.910780669,8.505576208,16.69144981,35.10037175,48.4535316
1982-08-01,0.609665428,3.353159851,8.698884758,21.0260223,31.81412639
1982-09-01,2.579925651,6.059479554,12.95910781,29.91821561,43.04089219
1982-10-01,4.661710037,10.73605948,20.92193309,39.18215613,52.46096654
1982-11-01,0.713754647,2.750929368,7.420074349,17.23420074,27.67286245
1982-12-01,0.795539033,2.788104089,7.31598513,18.04460967,29.76951673`);
var g3 = new Dygraph(
document.getElementById("graphdiv3"),
'data:application/text+csv;base64,' + csv, {
labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
legendFormatter: legendFormatter
}
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.css" rel="stylesheet" />
<div id="graphdiv3" style="width:1000px; height:300px;"></div>
<div id="status" class="status"></div>
对于更复杂的转换,您最好建设性地构建 HTML。查看 legendFormatter demo 上的源代码以获取示例。
您可以提供自己的自定义图例渲染器,但 Kosh 的 CSS 改动要简单得多。
无论如何,如果你看一下 Dygraph 源代码,你会注意到在静态 Legend.generateLegendHTML
函数的最后,有一个选项检查:g.getOption('legendFormatter')
。
这意味着您可以提供自己的 Legend.defaultFormatter
版本。
我所做的只是更改引用 data.series
的两个位置并改为调用 data.series.reverse()
。另外,我让它变得更活泼一点,让它对 ES6 更友好。
{
legendFormatter: reverseLegendFormatter
}
const csv = btoa(`Year-month,class1,class2,class3,class5,class6
1982-01-01,0.617100372,2.669144981,6.43866171,17.15241636,30.49070632
1982-02-01,0.081784387,1.278810409,3.955390335,12.29739777,24.58736059
1982-03-01,0.104089219,0.996282528,3.568773234,11.98513011,21.81412639
1982-04-01,0.022304833,0.505576208,2.453531599,9.56133829,19.97769517
1982-05-01,0.215613383,2.066914498,7.152416357,18.47583643,31.21189591
1982-06-01,0.133828996,1.144981413,4.29739777,15.53159851,29.40520446
1982-07-01,3.910780669,8.505576208,16.69144981,35.10037175,48.4535316
1982-08-01,0.609665428,3.353159851,8.698884758,21.0260223,31.81412639
1982-09-01,2.579925651,6.059479554,12.95910781,29.91821561,43.04089219
1982-10-01,4.661710037,10.73605948,20.92193309,39.18215613,52.46096654
1982-11-01,0.713754647,2.750929368,7.420074349,17.23420074,27.67286245
1982-12-01,0.795539033,2.788104089,7.31598513,18.04460967,29.76951673`);
const g3 = new Dygraph(
document.getElementById("graphdiv3"),
'data:application/text+csv;base64,' + csv, {
labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
legendFormatter: reverseLegendFormatter
}
)
function reverseLegendFormatter(data) {
let g = data.dygraph;
if (g.getOption('showLabelsOnHighlight') !== true) return '';
let sepLines = g.getOption('labelsSeparateLines'), htmlLines = [];
if (typeof data.x === 'undefined') {
if (g.getOption('legend') != 'always') return '';
data.series.reverse()
.filter(series => series.isVisible)
.forEach(series => {
htmlLines.push(`
<span style="font-weight:bold; color:${series.color}">
${series.dashHTML} ${series.labelHTML}
</span>
`);
});
} else {
htmlLines.push(`${data.xHTML}:`);
data.series.reverse()
.filter(series => series.isVisible)
.forEach(series => {
htmlLines.push(`
<span${ series.isHighlighted ? ' class="highlight"' : '' }>
<b><span style="color: ${series.color}">${series.labelHTML}</span></b>:
 ${series.yHTML}
</span>
`);
});
}
return htmlLines.join(sepLines ? '<br />' : '');
}
演示
const csv = btoa(`Year-month,class1,class2,class3,class5,class6
1982-01-01,0.617100372,2.669144981,6.43866171,17.15241636,30.49070632
1982-02-01,0.081784387,1.278810409,3.955390335,12.29739777,24.58736059
1982-03-01,0.104089219,0.996282528,3.568773234,11.98513011,21.81412639
1982-04-01,0.022304833,0.505576208,2.453531599,9.56133829,19.97769517
1982-05-01,0.215613383,2.066914498,7.152416357,18.47583643,31.21189591
1982-06-01,0.133828996,1.144981413,4.29739777,15.53159851,29.40520446
1982-07-01,3.910780669,8.505576208,16.69144981,35.10037175,48.4535316
1982-08-01,0.609665428,3.353159851,8.698884758,21.0260223,31.81412639
1982-09-01,2.579925651,6.059479554,12.95910781,29.91821561,43.04089219
1982-10-01,4.661710037,10.73605948,20.92193309,39.18215613,52.46096654
1982-11-01,0.713754647,2.750929368,7.420074349,17.23420074,27.67286245
1982-12-01,0.795539033,2.788104089,7.31598513,18.04460967,29.76951673`);
const g3 = new Dygraph(
document.getElementById("graphdiv3"),
'data:application/text+csv;base64,' + csv, {
labelsDiv: document.getElementById('status'),
labelsSeparateLines: true,
labelsKMB: true,
legend: 'always',
xlabel: 'Date',
ylabel: 'Area',
drawGrid: false,
rollPeriod: 10,
showRoller: true,
fillGraph: true,
fillAlpha: 1.0,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
legendFormatter: reverseLegendFormatter,
labelsSeparateLines: false // Really shines here!
}
)
function reverseLegendFormatter(data) {
let g = data.dygraph;
if (g.getOption('showLabelsOnHighlight') !== true) return '';
let sepLines = g.getOption('labelsSeparateLines'), htmlLines = [];
if (typeof data.x === 'undefined') {
if (g.getOption('legend') != 'always') return '';
data.series.reverse()
.filter(series => series.isVisible)
.forEach(series => {
htmlLines.push(`
<span style="font-weight:bold; color:${series.color}">
${series.dashHTML} ${series.labelHTML}
</span>
`);
});
} else {
htmlLines.push(`${data.xHTML}:`);
data.series.reverse()
.filter(series => series.isVisible)
.forEach(series => {
htmlLines.push(`
<span${ series.isHighlighted ? ' class="highlight"' : '' }>
<b><span style="color: ${series.color}">${series.labelHTML}</span></b>:
 ${series.yHTML}
</span>
`);
});
}
return htmlLines.join(sepLines ? '<br />' : '');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.1.0/dygraph.min.css" rel="stylesheet" />
<div id="graphdiv3" style="width:1000px; height:300px;"></div>
<div id="status" class="status"></div>