有没有办法在 AmCharts 线系列中省略 NaN 而没有线通过值零(0)?
Is there a way to omit NaN in AmCharts line series without line going through value zero (0)?
有机会 skip/omit AmChart4 中的 NaN 值吗?一旦数据集中缺少某些数据,该行就不正确。在这种情况下,该线认为值 0,而不是简单地连接到下一个已知值。或者至少在 NaN 出现的地方断开连接。我尝试了 series.connect = false
,但没有达到我预期的结果。
如有任何帮助,我们将不胜感激。提前谢谢你。
跳过这些值的唯一方法是将它们从数组中删除。您可以使用 beforedatavalidated
事件在图表使用 NaN 值之前删除它们:
chart.events.on("beforedatavalidated", function(ev) {
let source = ev.target.data;
let data = [];
for(let i = 0; i < source.length; i++) {
let row = JSON.parse(JSON.stringify(source[i]));
data.push(row);
if (isNaN(row.series1)) {
row.series1 = undefined;
}
if (isNaN(row.series2)) {
row.series2 = undefined;
}
}
ev.target.data = data;
});
感谢更新 fiddle。有没有办法跳过没有数据的类别?
我可以使用 zoomToCategories
跳过前两个类别,同时禁用缩小。有什么更好的办法来避免 NaN 类别??
chart.events.on("inited", function zoomAxis() { categoryAxis.zoomToCategories("2010", "2019"); });
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);
chart.paddingTop = 20;
// Add data
chart.data = [
{
"datum": "2008",
"indeks_placana": NaN,
"indeks_neplacana": NaN
},
{
"year": "2009",
"series1": NaN,
"series2": NaN
},
{
"year": "2010",
"series1": 100,
"series2": 100
},
{
"year": "2011",
"series1": 102,
"series2": 97
},
{
"year": "2012",
"series1": 102,
"series2": 95
},
{
"year": "2013",
"series1": 114,
"series2": 95
},
{
"year": "2014",
"series1": 154,
"series2": 100
},
{
"year": "2015",
"series1": 155,
"series2": 103
},
{
"year": "2016",
"series1": 154,
"series2": 103
},
{
"year": "2017",
"series1": 152,
"series2": NaN
},
{
"year": "2018",
"series1": NaN,
"series2": 96
},
{
"year": "2019",
"series1": 151,
"series2": 99
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "year";
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
function createAxisAndSeries(field, name, opposite, bullet) {
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = field;
series.dataFields.categoryX = "year";
series.strokeWidth = 2;
series.yAxis = valueAxis;
series.connect = false;
series.name = name;
series.tooltipText = "{name}: [bold]{valueY}[/]";
series.tensionX = 0.8;
var interfaceColors = new am4core.InterfaceColorSet();
switch(bullet) {
case "triangle":
var bullet = series.bullets.push(new am4charts.Bullet());
bullet.width = 12;
bullet.height = 12;
bullet.horizontalCenter = "middle";
bullet.verticalCenter = "middle";
var triangle = bullet.createChild(am4core.Triangle);
triangle.stroke = interfaceColors.getFor("background");
triangle.strokeWidth = 2;
triangle.direction = "top";
triangle.width = 12;
triangle.height = 12;
break;
case "rectangle":
var bullet = series.bullets.push(new am4charts.Bullet());
bullet.width = 10;
bullet.height = 10;
bullet.horizontalCenter = "middle";
bullet.verticalCenter = "middle";
var rectangle = bullet.createChild(am4core.Rectangle);
rectangle.stroke = interfaceColors.getFor("background");
rectangle.strokeWidth = 2;
rectangle.width = 10;
rectangle.height = 10;
break;
default:
var bullet = series.bullets.push(new am4charts.CircleBullet());
bullet.circle.stroke = interfaceColors.getFor("background");
bullet.circle.strokeWidth = 2;
break;
}
valueAxis.renderer.line.strokeOpacity = 1;
valueAxis.renderer.line.strokeWidth = 2;
valueAxis.renderer.line.stroke = series.stroke;
//valueAxis.max = 14;
valueAxis.renderer.labels.template.fill = series.stroke;
valueAxis.renderer.opposite = opposite;
valueAxis.renderer.grid.template.disabled = false;
}
chart.events.on("beforedatavalidated", function(ev) {
let source = ev.target.data;
let data = [];
for(let i = 0; i < source.length; i++) {
let row = JSON.parse(JSON.stringify(source[i]));
data.push(row);
if (isNaN(row.series1)) {
row.series1 = undefined;
}
if (isNaN(row.series2)) {
row.series2 = undefined;
}
}
ev.target.data = data;
});
// this is a method which will be called after the event is fired:
chart.events.on("inited", function zoomAxis() {
categoryAxis.zoomToCategories("2010", "2019");
});
chart.zoomOutButton.disabled = true;
createAxisAndSeries("series1", "Series 1", true, "");
createAxisAndSeries("series2", "Series 2", true, "");
// Add legend
chart.legend = new am4charts.Legend();
// Create vertical scrollbar and place it before the value axis
chart.scrollbarY = new am4core.Scrollbar();
chart.scrollbarY.parent = chart.leftAxesContainer;
chart.scrollbarY.toBack();
// Create a horizontal scrollbar with previe and place it underneath the date axis
//chart.scrollbarX = new am4charts.XYChartScrollbar();
//chart.scrollbarX.series.push(series);
//chart.scrollbarX.parent = chart.bottomAxesContainer;
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
width: 100%;
height: 250px;
}
<script src="//www.amcharts.com/lib/4/core.js"></script>
<script src="//www.amcharts.com/lib/4/charts.js"></script>
<script src="//www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>
有机会 skip/omit AmChart4 中的 NaN 值吗?一旦数据集中缺少某些数据,该行就不正确。在这种情况下,该线认为值 0,而不是简单地连接到下一个已知值。或者至少在 NaN 出现的地方断开连接。我尝试了 series.connect = false
,但没有达到我预期的结果。
如有任何帮助,我们将不胜感激。提前谢谢你。
跳过这些值的唯一方法是将它们从数组中删除。您可以使用 beforedatavalidated
事件在图表使用 NaN 值之前删除它们:
chart.events.on("beforedatavalidated", function(ev) {
let source = ev.target.data;
let data = [];
for(let i = 0; i < source.length; i++) {
let row = JSON.parse(JSON.stringify(source[i]));
data.push(row);
if (isNaN(row.series1)) {
row.series1 = undefined;
}
if (isNaN(row.series2)) {
row.series2 = undefined;
}
}
ev.target.data = data;
});
感谢更新 fiddle。有没有办法跳过没有数据的类别?
我可以使用 zoomToCategories
跳过前两个类别,同时禁用缩小。有什么更好的办法来避免 NaN 类别??
chart.events.on("inited", function zoomAxis() { categoryAxis.zoomToCategories("2010", "2019"); });
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);
chart.paddingTop = 20;
// Add data
chart.data = [
{
"datum": "2008",
"indeks_placana": NaN,
"indeks_neplacana": NaN
},
{
"year": "2009",
"series1": NaN,
"series2": NaN
},
{
"year": "2010",
"series1": 100,
"series2": 100
},
{
"year": "2011",
"series1": 102,
"series2": 97
},
{
"year": "2012",
"series1": 102,
"series2": 95
},
{
"year": "2013",
"series1": 114,
"series2": 95
},
{
"year": "2014",
"series1": 154,
"series2": 100
},
{
"year": "2015",
"series1": 155,
"series2": 103
},
{
"year": "2016",
"series1": 154,
"series2": 103
},
{
"year": "2017",
"series1": 152,
"series2": NaN
},
{
"year": "2018",
"series1": NaN,
"series2": 96
},
{
"year": "2019",
"series1": 151,
"series2": 99
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "year";
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
function createAxisAndSeries(field, name, opposite, bullet) {
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = field;
series.dataFields.categoryX = "year";
series.strokeWidth = 2;
series.yAxis = valueAxis;
series.connect = false;
series.name = name;
series.tooltipText = "{name}: [bold]{valueY}[/]";
series.tensionX = 0.8;
var interfaceColors = new am4core.InterfaceColorSet();
switch(bullet) {
case "triangle":
var bullet = series.bullets.push(new am4charts.Bullet());
bullet.width = 12;
bullet.height = 12;
bullet.horizontalCenter = "middle";
bullet.verticalCenter = "middle";
var triangle = bullet.createChild(am4core.Triangle);
triangle.stroke = interfaceColors.getFor("background");
triangle.strokeWidth = 2;
triangle.direction = "top";
triangle.width = 12;
triangle.height = 12;
break;
case "rectangle":
var bullet = series.bullets.push(new am4charts.Bullet());
bullet.width = 10;
bullet.height = 10;
bullet.horizontalCenter = "middle";
bullet.verticalCenter = "middle";
var rectangle = bullet.createChild(am4core.Rectangle);
rectangle.stroke = interfaceColors.getFor("background");
rectangle.strokeWidth = 2;
rectangle.width = 10;
rectangle.height = 10;
break;
default:
var bullet = series.bullets.push(new am4charts.CircleBullet());
bullet.circle.stroke = interfaceColors.getFor("background");
bullet.circle.strokeWidth = 2;
break;
}
valueAxis.renderer.line.strokeOpacity = 1;
valueAxis.renderer.line.strokeWidth = 2;
valueAxis.renderer.line.stroke = series.stroke;
//valueAxis.max = 14;
valueAxis.renderer.labels.template.fill = series.stroke;
valueAxis.renderer.opposite = opposite;
valueAxis.renderer.grid.template.disabled = false;
}
chart.events.on("beforedatavalidated", function(ev) {
let source = ev.target.data;
let data = [];
for(let i = 0; i < source.length; i++) {
let row = JSON.parse(JSON.stringify(source[i]));
data.push(row);
if (isNaN(row.series1)) {
row.series1 = undefined;
}
if (isNaN(row.series2)) {
row.series2 = undefined;
}
}
ev.target.data = data;
});
// this is a method which will be called after the event is fired:
chart.events.on("inited", function zoomAxis() {
categoryAxis.zoomToCategories("2010", "2019");
});
chart.zoomOutButton.disabled = true;
createAxisAndSeries("series1", "Series 1", true, "");
createAxisAndSeries("series2", "Series 2", true, "");
// Add legend
chart.legend = new am4charts.Legend();
// Create vertical scrollbar and place it before the value axis
chart.scrollbarY = new am4core.Scrollbar();
chart.scrollbarY.parent = chart.leftAxesContainer;
chart.scrollbarY.toBack();
// Create a horizontal scrollbar with previe and place it underneath the date axis
//chart.scrollbarX = new am4charts.XYChartScrollbar();
//chart.scrollbarX.series.push(series);
//chart.scrollbarX.parent = chart.bottomAxesContainer;
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
width: 100%;
height: 250px;
}
<script src="//www.amcharts.com/lib/4/core.js"></script>
<script src="//www.amcharts.com/lib/4/charts.js"></script>
<script src="//www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>