Doughnut Chart not displaying data with Chart Js and Backbone js - javascript

I'm making an application and I have to display data in a chart. I also only want the last 5 transactions entered to display.
I'm using Backbone.js and Chart.js. In my prototype displaying data was no problem because I just bootstrapped the data. But now that I'm trying to pull the data from my Backbone Collection it's not working. I only get a transparent image
// Model
(function (exports) {
var Transaction = Backbone.Model.extend({
defaults: {
amount: 0,
transactionDate: "",
transactionType: "debit",
category: "miscellaneous",
description: ""
},
categories: [
"salary",
"rent",
"miscellaneous"
],
transactionTypes: [
"credit",
"debit"
],
initialize: function() {
this.set({transactionDate: this.attributes.transactionDate || Date.now()}, {validate: true});
},
validate: function(attrs, options) {
if (attrs['transactionType'] !== undefined &&
!_.contains(this.transactionTypes, attrs['transactionType'].toLowerCase())) {
return 'Invalid type: ' + attrs['transactionType'];
} else if (attrs['category'] !== undefined &&
!_.contains(this.categories, attrs['category'].toLowerCase())) {
return 'Invalid category: ' + attrs['category'];
} else if (attrs['transactionDate'] !== undefined &&
_.isNaN(parseInt(attrs['transactionDate'])) || attrs['transactionDate'] < 0) {
return 'Invalid date: '+ attrs['transactionDate'];
} else if (attrs['amount'] !== undefined &&
_.isNaN(parseInt(attrs['amount'])) || attrs['amount'] < 0) {
return 'Invalid amount: '+ attrs['amount'];
}
return null;
}
});
// export for global use
exports.expensus.Models.Transaction = Transaction;
}(this));
This is the collection I'm using ..
;(function (exports) {
var Transactions = Backbone.Collection.extend({
// stuff and thangs
model: expensus.Models.Transaction,
localStorage: new Backbone.LocalStorage('TransactionsCollection'),
latestFive: function(toJSON) {
this.sortByDate(-1); // sort latest first
if (!toJSON) {
return _.first(this.models, 5);
} else {
var models = _.first(this.models, 5),
idx = -1,
json = [],
model;
while (model = models[++idx]) {
json.push(model.attributes);
}
return json;
}
},
sortByDate: function(dir) {
dir = dir || -1;
this.comparator = function(transaction) {
return dir * transaction.get("transactionDate");
};
this.sort();
},
sortByAmount: function(dir) {
dir = dir || -1;
this.comparator = function(transaction) {
return dir * transaction.get("amount");
};
this.sort();
}
});
exports.expensus.Collections.Transactions = Transactions;
}(this));
And this is the Chart View, I get no errors in dev tools so I'm really at a loss ...
;(function (exports){
var ChartView = Backbone.View.extend({
el: ".home-page",
template: Handlebars.compile($("#chart-template").html()),
chart: null,
initialize: function () {
this.listenTo(this.collection, "add", this.render);
this.listenTo(this.collection, "change", this.render);
this.$(".chart-view-div").html(this.template());
this.chart = new Chart($("#expense-chart")[0].getContext("2d"));
this.render();
},
render: function() {
var self = this;
var data = this.chartData();
self.chart.Doughnut(data, {
responsive: true,
animateScale: true
});
},
chartData: function() {
var collection = this.collection.latestFive(true);
var data = {
vals: [],
labels: [],
allData: []
};
var getData = function(color, highlight, labels, vals, collection) {
var object = {
color: color,
highlight: highlight,
chartData: [
{
value: "",
label: ""
}
]
};
for (var i = 0; i < labels.length; i++ ) {
object.chartData.push(0);
}
for (var j = 0; j < vals.length; j++ ) {
object.chartData.push(0);
}
for (var i = 0; i < collection.length; i++ ) {
var item = collection[i];
var label = labels.indexOf(item.category);
var val = vals.indexOf(item.amount);
object.chartData[ { value: val, label: label } ]++;
}
return object;
};
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
for (var i = 0; i < collection.length; i++ ) {
var object = collection[i];
var color = getRandomColor();
var highlight = getRandomColor();
data.labels.push(object.category);
data.vals.push(object.amount);
data.allData.push(getData(color, highlight, data.labels, data.vals, collection));
}
return data;
}
});
exports.expensus.Views.ChartView = ChartView;
}(this));
My Add Transaction View
;(function (exports) {
var AddTransactionView = Backbone.View.extend({
el: "#add-transaction-page",
events: {
"submit .add-transaction-form": "addTransaction"
},
initialize: function() {
this.form = this.$(".add-transaction-form")[0];
},
addTransaction: function(evt) {
if (evt) {
evt.preventDefault();
}
var m = new expensus.Models.Transaction({
transactionDate: Date.now(),
transactionType: this.form["trans-type"].value,
amount: this.form["trans-amount"].value,
description: this.form["trans-description"].value,
category: this.form["trans-category"].value
});
if(m.validationError === null) {
this.collection.add(m);
m.save();
$(this.el).modal("hide");
this.form.reset();
} else {
alert("Model is invalid: " + m.validationError);
}
}
});
exports.expensus.Views.AddTransactionView = AddTransactionView;
}(this));
This is as far as I could get. I've done this before with a different kind of chart but can't for the life of me figure it out with the Doughnut chart.
Thanks, everyone

