SheetJS xlsx-style cell style in excel is not working - javascript

I want to set different baground color for each cell in xslx in angular4.
But no style effect appear on excel.Is there any solution?
My code is below.
import { saveAs } from 'file-saver';
const XLSX = require('xlsx');
const wb = {SheetNames: [], Sheets: {}};
const ws_name = 'Report';
/* create worksheet: */
const ws: any = {};
/* the range object is used to keep track of the range of the sheet */
const range = { s: { c: 0, r: 0 }, e: { c: 0, r: 0 } };
/* Iterate through each element in the structure */
for (let R = 0; R < data.length; R++) {
if (range.e.r < R) {
range.e.r = R;
}
for (let C = 0; C < data[R].length; C++) {
if (range.e.c < C) {
range.e.c = C;
}
// tslint:disable-next-line:max-line-length
const cell = { v: data[R][C], s: { alignment: { textRotation: 90 }, font: { sz: 16, bold: true, color: '#FF00FF' }, fill: { bgColor: '#FFFFFF' } }, t: 's' };
if (cell.v == null) {
continue;
}
/* create the correct cell reference */
const cell_ref = XLSX.utils.encode_cell({ c: C, r: R });
/* determine the cell type */
if (typeof cell.v === 'number') {
cell.t = 'n';
} else if (typeof cell.v === 'boolean') {
cell.t = 'b';
} else {
cell.t = 's';
}
/* add to structure */
ws[cell_ref] = cell;
}
}
ws['!ref'] = XLSX.utils.encode_range(range);
const wscols = [
{ wch: 4 }, // "characters"
{ wch: 3 },
{ wch: 20 },
{ wch: 45 },
{ wch: 13 },
{ wch: 30 },
{ wch: 15 },
{ wch: 5 },
{ wch: 20 },
{ wch: 3 },
{ wch: 15 },
{ wch: 15 },
{ wch: 12 },
{ wch: 75 }
];
ws['!cols'] = wscols;
wb.SheetNames.push(ws_name);
/**
* Set worksheet sheet to "narrow".
*/
ws['!margins'] = { left: 0.25, right: 0.25, top: 0.75, bottom: 0.75, header: 0.3, footer: 0.3 };
wb.Sheets[ws_name] = ws;
const wbout = XLSX.write(wb, {
type: 'binary',
bookSST: true,
bookType: 'xlsx',
cellStyles: true
});
saveAs(new Blob([this.s2ab(wbout)], { type: 'application/octet-stream' }), 'report.xlsx');
I installed both xlsx and xlsx-styles.
npm install xlsx ,
npm install xlsx-style
Any one can help me to find the solution.Thanks in advance.

Related

How to restrict linking between ports of elements if one link already exist between them in JointJS?

