我正在使用amchart作为图表。以下是代码,
var chart = AmCharts.makeChart("chartdiv", {
"theme": "light",
"type": "serial",
"startDuration": 2,
"dataProvider": [{
"country": "This is Sample Data with long label",
"visits": 4025,
"color": "#FF0F00"
}, {
"country": "This is Sample Data with long label1",
"visits": 1882,
"color": "#FF6600"
}, {
"country": "This is Sample Data with long label2",
"visits": 1809,
"color": "#FF9E01"
}, {
"country": "This is Sample Data with long label3",
"visits": 1322,
"color": "#FCD202"
}, {
"country": "This is Sample Data with long label4",
"visits": 1122,
"color": "#F8FF01"
}, {
"country": "This is Sample Data with long label5",
"visits": 1114,
"color": "#B0DE09"
}, {
"country": "This is Sample Data with long label6",
"visits": 984,
"color": "#04D215"
}, {
"country": "This is Sample Data with long label7",
"visits": 711,
"color": "#0D8ECF"
}, {
"country": "This is Sample Data with long label8",
"visits": 665,
"color": "#0D52D1"
}, {
"country": "This is Sample Data with long label9",
"visits": 580,
"color": "#2A0CD0"
}, {
"country": "This is Sample Data with long label10",
"visits": 443,
"color": "#8A0CCF"
}, {
"country": "This is Sample Data with long label11",
"visits": 441,
"color": "#CD0D74"
}, {
"country": "This is Sample Data with long label12",
"visits": 395,
"color": "#754DEB"
}, {
"country": "This is Sample Data with long label13",
"visits": 386,
"color": "#DDDDDD"
}, {
"country": "This is Sample Data with long label14",
"visits": 338,
"color": "#333333"
}],
"valueAxes": [{
"position": "left",
"axisAlpha":0,
"gridAlpha":0
}],
"graphs": [{
"balloonText": "[[category]]: <b>[[value]]</b>",
"colorField": "color",
"fillAlphas": 0.85,
"lineAlpha": 0.1,
"type": "column",
"topRadius":1,
"valueField": "visits"
}],
"depth3D": 40,
"angle": 30,
"chartCursor": {
"categoryBalloonEnabled": false,
"cursorAlpha": 0,
"zoomable": false
},
"categoryField": "country",
"categoryAxis": {
"gridPosition": "start",
"axisAlpha":0,
"gridAlpha":0
},
"labelFunction": function(label, item, axis) {
var chart = axis.chart;
if ( (chart.realWidth <= 300 ) && ( label.length > 5 ) )
return label.substr(0, 5) + '...';
if ( (chart.realWidth <= 500 ) && ( label.length > 10 ) )
return label.substr(0, 10) + '...';
return label;
},
"legend": {
"useGraphSettings": true
},
"export": {
"enabled": true
}
}, 0);
然而,Xaxis标签非常冗长,我想自动截断长类别轴标签,如this example,并启用图例。但启用图例并不起作用,自动截断似乎也不起作用。有人可以帮帮我吗?提前谢谢。
这是codepen [1]的链接。
答案 0 :(得分:2)
如下所示制作labelFunction
:
"labelFunction": function(label, item, axis) {
var chart = axis.chart;
console.log("CHART:", chart.realWidth, label.length, label );
if ( ( label.length > 5 ) ){
console.log("CHARTLABEL:", label.substr(0, 5) + '...');
return label.substr(0, 7) + '...';
}
if ( ( label.length > 10 ) ){
return label.substr(0, 10) + '...';
}
return label;
},
您的代码无效,因为您必须将标签功能放在categoryAxis
答案 1 :(得分:2)
您的代码中存在一些小错误:
labelFunction
不在categoryAxis
我已将某些代码分开,并为标签添加了最大长度(15个字符),与图表宽度无关
View the full example on Codepen
// keep the data object separate from the call
var dataProvider = [
{
country: "This is Sample Data with long label",
visits: 4025,
color: "#FF0F00"
},
{
country: "This is Sample Data with long label1",
visits: 1882,
color: "#FF6600"
},
{
country: "This is Sample Data with long label2",
visits: 1809,
color: "#FF9E01"
},
{
country: "This is Sample Data with long label3",
visits: 1322,
color: "#FCD202"
}
];
var chart = AmCharts.makeChart(
"chartdiv",
{
theme: "light",
type: "serial",
startDuration: 2,
dataProvider: dataProvider,
valueAxes: [
{
position: "left",
axisAlpha: 0,
gridAlpha: 0
}
],
graphs: [
{
balloonText: "[[category]]: <b>[[value]]</b>",
colorField: "color",
fillAlphas: 0.85,
lineAlpha: 0.1,
type: "column",
topRadius: 1,
valueField: "visits"
}
],
depth3D: 40,
angle: 30,
chartCursor: {
categoryBalloonEnabled: false,
cursorAlpha: 0,
zoomable: false
},
categoryField: "country",
categoryAxis: {
gridPosition: "start",
axisAlpha: 0,
gridAlpha: 0,
labelFunction: trimLabel,
},
legend: {
useGraphSettings: true
},
export: {
enabled: true
}
},
0
);
// function to trim the labels
function trimLabel(label, item, axis) {
var chartWidth = axis.chart.realWidth;
var maxLabelLength = 15; // not counting the dots...
// trim when the width of the chart is smalled than 300px
if (chartWidth <= 300 && label.length > 5)
return label.substr(0, 5) + "...";
// trim when the width of the chart is smalled than 500px
if (chartWidth <= 500 && label.length > 10)
return label.substr(0, 10) + "...";
// trim when label is longer than maxLabelLength regardless of chart width
return label.length >= 15 ? label.substr(0, 14) + "...": label;
}
答案 2 :(得分:2)
正如其他人所说,labelFunction
是categoryAxis的一部分,所以它需要进入那里。我对kuzyn实现中的方法不感兴趣,但选择你想要的方法。
对于图例,它是由图形对象按设计生成的。由于有一个图形对象,因此只有一个标记。为每列添加标记需要添加自定义代码,以修改图例的data
数组以生成自定义标记。 AmCharts有一个knowledge base article for generating markers for each column。相关代码如下:
/*
Plugin to generate legend markers based on category
and fillColor/lineColor/color field from the chart data by using
the legend's custom data array. Also allows for toggling markers
by completely removing/adding columns from the chart
The plugin assumes there is only one graph object.
*/
AmCharts.addInitHandler(function(chart) {
//method to handle removing/adding columns when the marker is toggled
function handleCustomMarkerToggle(legendEvent) {
var dataProvider = legendEvent.chart.dataProvider;
var itemIndex; //store the location of the removed item
//Set a custom flag so that the dataUpdated event doesn't fire infinitely, in case you have
//a dataUpdated event of your own
legendEvent.chart.toggleLegend = true;
// The following toggles the markers on and off.
// The only way to "hide" a column and reserved space on the axis is to remove it
// completely from the dataProvider. You'll want to use the hidden flag as a means
// to store/retrieve the object as needed and then sort it back to its original location
// on the chart using the dataIdx property in the init handler
if (undefined !== legendEvent.dataItem.hidden && legendEvent.dataItem.hidden) {
legendEvent.dataItem.hidden = false;
dataProvider.push(legendEvent.dataItem.storedObj);
legendEvent.dataItem.storedObj = undefined;
//re-sort the array by dataIdx so it comes back in the right order.
dataProvider.sort(function(lhs, rhs) {
return lhs.dataIdx - rhs.dataIdx;
});
} else {
// toggle the marker off
legendEvent.dataItem.hidden = true;
//get the index of the data item from the data provider, using the
//dataIdx property.
for (var i = 0; i < dataProvider.length; ++i) {
if (dataProvider[i].dataIdx === legendEvent.dataItem.dataIdx) {
itemIndex = i;
break;
}
}
//store the object into the dataItem
legendEvent.dataItem.storedObj = dataProvider[itemIndex];
//remove it
dataProvider.splice(itemIndex, 1);
}
legendEvent.chart.validateData(); //redraw the chart
}
//check if legend is enabled and custom generateFromData property
//is set before running
if (!chart.legend || !chart.legend.enabled || !chart.legend.generateFromData) {
return;
}
var categoryField = chart.categoryField;
var colorField = chart.graphs[0].lineColorField || chart.graphs[0].fillColorsField || chart.graphs[0].colorField;
var legendData = chart.dataProvider.map(function(data, idx) {
var markerData = {
"title": data[categoryField] + ": " + data[chart.graphs[0].valueField],
"color": data[colorField],
"dataIdx": idx //store a copy of the index of where this appears in the dataProvider array for ease of removal/re-insertion
};
if (!markerData.color) {
markerData.color = chart.graphs[0].lineColor;
}
data.dataIdx = idx; //also store it in the dataProvider object itself
return markerData;
});
chart.legend.data = legendData;
//make the markers toggleable
chart.legend.switchable = true;
chart.legend.addListener("clickMarker", handleCustomMarkerToggle);
}, ["serial"]);
此插件要求您在图例中将自定义generateFromData
标记设置为true,而其他内容(useGraphSettings
不兼容):
"legend": {
"generateFromData": true //custom property for the plugin
},
这是一个利用kuzyn的trim方法和上述插件的演示:
/*
Plugin to generate legend markers based on category
and fillColor/lineColor/color field from the chart data by using
the legend's custom data array. Also allows for toggling markers
by completely removing/adding columns from the chart
The plugin assumes there is only one graph object.
*/
AmCharts.addInitHandler(function(chart) {
//method to handle removing/adding columns when the marker is toggled
function handleCustomMarkerToggle(legendEvent) {
var dataProvider = legendEvent.chart.dataProvider;
var itemIndex; //store the location of the removed item
//Set a custom flag so that the dataUpdated event doesn't fire infinitely, in case you have
//a dataUpdated event of your own
legendEvent.chart.toggleLegend = true;
// The following toggles the markers on and off.
// The only way to "hide" a column and reserved space on the axis is to remove it
// completely from the dataProvider. You'll want to use the hidden flag as a means
// to store/retrieve the object as needed and then sort it back to its original location
// on the chart using the dataIdx property in the init handler
if (undefined !== legendEvent.dataItem.hidden && legendEvent.dataItem.hidden) {
legendEvent.dataItem.hidden = false;
dataProvider.push(legendEvent.dataItem.storedObj);
legendEvent.dataItem.storedObj = undefined;
//re-sort the array by dataIdx so it comes back in the right order.
dataProvider.sort(function(lhs, rhs) {
return lhs.dataIdx - rhs.dataIdx;
});
} else {
// toggle the marker off
legendEvent.dataItem.hidden = true;
//get the index of the data item from the data provider, using the
//dataIdx property.
for (var i = 0; i < dataProvider.length; ++i) {
if (dataProvider[i].dataIdx === legendEvent.dataItem.dataIdx) {
itemIndex = i;
break;
}
}
//store the object into the dataItem
legendEvent.dataItem.storedObj = dataProvider[itemIndex];
//remove it
dataProvider.splice(itemIndex, 1);
}
legendEvent.chart.validateData(); //redraw the chart
}
//check if legend is enabled and custom generateFromData property
//is set before running
if (!chart.legend || !chart.legend.enabled || !chart.legend.generateFromData) {
return;
}
var categoryField = chart.categoryField;
var colorField = chart.graphs[0].lineColorField || chart.graphs[0].fillColorsField || chart.graphs[0].colorField;
var legendData = chart.dataProvider.map(function(data, idx) {
var markerData = {
"title": data[categoryField] + ": " + data[chart.graphs[0].valueField],
"color": data[colorField],
"dataIdx": idx //store a copy of the index of where this appears in the dataProvider array for ease of removal/re-insertion
};
if (!markerData.color) {
markerData.color = chart.graphs[0].lineColor;
}
data.dataIdx = idx; //also store it in the dataProvider object itself
return markerData;
});
chart.legend.data = legendData;
//make the markers toggleable
chart.legend.switchable = true;
chart.legend.addListener("clickMarker", handleCustomMarkerToggle);
}, ["serial"]);
// keep the data object separate from the call
var dataProvider = [
{
country: "This is Sample Data with long label",
visits: 4025,
color: "#FF0F00"
},
{
country: "This is Sample Data with long label1",
visits: 1882,
color: "#FF6600"
},
{
country: "This is Sample Data with long label2",
visits: 1809,
color: "#FF9E01"
},
{
country: "This is Sample Data with long label3",
visits: 1322,
color: "#FCD202"
}
];
var chart = AmCharts.makeChart(
"chartdiv",
{
theme: "light",
type: "serial",
startDuration: 2,
dataProvider: dataProvider,
valueAxes: [
{
position: "left",
axisAlpha: 0,
gridAlpha: 0
}
],
graphs: [
{
balloonText: "[[category]]: <b>[[value]]</b>",
colorField: "color",
fillAlphas: 0.85,
lineAlpha: 0.1,
type: "column",
topRadius: 1,
valueField: "visits"
}
],
depth3D: 40,
angle: 30,
chartCursor: {
categoryBalloonEnabled: false,
cursorAlpha: 0,
zoomable: false
},
categoryField: "country",
categoryAxis: {
gridPosition: "start",
axisAlpha: 0,
gridAlpha: 0,
labelFunction: trimLabel,
},
legend: {
generateFromData: true //custom property for the plugin
},
export: {
enabled: true
}
},
0
);
// function to trim the labels
function trimLabel(label, item, axis) {
var chartWidth = axis.chart.realWidth;
var maxLabelLength = 15; // not counting the dots...
// trim when the width of the chart is smalled than 300px
if (chartWidth <= 300 && label.length > 5)
return label.substr(0, 5) + "...";
// trim when the width of the chart is smalled than 500px
if (chartWidth <= 500 && label.length > 10)
return label.substr(0, 10) + "...";
// trim when label is longer than maxLabelLength regardless of chart width
return label.length >= 15 ? label.substr(0, 14) + "...": label;
}
#chartdiv {
width: 990px;
height: 365px;
border-radius: 3px;
margin: 0px;
border: 1px dotted #728FCE;
}
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
<script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script>
<link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" />
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<input type="button" value="Set width to 300px" onclick="document.getElementById('chartdiv').style.width='300px';" />
<input type="button" value="Set width to 500px" onclick="document.getElementById('chartdiv').style.width='500px';" />
<input type="button" value="Set width to 700px" onclick="document.getElementById('chartdiv').style.width='700px';" />
<div id="chartdiv"></div>
请注意,如果您希望修剪标记上的标签,则还必须在initHandler中创建标记标题时调用trim。