The main thing i can see is that you pass the chart data which is not in the format that chartjs expects, so it should be an array of objects which have the properties value label and color but you are passing it something different. so a quick fix for that would be to construct an array as described
// Model
var Transaction = Backbone.Model.extend({
defaults: {
amount: 0,
transactionDate: "",
transactionType: "debit",
category: "miscellaneous",
description: ""
},
categories: [
"salary",
"rent",
"miscellaneous"
],
transactionTypes: [
"credit",
"debit"
],
initialize: function() {
this.set({
transactionDate: this.attributes.transactionDate || Date.now()
}, {
validate: true
});
},
validate: function(attrs, options) {
if (attrs['transactionType'] !== undefined && !_.contains(this.transactionTypes, attrs['transactionType'].toLowerCase())) {
return 'Invalid type: ' + attrs['transactionType'];
} else if (attrs['category'] !== undefined && !_.contains(this.categories, attrs['category'].toLowerCase())) {
return 'Invalid category: ' + attrs['category'];
} else if (attrs['transactionDate'] !== undefined && _.isNaN(parseInt(attrs['transactionDate'])) || attrs['transactionDate'] < 0) {
return 'Invalid date: ' + attrs['transactionDate'];
} else if (attrs['amount'] !== undefined && _.isNaN(parseInt(attrs['amount'])) || attrs['amount'] < 0) {
return 'Invalid amount: ' + attrs['amount'];
}
return null;
}
});
var Transactions = Backbone.Collection.extend({
// stuff and thangs
model: Transaction,
latestFive: function(toJSON) {
this.sortByDate(-1); // sort latest first
if (!toJSON) {
return _.first(this.models, 5);
} else {
var models = _.first(this.models, 5),
idx = -1,
json = [],
model;
while (model = models[++idx]) {
json.push(model.attributes);
}
return json;
}
},
sortByDate: function(dir) {
dir = dir || -1;
this.comparator = function(transaction) {
return dir * transaction.get("transactionDate");
};
this.sort();
},
sortByAmount: function(dir) {
dir = dir || -1;
this.comparator = function(transaction) {
return dir * transaction.get("amount");
};
this.sort();
}
});
var ChartView = Backbone.View.extend({
el: ".home-page",
template: Handlebars.compile($("#chart-template").html()),
chart: null,
initialize: function() {
this.listenTo(this.collection, "add", this.render);
this.listenTo(this.collection, "change", this.render);
this.$(".chart-view-div").html(this.template());
this.chart = new Chart(this.$("#expense-chart")[0].getContext("2d"));
this.render();
},
render: function() {
var self = this;
var data = this.chartData();
this.chart.Doughnut(data, {
responsive: true,
animateScale: true
});
},
chartData: function() {
var collection = this.collection.latestFive(true);
var data = [];;
var getData = function(color, highlight, labels, vals, collection) {
var object = {
color: color,
highlight: highlight,
chartData: [{
value: "",
label: ""
}]
};
for (var i = 0; i < labels.length; i++) {
object.chartData.push(0);
}
for (var j = 0; j < vals.length; j++) {
object.chartData.push(0);
}
for (var i = 0; i < collection.length; i++) {
var item = collection[i];
var label = labels.indexOf(item.category);
var val = vals.indexOf(item.amount);
object.chartData[{
value: val,
label: label
}] ++;
}
return object;
};
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
for (var i = 0; i < collection.length; i++) {
var object = collection[i];
var color = getRandomColor();
var highlight = getRandomColor();
data.push({
value: object.amount,
color: color,
label: object.category
});
}
return data;
}
});
var collection = new Transactions([{
amount: 12,
transactionDate: 1417442176000,
transactionType: "debit",
category: "miscellaneous",
description: ""
}, {
amount: 13,
transactionDate: 1417442176000,
transactionType: "credit",
category: "salary",
description: ""
}]);
var view = new ChartView({
collection: collection
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone.js"></script>
<script src="http://www.chartjs.org/assets/Chart.min.js"></script>
<script id="chart-template" type="text/x-handlebars-template">
<canvas id="expense-chart"></canvas>
</script>
<div class="home-page">
<div class="chart-view-div"></div>
</div>

Related

Display data for specific release selected in release filter at the top of page in rally dashboard

This is my code and in this the data displayed in chart is hole project data but in rally dashboard there is release filter at the top of your page. and i want my chart to show data of the the release selected by that filter and my sdk version in code is 1.33
<!DOCTYPE HTML\>
<script
src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js">
var WORKSPACE_OID = "__WORKSPACE_OID__";
var PROJECT_OID = "__PROJECT_OID__";
var PROJECT_SCOPING_UP = "__PROJECT_SCOPING_UP__";
var PROJECT_SCOPING_DOWN = "__PROJECT_SCOPING_DOWN__";
var MILS_IN_DAY = 86400000;
var DAYS_BACK = 30;
var filterChart;
var currentProjectDataSource;
var fromDate = new Date(new Date().getTime() - (MILS_IN_DAY * DAYS_BACK));
var allDefects = [];
// var currentRelease;
var onLoadAllIssues = function (result) {
// var defects = result.defects.filter(function (defect) {
// return defect.Release && defect.Release.\_refObjectName === currentRelease.Name;
// });
var labels = [];
var openDefects = [];
var closedDefects = [];
var defects = result.defects;
for (var count = 0; count < defects.length; count++) {
allDefects[allDefects.length] = defects[count];
var defect = defects[count];
labels.push(defect.CreationDate.split('T')[0]);
if (defect.ClosedDate !==null) {
closedDefects.push(defect.ClosedDate.split('T')[0]);
}
}
closedDefects.sort();
const counts = {};
labels.forEach(function (x) { counts[x] = (counts[x] || 0) + 1; });
const closedcounts = {};
closedDefects.forEach(function (x) { closedcounts[x] = (closedcounts[x] || 0) + 1; });
mychart(counts,closedcounts,labels)
};
var createCharts = function () {
var loadAllDefectsQuery = {
type: 'defect',
key: 'defects',
fetch: 'CreationDate,ClosedDate,ObjectID,FormattedID,Name,State,Priority',
order: 'CreationDate',
query: '((CreationDate != "null") OR (CreationDate > "' + dojo.date.stamp.toISOString(fromDate, { zulu: true }) +
'"))'
};
currentProjectDataSource.findAll(loadAllDefectsQuery, onLoadAllIssues);
};
var initPage = function () {
currentProjectDataSource = new rally.sdk.data.RallyDataSource(WORKSPACE_OID, PROJECT_OID, PROJECT_SCOPING_UP,
PROJECT_SCOPING_DOWN);
createCharts();
};
rally.addOnLoad(initPage);
function mychart(counts,closedcounts,labels) {
const pielable = labels;
const piedata = counts;
const closedcountsdata = closedcounts;
const data = {
datasets: [
{
label: 'Number of opened defects',
data: piedata,
},
{
label: 'Number of closed defects',
data: closedcountsdata,
}
]
};
const config = {
type: 'line',
data: data,
options: {
scales: {
x: {
min:"2022-01-01",
max:"2022-12-31",
type: 'time',
time:{
unit:'day',
},
},
y: {
beginAtZero: true,
grace: 5,
ticks: {
stepSize: 1,
},
},
},
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Defect Burndown Chart'
},
tooltip: {
yAlign: 'bottom',
titleMarginBottom: 0,
callbacks: {
title: function (context) {
return( `${context[0].label.slice(0, -13).replace(/,/g, " ")}`)
},
}
}
}
}
};
const myChart = new Chart(
document.getElementById('myChart'),
config
)
filterChart= function filterChart(date){
const year = date.value.substring(0,4);
const month = date.value.substring(5);
const lastday = (y,m)=>{
return new Date(y,m,0).getDate();
}
const startDate = `${date.value}-01`;
const endDate = `${date.value}-${lastday(year,month)}`;
myChart.config.options.scales.x.min=startDate;
myChart.config.options.scales.x.ma`your text`x=endDate;
myChart.update();
}}
</script>