I have 3 elements with ports. My goal is to not allow linking ports between source and destination elements if one of their ports are already linked to each other. Please see my visualization below:
As you can see, I need only 1 to 1 connection between cells. How do I acheive this with JointJS? Please see my JSFiddle.
HTML
<html>
<body>
<button id="btnAdd">Add Table</button>
<div id="dbLookupCanvas"></div>
</body>
</html>
JS
$(document).ready(function() {
$('#btnAdd').on('click', function() {
AddTable();
});
InitializeCanvas();
// Adding of two sample tables on first load
AddTable(50, 50);
AddTable(250, 50);
AddTable(150, 180);
});
var graph;
var paper
var selectedElement;
var namespace;
function InitializeCanvas() {
let canvasContainer = $('#dbLookupCanvas').parent();
namespace = joint.shapes;
graph = new joint.dia.Graph({}, {
cellNamespace: namespace
});
paper = new joint.dia.Paper({
el: document.getElementById('dbLookupCanvas'),
model: graph,
width: canvasContainer.width(),
height: 500,
gridSize: 10,
drawGrid: true,
cellViewNamespace: namespace,
validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
// Prevent link to self
if (cellViewS === cellViewT)
return false;
// Prevent linking from input ports
if ((magnetS !== magnetT))
return true;
},
snapLinks: {
radius: 20
},
defaultLink: () => new joint.shapes.standard.Link({
router: {
name: 'manhattan'
},
connector: {
name: 'normal'
},
attrs: {
line: {
stroke: 'black',
strokeWidth: 1,
sourceMarker: {
'type': 'path',
'stroke': 'black',
'fill': 'black',
'd': 'M 10 -5 0 0 10 5 Z'
},
targetMarker: {
'type': 'path',
'stroke': 'black',
'fill': 'black',
'd': 'M 10 -5 0 0 10 5 Z'
}
}
}
})
});
//Dragging navigation on canvas
var dragStartPosition;
paper.on('blank:pointerdown',
function(event, x, y) {
dragStartPosition = {
x: x,
y: y
};
}
);
paper.on('cell:pointerup blank:pointerup', function(cellView, x, y) {
dragStartPosition = null;
});
$("#dbLookupCanvas")
.mousemove(function(event) {
if (dragStartPosition)
paper.translate(
event.offsetX - dragStartPosition.x,
event.offsetY - dragStartPosition.y);
});
// Remove links not connected to anything
paper.model.on('batch:stop', function() {
var links = paper.model.getLinks();
_.each(links, function(link) {
var source = link.get('source');
var target = link.get('target');
if (source.id === undefined || target.id === undefined) {
link.remove();
}
});
});
paper.on('cell:pointerdown', function(elementView) {
resetAll(this);
let isElement = elementView.model.isElement();
if (isElement) {
var currentElement = elementView.model;
currentElement.attr('body/stroke', 'orange');
selectedElement = elementView.model;
} else
selectedElement = null;
});
paper.on('blank:pointerdown', function(elementView) {
resetAll(this);
});
$('#dbLookupCanvas')
.attr('tabindex', 0)
.on('mouseover', function() {
this.focus();
})
.on('keydown', function(e) {
if (e.keyCode == 46)
if (selectedElement) selectedElement.remove();
});
}
function AddTable(xCoord = undefined, yCoord = undefined, portID = undefined) {
// This is a sample database data here
let data = [{
columnName: "radomData1"
},
{
columnName: "radomData2"
}
];
if (xCoord == undefined && yCoord == undefined) {
xCoord = 50;
yCoord = 50;
}
const rect = new joint.shapes.standard.Rectangle({
position: {
x: xCoord,
y: yCoord
},
size: {
width: 150,
height: 200
},
ports: {
groups: {
'a': {},
'b': {}
}
}
});
$.each(data, (i, v) => {
const port = {
group: 'a',
args: {}, // Extra arguments for the port layout function, see `layout.Port` section
label: {
position: {
name: 'right',
args: {
y: 6
} // Extra arguments for the label layout function, see `layout.PortLabel` section
},
markup: [{
tagName: 'text',
selector: 'label'
}]
},
attrs: {
body: {
magnet: true,
width: 16,
height: 16,
x: -8,
y: -4,
stroke: 'red',
fill: 'gray'
},
label: {
text: v.columnName,
fill: 'black'
}
},
markup: [{
tagName: 'rect',
selector: 'body'
}]
};
rect.addPort(port);
});
rect.resize(150, data.length * 40);
graph.addCell(rect);
}
function resetAll(paper) {
paper.drawBackground({
color: 'white'
});
var elements = paper.model.getElements();
for (var i = 0, ii = elements.length; i < ii; i++) {
var currentElement = elements[i];
currentElement.attr('body/stroke', 'black');
}
var links = paper.model.getLinks();
for (var j = 0, jj = links.length; j < jj; j++) {
var currentLink = links[j];
currentLink.attr('line/stroke', 'black');
currentLink.label(0, {
attrs: {
body: {
stroke: 'black'
}
}
});
}
}
Any help would be appreciated. Thanks!
If you add another condition to validateConnection, it should do the trick.
If you compare the links of the source and target, then return false if they already contain a link with the same ID.
The following seems to work well in your JSFiddle.
validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
// Prevent link on body
if (magnetT == null)
return false;
// Prevent link to self
if (cellViewS === cellViewT)
return false;
const sourceCell = cellViewS.model;
const sourceLinks = graph.getConnectedLinks(sourceCell);
const targetCell = cellViewT.model;
const targetLinks = graph.getConnectedLinks(targetCell);
let isConnection;
// Compare link IDs of source and target elements
targetLinks.forEach((linkT) => {
sourceLinks.forEach((linkS) => {
if (linkS.id === linkT.id) isConnection = true;
});
});
// If source and target already contain a link with the same id , return false
if (isConnection) return false;
// Prevent linking from input ports
if ((magnetS !== magnetT))
return true;
},

I got error in react while using normal javascript

