How to add HTML to the panel title in amchart. I tried adding HTML for title but its rendering as HTML code only.
Here is the DEMO.
Here is the JavaScript code:
var chartData1 = [];
var chartData2 = [];
generateChartData();
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 500);
firstDate.setHours(0, 0, 0, 0);
for (var i = 0; i < 500; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
var a1 = Math.round(Math.random() * (40 + i)) + 100 + i;
var a2 = -1 * Math.round(Math.random() * (100 + i)) + 200 + i;
chartData1.push({
date: newDate,
value: a1
});
chartData2.push({
date: newDate,
value: a2
});
}
}
AmCharts.makeChart("chartdiv", {
type: "stock",
dataSets: [{
title: "first data set",
fieldMappings: [{
fromField: "value",
toField: "value"
}],
dataProvider: chartData1,
categoryField: "date"
},
{
title: "second data set",
fieldMappings: [{
fromField: "value",
toField: "value2"
}],
dataProvider: chartData2,
categoryField: "date",
compared: true
}
],
panels: [{
showCategoryAxis: false,
title: "<span>Hello</span>",
recalculateToPercents: "never",
stockGraphs: [{
id: "g1",
valueField: "value",
comparable: true
}],
stockLegend: {
}
}, {
showCategoryAxis: true,
title: "Data set #2",
recalculateToPercents: "never",
stockGraphs: [{
id: "g2",
valueField: "value2",
compareField: "value2",
comparable: true,
visibleInLegend: false
}],
stockLegend: {
}
}
],
chartScrollbarSettings: {
graph: "g1"
},
chartCursorSettings: {
valueBalloonsEnabled: true,
cursorColor: '#000000',
cursorAlpha:0.1
},
periodSelector: {
periods: [{
period: "MM",
selected: true,
count: 1,
label: "1 month"
}, {
period: "YYYY",
count: 1,
label: "1 year"
}, {
period: "YTD",
label: "YTD"
}, {
period: "MAX",
label: "MAX"
}]
}
});
It only supports text. Depending on what you need, you can try styling it directly using css by setting addClassNames to true in your chart using the generated CSS classes. For example, to change the color of the first panel's legend title:
.amcharts-stock-panel-div-stockPanel0 .amcharts-legend-title {
fill: #ee0000;
}
Demo
Related
I am trying to write logic to display data in datatable. Below is the table I need to display.
There will be only 5 columns Day1 to Day5.
In rows, if dayName='DAY 1' then data present in weekDay arrayList needs to be fetch like Music Theme(which is value to theme key in weekDay arrayList). 10 mins is themeTime and singing practice is title and so on.
Below is format of data -
[
{
"id": "7658dc9e-5720-4544-8780-761e1993a8a3",
"folderMapID": "d56eb3ff-dc9f-477e-82b2-ffc29a12b9f1",
"themeName": "test",
"classTime": 45,
"dayName": "DAY 2",
"isActive": true,
"weekDay": [
{
"id": "2cebd6c7-339d-4d99-a199-b1c145211272",
"position": 1,
"theme": "QA Theme One",
"themeTime": 14,
"title": "test title",
"isActive": true
}
]
},
{
"id": "8f638849-6e54-4949-b404-300aa2c8a0c0",
"folderMapID": "d56eb3ff-dc9f-477e-82b2-ffc29a12b9f1",
"themeName": "Butterfly Theme",
"classTime": 60,
"dayName": "DAY 1",
"isActive": true,
"weekDay": [
{
"id": "3796dac9-18b0-4dd4-912f-8aeeede84e6b",
"position": 1,
"theme": "Music Theme",
"themeTime": 10,
"title": "singing practice",
"isActive": true
},
{
"id": "57b8f608-d2ad-4f7b-807b-db75aa0d10a9",
"position": 2,
"theme": "Dance Theme",
"themeTime": 15,
"title": "learn dance steps",
"isActive": true
},
{
"id": "d395b047-2847-474a-a553-afbd93782092",
"position": 3,
"theme": "QA Theme One",
"themeTime": 20,
"title": "QA testing",
"isActive": true
}
]
}
]
HTML template -
<v-data-table :headers="headers" :items="weekScheduleList" disable-pagination
hide-default-footer>
<template v-slot:no-data>
<v-card-subtitle class="d-flex justify-center">No Data Available</v-card-subtitle>
</template>
</v-data-table>
export default {
data () {
return {
weekScheduleList: [],
theme: '',
headers: [
{ text: 'DAY 1', value: 'theme', align: 'center', sortable: true },
{ text: 'DAY 2', value: '0', align: 'center', sortable: true },
{ text: 'DAY 3', value: '0', align: 'center', sortable: true },
{ text: 'DAY 4', value: '0', align: 'center', sortable: true },
{ text: 'DAY 5', value: '0', align: 'center', sortable: true }
],
}
},
methods: {
getWeekScheduleList: async function () {
try {
this.isLoading = true
let res = await http.get(`${CONSTANTS.API_URL}/api/get-week/${this.folderId}`)
const days = res.data
const newData = []
days.forEach(day => {
const row = {
day: day.dayName
}
day.weekDay.forEach(weekDay => {
row[weekDay.theme] = `${weekDay.theme} - ${weekDay.themeTime} mins - ${weekDay.title}`
})
newData.push(row)
})
this.weekScheduleList = newData
console.log('this.weekScheduleList :', this.weekScheduleList)
} catch (e) {
const errorMessage = (e && e.response && e.response.data.message) || e.message
this.errMsg(errorMessage)
}
},
}
As per looking at your tabular UI, you need to convert your API data in the below format where each row would have all 5 days' data.
[
{
// Day 1,
// Day 2,
// Day 3,
// Day 4,
// Day 5
},
{
// Day 1,
// Day 2,
// Day 3,
// Day 4,
// Day 5
}
]
Try the below logic in your getWeekScheduleList function. I added the respective comments to explain the code.
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="weekScheduleList"
disable-pagination
hide-default-footer
>
</v-data-table>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
weekScheduleList: [],
theme: "",
headers: [{
text: "DAY 1",
value: "DAY 1",
align: 'center',
sortable: true
},
{
text: "DAY 2",
value: "DAY 2",
align: 'center',
sortable: true
},
{
text: "DAY 3",
value: "DAY 3",
align: 'center',
sortable: true
},
{
text: "DAY 4",
value: "DAY 4",
align: 'center',
sortable: true
},
{
text: "DAY 5",
value: "DAY 5",
align: 'center',
sortable: true
},
],
api_data: [{
id: "7658dc9e-5720-4544-8780-761e1993a8a3",
folderMapID: "d56eb3ff-dc9f-477e-82b2-ffc29a12b9f1",
themeName: "test",
classTime: 45,
dayName: "DAY 2",
isActive: true,
weekDay: [{
id: "2cebd6c7-339d-4d99-a199-b1c145211272",
position: 1,
theme: "QA Theme One",
themeTime: 14,
title: "test title",
isActive: true,
}, ],
},
{
id: "8f638849-6e54-4949-b404-300aa2c8a0c0",
folderMapID: "d56eb3ff-dc9f-477e-82b2-ffc29a12b9f1",
themeName: "Butterfly Theme",
classTime: 60,
dayName: "DAY 1",
isActive: true,
weekDay: [{
id: "3796dac9-18b0-4dd4-912f-8aeeede84e6b",
position: 1,
theme: "Music Theme",
themeTime: 10,
title: "singing practice",
isActive: true,
},
{
id: "57b8f608-d2ad-4f7b-807b-db75aa0d10a9",
position: 2,
theme: "Dance Theme",
themeTime: 15,
title: "learn dance steps",
isActive: true,
},
{
id: "d395b047-2847-474a-a553-afbd93782092",
position: 3,
theme: "QA Theme One",
themeTime: 20,
title: "QA testing",
isActive: true,
},
],
},
],
};
},
mounted() {
this.getWeekScheduleList();
},
methods: {
getWeekScheduleList: async function() {
try {
var api_data = this.api_data;
var total_days = 5;
// Sort the api data by day's name first
api_data.sort(function(a, b) {
return a.dayName.localeCompare(b.dayName);
});
// Find the item which has maximum weedays
let max_weekday_item = this.api_data.find((item) =>
Math.max(item.weekDay.length)
);
// Outer loop for row - API data
for (
let rowIndex = 0; rowIndex < max_weekday_item.weekDay.length; rowIndex++
) {
const row = {};
// Inner loop for column
for (let colIndex = 1; colIndex <= total_days; colIndex++) {
// Find the item of respective day number
let day_item = this.api_data.find((item) => {
return item.dayName === `DAY ${colIndex}`;
});
/**
* If found then assign like this-
* row['DAY 1'] = Day 1's weekday data
* row['DAY 2'] = Day 2's weekday data
*/
if (day_item) {
row[`DAY ${colIndex}`] = day_item.weekDay[rowIndex] ?
`${day_item.weekDay[rowIndex].theme} - ${day_item.weekDay[rowIndex].themeTime} mins - ${day_item.weekDay[rowIndex].title}` :
"";
}
// Else leave it empty
else {
row[`DAY ${colIndex}`] = "";
}
}
// Push this row's data in the array
this.weekScheduleList.push(row);
}
} catch (e) {
console.error(e);
}
},
},
})
</script>
</body>
</html>
How to reduce the hover line width in Amchart. Here is a screen shot of the live chart..
Here is a DEMO of the code in action.
Here is how the JavaScript code looks:
var chartData1 = [];
var chartData2 = [];
generateChartData();
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 500);
firstDate.setHours(0, 0, 0, 0);
for (var i = 0; i < 500; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
var a1 = Math.round(Math.random() * (40 + i)) + 100 + i;
var a2 = -1 * Math.round(Math.random() * (100 + i)) + 200 + i;
chartData1.push({
date: newDate,
value: a1
});
chartData2.push({
date: newDate,
value: a2
});
}
}
AmCharts.makeChart("chartdiv", {
type: "stock",
dataSets: [{
title: "first data set",
fieldMappings: [{
fromField: "value",
toField: "value"
}],
dataProvider: chartData1,
categoryField: "date"
},
{
title: "second data set",
fieldMappings: [{
fromField: "value",
toField: "value2"
}],
dataProvider: chartData2,
categoryField: "date",
compared: true
}
],
panels: [{
showCategoryAxis: false,
title: "Data set #1",
recalculateToPercents: "never",
stockGraphs: [{
id: "g1",
valueField: "value",
comparable: true
}],
stockLegend: {
}
}, {
showCategoryAxis: true,
title: "Data set #2",
recalculateToPercents: "never",
stockGraphs: [{
id: "g2",
valueField: "value2",
compareField: "value2",
comparable: true,
visibleInLegend: false
}],
stockLegend: {
}
}
],
chartScrollbarSettings: {
graph: "g1"
},
chartCursorSettings: {
valueBalloonsEnabled: true,
fullWidth:true,
cursorAlpha:0.1
},
periodSelector: {
periods: [{
period: "MM",
selected: true,
count: 1,
label: "1 month"
}, {
period: "YYYY",
count: 1,
label: "1 year"
}, {
period: "YTD",
label: "YTD"
}, {
period: "MAX",
label: "MAX"
}]
}
});
Your demo doesn't show the wide cursor but it seems that you figured it out - you have to remove fullWidth: true in your chartCursorSettings to make the cursor a normal narrow line rather than a wide one.
I'm trying to display details of projects.
I want show completion percentage on a bar chart with the start date for each of those project as line chart.
Now, for achieving this I have created a chart with dual y-axis.
1 - axis-1 shows progress with bar-chart
2 - axis-2 supposed to show start dates with a line chart
Bar chart works fine. Even the line chart works fine without the dual axis. But, when I add them together the line-chart disappears. I tried changing the dates on the line chart for random numbers - that works as well.
Anyone knows how to make dates work on a dual-axis chart.
jsfiddle
var projectDetails =
[{
"name": "+PS8039",
"startDate": "2016-02-01",
"finishDate": "2016-04-01"
}, {
"name": "+PS8039",
"startDate": "2016-01-02",
"finishDate": "2016-08-02"
}, {
"name": "+PS8039",
"startDate": "2016-03-08",
"finishDate": "2016-08-08"
}, {
"name": "+PS8039",
"startDate": "2016-04-11",
"finishDate": "2016-09-11"
}, {
"name": "+PS8039",
"startDate": "2016-05-13",
"finishDate": "2016-12-13"
}, {
"name": "+PS8039",
"startDate": "2016-01-15",
"finishDate": "2016-04-15"
}, {
"name": "+PS8039",
"startDate": "2016-02-25",
"finishDate": "2016-08-25"
}, {
"name": "+PS8039",
"startDate": "2016-03-03",
"finishDate": "2016-07-03"
}, {
"name": "+PC2E",
"startDate": "2016-04-07",
"finishDate": "2016-05-31"
}, {
"name": "+PC2E",
"startDate": "2016-05-16",
"finishDate": "2016-09-01"
}];
$(function () {
var xCategories = new Array();
var completionpercent = new Array();
var startdates = new Array();
var finishdates = new Array();
for(var i = 0; i< projectDetails.length; i++){
xCategories[i] = projectDetails[i].name;
startdates[i] = moment(projectDetails[i].startDate).format('x');
finishdates[i] = projectDetails[i].finishDate;
completionpercent[i] = ((Date.now() - Date.parse(projectDetails[i].startDate))
/(Date.parse(projectDetails[i].finishDate) - Date.parse(projectDetails[i].startDate)))
*100 ;
}
$('#Chart').highcharts({
colors: ['#2C5898'],
title: {
text: 'Project Completion'
},
legend: {
enabled: false
},
xAxis: [{
categories: xCategories,
crosshair: true
}],
yAxis:[{
title: {
text: '% Completion'
},
max: 110
},
{
"title": {
"text": "Start Dates"
},
opposite: true
}
],
plotOptions: {
bar: {
groupPadding: 0,
zones: [{
value: 100
},{
color: {
linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
stops: [
[0, '#cc0000'],
[1, '#ff8080']
]
}
}]
}
},
credits: {
enabled: false
},
series: [{
name: 'Start Dates',
type: 'line',
data: startdates
},{
name: 'Completion %',
type: 'bar',
data: completionpercent
}]
});
});
You need to specify that the line series relates to the second axis:
yAxis: 1,
Updated fiddle:
https://jsfiddle.net/jlbriggs/4e6edy7t/2/
I want to use amcharts in my meteor project, how can I integrate amcharts in meteor project?
I added mrt:amcharts package to my project.
Copied amcharts free version folder to my public folder. But it is not appearing.
My code is following.
chart.html
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script src="/amcharts/amcharts.js" type="text/javascript"></script>
<script src="/amcharts/serial.js" type="text/javascript"></script>
<script src="/amcharts/amstock.js" type="text/javascript"></script>
<link rel="stylesheet" href="/amcharts/style.css" type="text/css">
</head>
<template name="chart">
<p>chart is here</p>
<div id="chartdiv" style="width: 100%; height: 400px;"></div>
</template>
chart.js
var chartData1 = [];
var chartData2 = [];
var chartData3 = [];
var chartData4 = [];
generateChartData();
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 500);
firstDate.setHours(0, 0, 0, 0);
for (var i = 0; i < 500; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
var a1 = Math.round(Math.random() * (40 + i)) + 100 + i;
var b1 = Math.round(Math.random() * (1000 + i)) + 500 + i * 2;
var a2 = Math.round(Math.random() * (100 + i)) + 200 + i;
var b2 = Math.round(Math.random() * (1000 + i)) + 600 + i * 2;
var a3 = Math.round(Math.random() * (100 + i)) + 200;
var b3 = Math.round(Math.random() * (1000 + i)) + 600 + i * 2;
var a4 = Math.round(Math.random() * (100 + i)) + 200 + i;
var b4 = Math.round(Math.random() * (100 + i)) + 600 + i;
chartData1.push({
date: newDate,
value: a1,
volume: b1
});
chartData2.push({
date: newDate,
value: a2,
volume: b2
});
chartData3.push({
date: newDate,
value: a3,
volume: b3
});
chartData4.push({
date: newDate,
value: a4,
volume: b4
});
}
}
var chart = AmCharts.makeChart("chartdiv", {
type: "stock",
"theme": "none",
pathToImages: "http://www.amcharts.com/lib/3/images/",
dataSets: [{
title: "first data set",
fieldMappings: [{
fromField: "value",
toField: "value"
}, {
fromField: "volume",
toField: "volume"
}],
dataProvider: chartData1,
categoryField: "date"
},
{
title: "second data set",
fieldMappings: [{
fromField: "value",
toField: "value"
}, {
fromField: "volume",
toField: "volume"
}],
dataProvider: chartData2,
categoryField: "date"
},
{
title: "third data set",
fieldMappings: [{
fromField: "value",
toField: "value"
}, {
fromField: "volume",
toField: "volume"
}],
dataProvider: chartData3,
categoryField: "date"
},
{
title: "fourth data set",
fieldMappings: [{
fromField: "value",
toField: "value"
}, {
fromField: "volume",
toField: "volume"
}],
dataProvider: chartData4,
categoryField: "date"
}
],
panels: [{
showCategoryAxis: false,
title: "Value",
percentHeight: 70,
stockGraphs: [{
id: "g1",
valueField: "value",
comparable: true,
compareField: "value",
balloonText: "[[title]]:<b>[[value]]</b>",
compareGraphBalloonText: "[[title]]:<b>[[value]]</b>"
}],
stockLegend: {
periodValueTextComparing: "[[percents.value.close]]%",
periodValueTextRegular: "[[value.close]]"
}
},
{
title: "Volume",
percentHeight: 30,
stockGraphs: [{
valueField: "volume",
type: "column",
showBalloon: false,
fillAlphas: 1
}],
stockLegend: {
periodValueTextRegular: "[[value.close]]"
}
}
],
chartScrollbarSettings: {
graph: "g1"
},
chartCursorSettings: {
valueBalloonsEnabled: true,
fullWidth:true,
cursorAlpha:0.1,
valueLineBalloonEnabled:true,
valueLineEnabled:true,
valueLineAlpha:0.5
},
periodSelector: {
position: "left",
periods: [{
period: "MM",
selected: true,
count: 1,
label: "1 month"
}, {
period: "YYYY",
count: 1,
label: "1 year"
}, {
period: "YTD",
label: "YTD"
}, {
period: "MAX",
label: "MAX"
}]
},
dataSetSelector: {
position: "left"
}
});
try this: mrt add amcharts
Also, within your chart initialization, if referencing any images (e.g. 'export.png'), please prepend the path with the package path. E.g.
"exportConfig":{
"menuTop":"20px",
"menuRight":"20px",
"menuItems": [{
"icon": '/packages/amcharts/lib/images/export.png',
"format": 'png'
}]
}
I'm trying to get Kendo's Grid to show a filter using a combo box rather than a drop down list when used with values. What I mean is, on the grid columns array, each column can be given a list of values (objects with text and value properties) for each possible entry in the database, thereby rather than showing a code, it shows a recognisable name or text instead of the code. The problem is that whenever I specify values against the column, the filter reverts to a fixed list of criteria and a drop-down list, which I don't want.
See an example of what I mean here. What I'd like to see is the filter (on the Category column) to show a combo-box rather than a drop down list, but still use the values against the codes in the table to show in the data in the grid, but it doesn't seem to work.
As you say it doesn't work with the values property, so one approach would be to set up a custom row template and use a lookup function on category ID and replace it with the corresponding text:
var categories = [{
"value": 1,
"text": "Beverages"
}, {
"value": 2,
"text": "Condiments"
}, {
"value": 3,
"text": "Confections"
}, {
"value": 4,
"text": "Dairy Products"
}, {
"value": 5,
"text": "Grains/Cereals"
}, {
"value": 6,
"text": "Meat/Poultry"
}, {
"value": 7,
"text": "Produce"
}, {
"value": 8,
"text": "Seafood"
}];
function getCategory(catID) {
return $.grep(categories, function(n, i) {
return n.value === catID;
})[0].text;
}
$(document).ready(function() {
var dataSource = new kendo.data.DataSource({
pageSize: 20,
data: products,
autoSync: true,
schema: {
model: {
id: "ProductID",
fields: {
ProductID: {
editable: false,
nullable: true
},
ProductName: {
validation: {
required: true
}
},
CategoryID: {
field: "CategoryID",
type: "number",
defaultValue: 1
},
UnitPrice: {
type: "number",
validation: {
required: true,
min: 1
}
}
}
}
}
});
var rowTemplateString = '<tr data-uid="#: uid #">' +
'<td>#: ProductName #</td>' +
'<td>#: getCategory(CategoryID) #</td>' +
'<td>#: UnitPrice #</td>' + '<td></td>' +
'</tr>';
var altRowTemplateString = rowTemplateString.replace('tr class="', 'tr class="k-alt ');
var commonSettings = {
dataSource: dataSource,
filterable: true,
groupable: true,
pageable: true,
height: 430,
toolbar: ["create"],
columns: [{
field: "ProductName",
title: "Product Name"
},
{
field: "CategoryID",
width: "150px",
//values: categories,
dataTextField: "text",
dataValueField: "value",
dataSource: categories,
filterable: {
ui: function(element) {
element.kendoComboBox({
dataTextField: "text",
dataValueField: "value",
dataSource: categories
});
}
},
title: "Category"
},
{
field: "UnitPrice",
title: "Unit Price",
format: "{0:c}",
width: "150px"
},
{
command: "destroy",
title: " ",
width: "110px"
}
],
editable: true
};
$("#grid").kendoGrid($.extend({
rowTemplate: rowTemplateString,
altRowTemplate: altRowTemplateString
}, commonSettings));
});
Note: In this demo I haven't tried to handle the template for the Delete column. I just left it blank.
Here's the Dojo http://dojo.telerik.com/oFulu
Try this One,According to your demo here
</script>
<div id="example" class="k-content">
<div id="grid"></div>
<script>
var categories = [{
"value": 1,
"text": "Beverages"
},{
"value": 2,
"text": "Condiments"
},{
"value": 3,
"text": "Confections"
},{
"value": 4,
"text": "Dairy Products"
},{
"value": 5,
"text": "Grains/Cereals"
},{
"value": 6,
"text": "Meat/Poultry"
},{
"value": 7,
"text": "Produce"
},{
"value": 8,
"text": "Seafood"
}];
$(document).ready(function () {
var dataSource = new kendo.data.DataSource({
pageSize: 20,
data: products,
autoSync: true,
schema: {
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
ProductName: { validation: { required: true} },
CategoryID: { field: "CategoryID", type: "number", defaultValue: 1 },
UnitPrice: { type: "number", validation: { required: true, min: 1} }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
filterable: true,
groupable: true,
pageable: true,
height: 430,
toolbar: ["create"],
columns: [
{ field: "ProductName", title: "Product Name" },
{
field: "CategoryID",
width: "150px",
values: categories,
editor:function(container,options)
{
$('<input name-"' + options.fields +'"/>').
appendTo(container).kendoComboBox({
autoBind:false,
dataTextField:"text",
dataValueFiled:"value",
dataSource:new kendo.data.DataSource({
schema:{
model:{
id:"value",
fields:{
text:{},
value:{}
}
}
},
data:categories
})
})
},
title: "Category"
},
{ field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "150px" },
{ command: "destroy", title: " ", width: "110px"}],
editable: true
});
});
</script>