Error: Highcharts error #13: www.highcharts.com/errors/13/ in Reactjs

I am trying to use High-charts in reactjs and I am new to both these. In the beginning, everything was fine but now I am unable to solve this error.
The following is my code:
Array.prototype.contains = function (v) {
for (var i = 0; i < this.length; i++) {
if (this[i] === v) return true;
}
return false;
};
Array.prototype.unique = function () {
var arr = [];
for (var i = 0; i < this.length; i++) {
if (!arr.contains(this[i])) {
arr.push(this[i]);
}
}
return arr;
}
export default class Chart extends React.Component {
constructor(props) {
super(props);
this.state = {
installs: [],
isLoaded: false,
}
this.state = {
filteredData: [],
isLoadedFilteredData: false,
showChart: true
}
this.state = {
options: {}
}
}
componentDidMount() {
// setInterval(() => {
fetch('xyz)
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
installs: json,
});
});
}
getFilteredData = async (operatingSystem, applicationServer, database, cloud, serverRelease) => {
fetch(`xyz`)
.then(res => res.json())
.then(json => {
// console.log(json);
this.setState({
isLoadedFilteredData: true,
filteredData: json,
}, console.log("getFilteredData called ... "));
});
}
handleChange = ({ altered, name, text, value }) => {
const nextFormValue = {
[name]: {
text,
value,
altered
}
};
this.setState({ ...this.state, ...nextFormValue }, () =>
console.log("handleChange()", this.state),
);
};
render() {
const { isLoaded, installs } = this.state;
const { isLoadedFilteredData, filteredData } = this.state;
if (!isLoaded) {
return <p>Loading...</p>;
}
else {
var arrayOS = []
var arrayApp = []
var arrayDB = []
var arrayCloud = []
var arrayServerRelease = []
for (var i = 0; i < installs.length; i++) {
arrayOS.push(this.state.installs[i].object.hardwareStackDetails.operatingSystem)
arrayApp.push(this.state.installs[i].object.hardwareStackDetails.applicationServer)
arrayDB.push(this.state.installs[i].object.hardwareStackDetails.database)
arrayCloud.push(this.state.installs[i].object.cloud)
arrayServerRelease.push(this.state.installs[i].object.serverRelease)
}
var operatingSystemTemp = arrayOS.unique();
var applicationServerTemp = arrayApp.unique();
var dataBaseTemp = arrayDB.unique();
var cloudTemp = arrayCloud.unique();
var serverReleaseTemp = arrayServerRelease.unique();
arrayOS = []
arrayApp = []
arrayDB = []
arrayCloud = []
arrayServerRelease = []
for (var i = 0; i < operatingSystemTemp.length; i++) {
arrayOS.push({
text: operatingSystemTemp[i],
value: operatingSystemTemp[i]
})
}
for (var i = 0; i < applicationServerTemp.length; i++) {
arrayApp.push({
text: applicationServerTemp[i],
value: applicationServerTemp[i]
})
}
for (var i = 0; i < dataBaseTemp.length; i++) {
arrayDB.push({
text: dataBaseTemp[i],
value: dataBaseTemp[i],
})
}
for (var i = 0; i < cloudTemp.length; i++) {
arrayCloud.push({
text: cloudTemp[i],
value: cloudTemp[i]
})
}
for (var i = 0; i < serverReleaseTemp.length; i++) {
arrayServerRelease.push({
text: serverReleaseTemp[i],
value: serverReleaseTemp[i]
})
}
if (isLoadedFilteredData){
if(filteredData.length === 0) {
console.log("filteredData")
mapNew = new Map();
labelMap = {};
xlabels = []
seriesDataValue = []
Highcharts.chart('container', {
title: {
text: ''
},
subtitle: {
// text: 'Source: thesolarfoundation.com'
},
xAxis: {
categories: xlabels
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
series: seriesDataValue,
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
}
);
}
else {
console.log(filteredData)
var mapNew = new Map();
var labelMap = {};
var xlabels = []
var seriesDataValue = []
for (var j = 0; j < filteredData.length; j++) {
if (filteredData[j].object.status === "PASS") {
var date1 = moment(filteredData[j].object.creationTime);
var date2 = moment(filteredData[j].object.updationTime);
var ms = moment(date2, "DD/MM/YYYY HH:mm:ss").diff(moment(date1, "DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
// var s = d.format("hh:mm:ss");
console.log(ms)
console.log(d.hours())
var timeInhrs = d.hours()
if (mapNew.has(filteredData[j].object.clientBuild)) {
// timeInhrs = ((timeInhrs + mapNewInnerTemp.get(this.state.kuch[j].object.clientBuild)));
console.log(this.state.filteredData[j].object.clientBuild + " " + timeInhrs);
mapNew.set(this.state.filteredData[j].object.clientBuild, timeInhrs);
} else {
console.log(this.state.filteredData[j].object.clientBuild + " " + timeInhrs);
mapNew.set(this.state.filteredData[j].object.clientBuild, timeInhrs);
labelMap[this.state.filteredData[j].object.clientBuild] = 0; ///
//count = count + 1;
}
}
}
console.log(mapNew)
for (var key in labelMap) {
xlabels.push(key);
}
console.log(xlabels)
var dataValue = [] // array
for (const entry of mapNew.entries()) {
console.log(entry)
for (var key in labelMap) {
if (key === entry[0]) {
dataValue.push(entry[1])
}
}
}
console.log(dataValue)
seriesDataValue.push(
{
data: dataValue,
})
console.log(seriesDataValue)
var elementExists = document.getElementById("container");
if(elementExists === null){
let div = document.createElement("div");
div.id="container";
div.id="select"
document.body.appendChild(div);
}
Highcharts.chart('container',
xAxis: {
categories: xlabels
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
series: seriesDataValue,
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
}
);
}
}
return (
<div>
<div id="container"> </div>
</div>
);
}
}
}
The above error gets vanished after the page gets refreshed .
The error results from the fact that you create a chart before a div element with the 'container' id is created.
However, to avoid such problems I recommend you to use officially supported Highcharts wrapper for React: https://www.npmjs.com/package/highcharts-react-official

How to clear the vue warn when I use vue-slider-component?

The issue detail:
1. I implement the feature with the vue-slider-component module, but that has a lot of warnings when I move the dots on the slider.
2. I know that the reason is that I used v-for to point to an object that will change, but I do not know how to fix this issue.
the following link is my test site:
https://jsfiddle.net/ncwv84x9/
enter image description here
My codes:
code1 (Html)
<div id="app">
<div class="box" v-for="(item,index) in columnvalue">
<label>{{item.text}}</label>
<input v-model="value[index]" />
</div>
<hr />
<br />
<vue-slider v-model="value" :order="false" :tooltip="'always'" :process="false" :marks="marks" :width="600">
<template slot="tooltip" slot-scope="{index}">
<div>{{getText(index)}}</div>
</template>
</vue-slider>
</div>
JavaScript + Vue:
new Vue({
el: '#app',
components: {
VueSlider: window['vue-slider-component']
},
data: function() {
return {
// collect the all values
columnvalue: [],
// stored disease value
pet_name: [{
text: 'dog',
index: 0
},
{
text: 'cat',
index: 1
}
],
// stored drug value
feeder_name: [{
text: 'Sam',
index: 0
}],
// from age filter
age: [
65, 100
],
test: "",
value: [],
process: dotsPos => [
[dotsPos[0], dotsPos[1], {
backgroundColor: 'pink'
}],
[dotsPos[1], dotsPos[2], {
backgroundColor: 'blue'
}],
[dotsPos[2], dotsPos[3], {
backgroundColor: 'black'
}],
],
after: {},
relations: [],
marks: {
'0': {
label: 'start',
margin: '0 0 0 10px'
},
'100': {
label: 'end',
labelStyle: {
left: '100%',
margin: '0 0 0 10px',
top: '50%',
transform: 'translateY(-50%)'
}
}
}
}
},
created: function() {
//vue instance 被 constructor 建立後,在這裡完成 data binding
let tmpArray = this.pet_name.concat(this.feeder_name);
let tmpValueArray = [];
for (i = 0; i < tmpArray.length; i++) {
tmpArray[i].index = i;
tmpValueArray.push(0);
}
this.columnvalue = tmpArray;
this.value = tmpValueArray;
},
methods: {
getText(index) {
const ani = this.columnvalue.find((v) => v.index == index).text;
this.after = {
...this.after,
[ani]: this.value[index]
}
return ani;
},
getNodeRelation() {
const indexs = this.after;
let result = [];
let result2 = [];
let placement = [];
for (obj in indexs) {
placement.push([obj, indexs[obj]]);
}
placement.sort(function(a, b) {
/* console.log(a[1]) */
return a[1] - b[1];
})
for (i = 0; i < placement.length; i++) {
if (i + 1 >= placement.length) {
break;
}
let distance = placement[i + 1][1] - placement[i][1];
let predicate = "";
if (distance > 0) {
predicate = "after";
} else if (distance == 0 && placement[i + 1][1] == 0) {
predicate = "hasUse";
} else {
predicate = "same";
}
let source = {
label: placement[i][0],
index: i
};
let target = {
label: placement[i + 1][0],
index: i
};
// store the 4-tuple reprsentations about slider
result2.push({
source: source,
target: target,
type: predicate,
days: distance
});
}
/* this.relations = "{\"relation\":" + JSON.stringify(result2)+"}" */
;
this.relations = JSON.stringify(result2);
},
getAllFilters() {
let vm = this;
let beginHas = true;
if (vm.relations.length == 0) {
vm.getNodeRelation();
beginHas = false;
}
let result = {
age: vm.age,
disease_name: vm.disease_name,
drug_name: vm.drug_name,
relation: vm.relations
};
if (!beginHas) {
vm.relations = [];
}
this.test = JSON.stringify(result);
}
},
})
I get a infinite loop error which disappears when I remove this section in getText()
this.after = {
...this.after,
[ani]: this.value[index]
}
This is because there is some reactivity triggered and re-renders the dom, which calls that function, which renders the dom and so on...

Expected an identifier and instead saw '<'

I get this error at the very beginning. Not sure how to fix. I also get the expected an assignment or function call and instead saw an expression. Not to mention Expected an identifier and instead saw "var"
<script>
var interactiveSearch = {};
(function() {
interactiveSearch.common = {
init: function() {
interactiveSearch.common.setupDataTableDefaults();
$.ajaxSetup({
cache: false
});
},
setupDataTableDefaults: function() {
$.extend($.fn.dataTable.defaults, {
"sDom": "<'table-header-controls'<'row'<l><f>>r><i>t<'table-footer-controls'<'row'<'span12'p><'span12'i>>>",
"sPaginationType": "bootstrap",
"bJQueryUI": false,
"bProcessing": false,
"bServerSide": true,
"fnServerData": interactiveSearch.common.getTableData
});
},
getTableData: function(sSource, aoData, fnCallback) {
var data = new Array();
var columnCount = _.find(aoData, function(o) {
return o.name == 'iColumns';
}).value;
var echo = _.find(aoData, function(o) {
return o.name == 'sEcho';
}).value;
var skip = _.find(aoData, function(o) {
return o.name == 'iDisplayStart';
}).value;
var take = _.find(aoData, function(o) {
return o.name == 'iDisplayLength';
}).value;
var search = _.find(aoData, function(o) {
return o.name == 'sSearch';
}).value;
var sortCols = _.filter(aoData, function(o) {
return o.name.indexOf('iSortCol_') == 0;
});
var sortDirs = _.filter(aoData, function(o) {
return o.name.indexOf('sSortDir_') == 0;
});
var searches = _.filter(aoData, function(o) {
return o.name.indexOf('sSearch_') == 0;
});
data.push({
"name": "TableEcho",
"value": echo
});
data.push({
"name": "Skip",
"value": skip
});
data.push({
"name": "Take",
"value": take
});
data.push({
"name": "AllSearch",
"value": search
});
var actual = 0;
_.each(sortCols, function(columnSort, sortIndex) {
var columnIndex = columnSort.value;
var columnSearch = searches[columnIndex].value;
var sortDir = sortDirs[sortIndex].value;
data.push({
"name": "Columns[" + actual + "].ColumnIndex",
"value": columnIndex
});
data.push({
"name": "Columns[" + actual + "].SortDirection",
"value": sortDir
});
if (columnSearch != '') {
data.push({
"name": "Columns[" + actual + "].SearchTerm",
"value": columnSearch
});
}
actual++;
});
for (var i = 0; i < columnCount; i++) {
var searchTerm = searches[i].value;
if (searchTerm == '') {
continue;
}
data.push({
"name": "Columns[" + actual + "].ColumnIndex",
"value": i
});
data.push({
"name": "Columns[" + actual + "].SearchTerm",
"value": searchTerm
});
actual++;
}
$.post(sSource, data)
.success(fnCallback);
}
};
})();
$(function() {
interactiveSearch.common.init();
});
(function() {
var product = interactiveSearch.product = {};
product.init = function() {
product.initDataTable();
product.bindEvents();
};
function convertFullRowToDataObject(fullRow) {
return {
Id: fullRow[0],
ProductName: fullRow[1],
Synonym: fullRow[2],
Acronym: fullRow[3],
CasNo: fullRow[4],
EinecsNo: fullRow[5],
Formula: fullRow[6],
MolecularWeight: fullRow[7],
Status: fullRow[8],
MeltingPoint: fullRow[9],
BoilingPoint: fullRow[10],
HasDoc: fullRow[11] !== '',
RelatedDocPath: product.baseUrl + fullRow[11],
HasDImage: fullRow[12] !== '',
ImagePath: product.baseUrl + fullRow[12]
};
}
product.initDataTable = function() {
product.productTable = $("#product-table").dataTable({
aaSorting: [
[1, "asc"]
],
iDisplayLength: 15,
bServerSide: true,
bDestroy: true,
sAjaxSource: interactiveSearch.product.listUrl,
fnRowCallback: function(nRow, aData) {
$(nRow).data('rowInfo', convertFullRowToDataObject(aData));
},
aoColumns: [{
sType: "string",
sClass: "dtAlignLeft",
mData: 1
}]
});
};
product.bindEvents = function() {
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g,
evaluate: /\{\[([\s\S]+?)\]\}/g
};
var templateText = $('#productDetailTemplate').html(),
compiledTemplate = _.template(templateText);
$(document).on('click', '#product-table tr', function(e) {
var el = $(this);
var rowData = el.data('rowInfo');
var html = compiledTemplate(rowData);
$('#productDetailContainer').empty().html(html);
$('#product-table tr').removeClass('active');
el.addClass('active');
});
$('#searchClone').on('keyup', function(e) {
var el = $(this);
var mimicEl = $('#product-table_filter input');
mimicEl.val(el.val()).trigger('keyup');
})
$('.btn-reset-filter').on('click', function() {
$('#searchClone').val('').trigger('keyup');
});
};
})();
$(document).ready(function() {
interactiveSearch.product.listUrl = '/pa/Product/ListItems';
interactiveSearch.product.baseUrl = '/pa/';
interactiveSearch.product.init();
});
</script>
In .js files you don't have to put <script>, you can just write your code.
<script> is for HTML files when you have to insert a script in the middle of the page.
So you have to delete <script> and </script> in your file.

Adding a link to each stacked bar chart item

I have a stacked bar chart I am trying to make each item in the chart that is clicked open the sharepoint view based on what was clicked.
I am building the data here
seriesData.push({ name: xStatus[i], data: dataArray, url: countArray[i].url });
my chart code looks like this:
loadStackedBarChartWithLink = function (xCategories, seriesData, divId, chartTitle, yAxisTitle) {
//Build Stacked Bar Chart
$(divId).highcharts({
chart: {
type: 'bar'
},
credits: {
enabled: false
},
title: {
text: chartTitle
},
xAxis: {
categories: xCategories,
allowDecimals: false
},
yAxis: {
min: 0,
allowDecimals: false,
title: {
text: yAxisTitle
}
},
legend: {
backgroundColor: '#FFFFFF',
reversed: true
},
plotOptions: {
series: {
cursor: 'pointer',
stacking: 'normal',
point: {
events: {
click: function () {
location.href = this.options.url;
}
}
}
}
},
series: seriesData
});
}
The chart has the correct data, pointer is correct but I get 'undefined' for the url.
Any help is greatly appreciated.
IWSChartBuilder.PersonEngagementsByStatusChart = function () {
var load = function () {
$.when(
IWSChartBuilder.RESTQuery.execute(GET THE DATA HERE)
).done(
function (engagements1) {
var data = [];
var countArray = [];
var urls = [];
var results = engagements1.d.results;
for (var i = 0; i < results.length; i++) {
if (results[i].Consultant.Title == undefined) {
continue;
}
var found = false;
for (var j = 0; j < data.length; j++) {
if (data[j].personName == results[i].Consultant.Title && data[j].statusName == results[i].Engagement_x0020_Status) {
data[j].statusCount = data[j].statusCount + 1;
found = true;
}
}
if (!found) {
data.push(new IWSChartBuilder.StatusByPerson(results[i].Consultant.Title, results[i].Engagement_x0020_Status, 1));
}
}
//Put data into format for stacked bar chart
var seriesData = [];
var xCategories = [];
var xStatus = [];
var i, j, cat, stat;
//Get Categories (Person Name)
for (i = 0; i < data.length; i++) {
cat = data[i].personName;
if (xCategories.indexOf(cat) === -1) {
xCategories[xCategories.length] = cat;
}
}
//Get Status values
for (i = 0; i < data.length; i++) {
stat = data[i].statusName;
if (xStatus.indexOf(stat) === -1) {
xStatus[xStatus.length] = stat;
}
}
//Create initial series data with 0 values
for (i = 0; i < xStatus.length; i++) {
var dataArray = [];
for (j = 0; j < xCategories.length; j++) {
dataArray.push(0);
}
seriesData.push({ name: xStatus[i], data: dataArray });
}
//Cycle through data to assign counts to the proper location in the series data
for (i = 0; i < data.length; i++) {
var personIndex = xCategories.indexOf(data[i].personName);
for (j = 0; j < seriesData.length; j++) {
if(seriesData[j].name == data[i].statusName){
seriesData[j].data[personIndex] = data[i].statusCount;
break;
}
}
}
//Build Chart
IWSChartBuilder.Utilities.loadStackedBarChartWithLink(xCategories, seriesData, "#engagementsByStatusChart", "Engagements by Status", "Total Projects");
}
).fail(
function (engagements1) {
$("#engagementsByStatusChart").html("<strong>An error has occurred.</strong>");
}
);
};
return {
load: load
}
}();
The way I am trying now
plotOptions: {
series: {
cursor: 'pointer',
stacking: 'normal',
point: {
events: {
click: function () {
getURL(this, xCategories, seriesData);
}
}
}
}
},
function getURL(chartInfo, xCategories, seriesData) {
var baseUrl = "correctURL" + xCategories[chartInfo._i] + "-FilterField2%3DEngagement%255Fx0020% 255FStatus-FilterValue2%3D" + chartInfo.name;
location.href = baseUrl;
}
You are hooking into the point click event handler. In this handler, 'this' refers to the point, not the series.
Try this:
plotOptions: {
series: {
cursor: 'pointer',
stacking: 'normal',
events: {
click: function () {
location.href = this.options.url;
}
}
}
},
http://jsfiddle.net/2DG84/
If you need URL's which depend on point values as well as the series, you can access both. e.g.
plotOptions: {
series: {
cursor: 'pointer',
stacking: 'normal',
point: {
events: {
click: function () {
alert(this.series.options.url + "&y=" + this.y);
}
}
}
}
},
In this example, there is a base URL on the series, by I am adding to the UTL with the point.y value.
http://jsfiddle.net/Fygg2/

Categories