i am working on react-flow, and my task is to transform the following data => `
`const configObj = {
name: "Dataset",
nodeChild: {
type: "schema",
nodeConfiguration: {
sid1: {
name: "Schema 1",
nodeChild: {
type: "dashboard",
nodeConfiguration: {
did1: {
name: "Dashboard 1"
}
}
}
},
sid2: {
name: "Schema 2",
nodeChild: {
type: "dashboard",
nodeConfiguration: {
did2: {
name: "Dashboard s1",
},
did3: {
name: "Dashboard 3"
}
}
}
}
}
}
}` to this ->
const elements = [
{
id: '1',
type: 'input', // input node
data: { label: 'Input Node' },
position: { x: 250, y: 25 },
},
// default node
{
id: '2',
// you can also pass a React component as a label
data: { label: <div>Default Node</div> },
position: { x: 100, y: 125 },
},
{
id: '3',
type: 'output', // output node
data: { label: 'Output Node' },
position: { x: 250, y: 250 },
},
// animated edge
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e2-3', source: '2', target: '3' },
];
`
not exactly but according to data1 so i prepare a code for it and it is working well in node environment but the moment i try it on react it shows some errorenter image description here here is my code
const configObj = {
name: "Dataset",
onClick: true,
nodeChild: {
type: "schema",
nodeConfiguration: {
sid1: {
name: "Schema 1",
nodeChild: {
type: "dashboard",
nodeConfiguration: {
did1: {
name: "Dashboard 1"
}
}
}
},
sid2: {
name: "Schema 2",
nodeChild: {
type: "dashboard",
nodeConfiguration: {
did2: {
name: "Dashboard s1",
nodeChild: {
type: "ritik",
nodeConfiguration: {
ri1: {
name: "Ritik",
}
}
}
},
did3: {
name: "Dashboard 3"
}
}
}
}
}
},
}
let count =1;
let dataConfig = []
const recursion = (obj, level,type) => {
let objData = {}
for(let j in obj){
if(j !== 'nodeChild' && j !== 'nodeParent'){
if(j === 'name'){
objData= {
...objData,
label: obj[j]
}
}else {
objData= {
...objData,
[j]: obj[j]
}
}
}
}
let idd = count
dataConfig = [...dataConfig, {id: count, data: objData, type, level, parentID}]
count++;
if('nodeChild' in obj){
const {nodeConfiguration, type} = obj.nodeChild
for(let val in nodeConfiguration){
recursion(nodeConfiguration[val], level+1, type, parentID = idd)
}
}
if('nodeParent' in obj){
const {nodeConfiguration, type} = obj.nodeParent
for(let val in nodeConfiguration){
recursion(nodeConfiguration[val], level-1, type)
}
}
}
recursion(configObj, level=0, type='root', parentID=1)
let edges = []
for(let i=1; i<dataConfig.length; i++){
let e = {
id: `e${dataConfig[i].id}-${dataConfig[i].parentID}`,
source: `${dataConfig[i].parentID}`, target: `${dataConfig[i].id}`, animated: true
}
edges = [
...edges,
e
]
}
let finalDataSet = []
let x=650, y=25;
let flag = false;
for(let i in dataConfig){
let element = {}
for(let key in dataConfig[i]){
if(key !== 'parentID'){
if(key === 'type'){
let k = dataConfig[i][key]
if(k === 'schema' || k === 'root'){
element = {
...element,
[key]: 'input'
}
}else {
element = {
...element,
[key]: 'output'
}
}
}else {
element = {
...element,
[key]: dataConfig[i][key]
}
}
}
}
element = {
...element,
position: { x, y }
}
// console.log(i)
finalDataSet = [
...finalDataSet,
element
]
y += 75;
if(!flag){
x = 25;
}
x = flag ? x+155 : x
flag = true
}
for(let i =0; i<edges.length; i++){
finalDataSet = [
...finalDataSet,
edges[i]
]
}
const DataSET = finalDataSet
export default DataSET
this code is perfectly working on local nodejs but the same code pops errors on react.js can any one help me on this
It's the recursion(configObj, level=0, type='root', parentID=1) calls that are causing trouble. You think that level=0 is saying to pass 0 to the level parameter but javascript doesn't recognize that syntax. It thinks that level is some variable you forgot to define. Hence the is not defined error.
To fix the issue, just do something like recursion(configObj, 0, 'root', 1) instead.

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...

Creating 3 worksheets in one workbook (Excel-JS) problem

I need a create an one excel file with 3 worksheets. For now I wrote a function which create worksheet and workbook. I have problem because I need write data into workshet in some executed async function. Maybe some code will describe what I have to do.
var Excel = require('exceljs');
const workbook = new Excel.Workbook({
useStyles: true
})
const headers = [
{ header: 'Plik', key: 'path', width: 40 },
{ header: 'Zwierze', key: 'name', width: 12 },
{ header: 'Prawdopodobienstwo(%)', key: 'confidence', width: 24 },
{ header: 'Czas odpowiedzi(s)', key: 'responseTime', width: 20 }
];
workbook.xlsx.writeFile("./excel/Wyniki.xlsx");
setWorkSheet = (name, responses, filename) => {
workbook.xlsx.readFile(filename)
.then(function () {
const worksheet = workbook.addWorksheet(name);
worksheet.columns = headers;
for (let i = 0; i < responses.length; i++) {
worksheet.addRow(responses[i]);
}
worksheet.getRow(1).style.font = { size: 12, name: 'Bahnschrift SemiBold SemiConden' }
worksheet.getRow(1).eachCell((cell) => {
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: '993399' }
},
cell.style.font = {
color: {
argb: 'ffffff'
},
size: 14,
}
})
worksheet.eachRow((Row, rowNumber) => {
Row.alignment = {
horizontal: 'center',
}
Row.eachCell((Cell, cellNumber) => {
Cell.alignment = {
vertical: 'middle',
horizontal: 'center'
},
Cell.border = {
top: { style: 'double', color: { argb: 'black' } },
left: { style: 'double', color: { argb: 'black' } },
bottom: { style: 'double', color: { argb: 'black' } },
right: { style: 'double', color: { argb: 'black' } }
}
})
})
worksheet.views = [
{ state: 'frozen', xSplit: 1, ySplit: 1, activeCell: 'B2' },
];
return workbook.xlsx.writeFile(`${filename}`)
})
.then(function () {
console.log("Done");
})
.catch(function (err) {
console.log(err)
});
}
And this function for now create a new file with special defined name worksheet. I need execute this function 3 times and after this operations I need to have one file and 3 worksheets. Here are places where I executed this function:
async function Cognitive() {
let tab = [];
for (let i = 0; i < arrayOfFiles.length; i++) {
let x = await cognitive.cognitiveDetectLabels(arrayOfFiles[i]);
tab.push(x)
}
setWorkSheet('Cognitive', tab, "./excel/Wyniki.xlsx");
}
exports.Cognitive = Cognitive;
async function Rekognition() {
let tab = [];
const path = "./csv/Rekognition.csv";
for (let i = 0; i < arrayOfFiles.length; i++) {
let x = await rekognitionFile.callaws(arrayOfFiles[i]);
tab.push(x)
}
setWorkSheet("Rekognition", tab, "./excel/Wyniki.xlsx");
}
exports.Rekognition = Rekognition;
async function Vision() {
let tab = [];
for (let i = 0; i < arrayOfFiles.length; i++) {
let x = await vision.callVision(arrayOfFiles[i]);
tab.push(x)
}
setWorkSheet("Vision", tab, "./excel/Wyniki.xlsx");
}
exports.Vision = Vision;
When I execute one of this async function. File with worksheet always is overwritten.
However, I need to add sheets to one file (3 sheets). Anyone have some ideas about this problem ? Thank you

How to add value in the tooltip in graph Highcharts?

There is a chart that shows the statistics , production has been sold in any quantity in any city.
enter image description here
I need to add another value , for what amount it was sold . On the second day I'm sitting , I can not figure out how to do it .
here is the link
function ev(str) {
eval(str)
}
function regression(x, y, typ) {
var type = (typ == null) ? 'linear' : typ;
var N = x.length;
var slope;
var intercept;
var SX = 0;
var SY = 0;
var SXX = 0;
var SXY = 0;
var SYY = 0;
var Y = [];
var X = [];
if (type == 'linear') {
X = x;
Y = y;
} else if (type == 'exp' || type == 'exponential') {
for (var i = 0; i < y.length; i++) {
// ignore points <= 0, log undefined.
if (y[i] <= 0) {
N = N - 1;
} else {
X.push(x[i]);
Y.push(Math.log(y[i]));
}
}
}
for (var i = 0; i < N; i++) {
SX = SX + X[i];
SY = SY + Y[i];
SXY = SXY + X[i] * Y[i];
SXX = SXX + X[i] * X[i];
SYY = SYY + Y[i] * Y[i];
}
slope = (N * SXY - SX * SY) / (N * SXX - SX * SX);
intercept = (SY - slope * SX) / N;
return [slope, intercept];
}
function linearRegression(X, Y) {
var ret;
ret = regression(X, Y, 'linear');
return [ret[0], ret[1]];
}
function expRegression(X, Y) {
var ret;
var x = X;
var y = Y;
ret = regression(x, y, 'exp');
var base = Math.exp(ret[0]);
var coeff = Math.exp(ret[1]);
return [base, coeff];
}
function fitData(data, typ) {
var type = (typ == null) ? 'linear' : typ;
var ret;
var res;
var x = [];
var y = [];
var ypred = [];
for (i = 0; i < data.length; i++) {
if (data[i] != null && Object.prototype.toString.call(data[i]) === '[object Array]') {
if (data[i] != null && data[i][0] != null && data[i][1] != null) {
x.push(data[i][0]);
y.push(data[i][1]);
}
} else if (data[i] != null && typeof data[i] === 'number') { //If type of X axis is category
x.push(i);
y.push(data[i]);
} else if (data[i] != null && Object.prototype.toString.call(data[i]) === '[object Object]') {
if (data[i] != null && data[i].x != null && data[i].y != null) {
x.push(data[i].x);
y.push(data[i].y);
}
}
}
if (type == 'linear') {
ret = linearRegression(x, y);
for (var i = 0; i < x.length; i++) {
res = ret[0] * x[i] + ret[1];
ypred.push([x[i], res]);
}
return {
data: ypred,
slope: ret[0],
intercept: ret[1],
y: function(x) {
return (this.slope * x) + this.intercept;
},
x: function(y) {
return (y - this.intercept) / this.slope;
}
};
} else if (type == 'exp' || type == 'exponential') {
ret = expRegression(x, y);
for (var i = 0; i < x.length; i++) {
res = ret[1] * Math.pow(ret[0], x[i]);
ypred.push([x[i], res]);
}
ypred.sort();
return {
data: ypred,
base: ret[0],
coeff: ret[1]
};
}
}
function showGraph(zero) {
zero = typeof zero === "undefined" ? true : zero
sourceData.sort(function(a, b) {
return a[0] - b[0]
})
series = {}
seriesSum = []
dateStart = new Date(sourceData[0][0].toString().replace(/(\d{4})(\d{2})(\d{2})/g, "$1-$2-$3"))
dateEnd = new Date(sourceData[sourceData.length - 1][0].toString().replace(/(\d{4})(\d{2})(\d{2})/g, "$1-$2-$3"))
sourceData.map(function(entry) {
var date = new Date(entry[0].toString().replace(/(\d{4})(\d{2})(\d{2})/g, "$1-$2-$3"))
var microtime = date.getTime()
var dealer = entry[2]
var sum = entry[3]
//int
if (typeof entry[1] === "undefined") {
entry[1] = 0
}
//create group
if (typeof series[dealer] === "undefined") {
series[dealer] = []
}
//find similar day
if (series[dealer].length > 0 && series[dealer][series[dealer].length - 1][0] === microtime) {
series[dealer][series[dealer].length - 1][1] += entry[1]
} else {
series[dealer].push([microtime, entry[1]])
}
//mixed sum
if (seriesSum.length > 0 && seriesSum[seriesSum.length - 1][0] === microtime) {
seriesSum[seriesSum.length - 1][1] += entry[1]
} else {
seriesSum.push([microtime, entry[1]])
}
})
seriesByName = {}
seriesArray = []
_.map(series, function(days, dealer) {
var newDays = []
if (zero) {
for (var dateTemp = new Date(dateStart.getTime()), i = 0; dateTemp < dateEnd; dateTemp.setDate(dateTemp.getDate() + 1)) {
var microtime = dateTemp.getTime()
try {
if (days[i][0] == microtime) {
newDays.push(days[i])
i++
} else {
newDays.push([microtime, 0])
}
} catch (error) {}
}
} else {
newDays = days
}
seriesByName[dealer] = newDays
seriesArray.push({
name: dealer,
data: newDays,
id: dealer,
dataGrouping: {
approximation: "sum",
enabled: true,
forced: true,
units: [
['day', [1]]
],
dateTimeLabelFormats: {
week: ['За 7 дней начиная от "%A, %b %e, %Y"', '%A, %b %e', '-%A, %b %e, %Y']
}
}
})
})
graphContainer = $('#graph').highcharts('StockChart', {
rangeSelector: {
buttons: [, {
type: 'month',
count: 1,
text: '1м'
}, {
type: 'month',
count: 2,
text: '2м'
}, {
type: 'month',
count: 6,
text: '6м'
}, {
type: 'year',
count: 1,
text: '1г'
}, {
type: 'all',
text: 'Весь'
}],
selected: 5
},
tooltip: {
//pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
animation: false,
valueDecimals: 0
},
yAxis: [{
/*labels: {
formatter: function () {
return (this.value > 0 ? ' + ' : '') + this.value + '%';
}
},*/
}, {
labels: {
enabled: false
}
}],
plotOptions: {
series: {
//compare: 'percent'
}
},
series: seriesArray,
legend: {
align: 'center',
verticalAlign: 'bottom',
layout: 'horizontal',
enabled: true
}
})
graph = graphContainer.highcharts()
grouped = false
$('#groupWeek').on('click', function() {
for (var i = 0; i < graph.series.length; i++) {
var serie = graph.series[i]
if (grouped) {
serie.update({
dataGrouping: {
units: [
['day', [1]]
]
}
})
} else {
serie.update({
dataGrouping: {
units: [
['week', [1]]
]
}
})
}
}
grouped = grouped ? false : true
if (grouped) {
$(this).text('Убрать группировку')
} else {
$(this).text('Группировать по неделям')
}
})
percent = false
$('#changePercent').on('click', function() {
for (var i = 0; i < graph.series.length; i++) {
var serie = graph.series[i]
if (percent) {
serie.update({
compare: 'value'
})
} else {
serie.update({
compare: 'percent'
})
}
}
percent = percent ? false : true
if (percent) {
$(this).text('Представить в значениях')
} else {
$(this).text('Представить в процентах')
}
})
trend = false
trendArrayId = []
$('#showTrendline').on('click', function() {
if (grouped) $('#groupWeek').trigger('click')
if (trend) {
while (trendArrayId.length) {
graph.get(trendArrayId.pop()).remove()
}
} else {
var countSeries = graph.series.length
for (var iteratorSeries = 0; iteratorSeries < countSeries; iteratorSeries++) {
var serie = graph.series[iteratorSeries]
if (serie.name !== 'Navigator') {
var data = fitData(seriesByName[serie.name]).data
trendArrayId.push('trend_' + serie.name)
graph.addSeries({
data: data,
color: serie.color,
visible: serie.visible,
linkedTo: serie.name,
name: 'Тенденция (' + serie.name + ')',
id: 'trend_' + serie.name,
dataGrouping: {
approximation: "sum",
enabled: true,
forced: true,
units: [
['day', [1]]
]
}
})
}
}
}
trend = trend ? false : true
if (trend) {
$(this).text('Убрать линии тенденции')
} else {
$(this).text('Вывести линии тенденции')
}
})
}
var sourceData = [
[20140829, 63, "Москва и МО", 100],
[20140930, 1, "Краснодар", 100],
[20140819, 1, "Краснодар", 100],
[20141120, 1, "Краснодар", 100],
[20141010, 1, "Краснодар", 100],
[20141003, 2, "Краснодар", 100],
[20140825, 81, "Москва и МО", 100],
[20140822, 77, "Москва и МО", 100],
[20140918, 90, "Москва и МО", 100],
[20140930, 128, "Москва и МО", 100],
[20141031, 85, "Москва и МО", 100],
[20140827, 105, "Москва и МО", 100],
[20141027, 141, "Москва и МО", 100],
];
if (!oldBrowser) {
$(showGraph(false));
}
One option would be to add a hidden series with your extra value to the chart series: { visible: false ... } and display the value only in the tooltip.
You can override the tooltip formatter using the following property:
http://api.highcharts.com/highcharts#tooltip.formatter
Ensuring you have tooltip: { shared: true ... } setting, you can access all series values for a given x value.
This gives you the flexibility to use a hidden series OR another option would be to have a reference dictionary that you can use to look up your extra value (using the x value as the key) and render it in the tooltip.

Categories