Synchronise 3 Highcharts Trend Views - javascript

I'm looking for some help with syncing 3 line charts similar to this: http://jsfiddle.net/v2t171og/
Here is my code:
https://codepen.io/anon/pen/EerNyO
(function() {
var files = ["https://code.highcharts.com/stock/highstock.js", "https://code.highcharts.com/highcharts-more.js", "https://code.highcharts.com/highcharts-3d.js", "https://code.highcharts.com/modules/data.js", "https://code.highcharts.com/modules/exporting.js", "https://code.highcharts.com/modules/funnel.js", "https://code.highcharts.com/modules/annotations.js", "https://code.highcharts.com/modules/solid-gauge.js"],
loaded = 0;
if (typeof window["HighchartsEditor"] === "undefined") {
window.HighchartsEditor = {
ondone: [cl],
hasWrapped: false,
hasLoaded: false
};
include(files[0]);
} else {
if (window.HighchartsEditor.hasLoaded) {
cl();
} else {
window.HighchartsEditor.ondone.push(cl);
}
}
function isScriptAlreadyIncluded(src) {
var scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].hasAttribute("src")) {
if ((scripts[i].getAttribute("src") || "").indexOf(src) >= 0 || (scripts[i].getAttribute("src") === "http://code.highcharts.com/highcharts.js" && src === "https://code.highcharts.com/stock/highstock.js")) {
return true;
}
}
}
return false;
}
function check() {
if (loaded === files.length) {
for (var i = 0; i < window.HighchartsEditor.ondone.length; i++) {
try {
window.HighchartsEditor.ondone[i]();
} catch (e) {
console.error(e);
}
}
window.HighchartsEditor.hasLoaded = true;
}
}
function include(script) {
function next() {
++loaded;
if (loaded < files.length) {
include(files[loaded]);
}
check();
}
if (isScriptAlreadyIncluded(script)) {
return next();
}
var sc = document.createElement("script");
sc.src = script;
sc.type = "text/javascript";
sc.onload = function() {
next();
};
document.head.appendChild(sc);
}
function each(a, fn) {
if (typeof a.forEach !== "undefined") {
a.forEach(fn);
} else {
for (var i = 0; i < a.length; i++) {
if (fn) {
fn(a[i]);
}
}
}
}
var inc = {},
incl = [];
each(document.querySelectorAll("script"), function(t) {
inc[t.src.substr(0, t.src.indexOf("?"))] = 1;
});
function cl() {
if (typeof window["Highcharts"] !== "undefined") {
var options = {
"chart": {
"type": "line",
"height": 220,
"polar": false
},
"rangeSelector": {
"enabled": false
},
"title": {
"text": ""
},
"scrollbar": {
"enabled": false
},
"subtitle": {
"text": ""
},
"series": [{
"name": "RMS",
"_colorIndex": 0,
"_symbolIndex": 0,
"turboThreshold": 0,
"marker": {}
}, {
"name": "Minimum",
"_colorIndex": 1,
"_symbolIndex": 1
}, {
"name": "Maximum",
"_colorIndex": 2,
"_symbolIndex": 2
}, {
"name": "Threshold",
"_colorIndex": 3,
"_symbolIndex": 3
}],
"data": {
"csv": "\"Movement\";\"RMS\";\"Minimum\";\"Maximum\";\"Threshold\"\n1;12.87;12;15;14\n2;13.16;12;15;14\n3;12.92;12;15;14\n4;13.14;12;15;14\n5;12.88;12;15;14\n6;13.03;12;15;14\n7;12.76;12;15;14\n8;13.04;12;15;14\n9;12.72;12;15;14\n10;13.2;12;15;14",
"googleSpreadsheetKey": false,
"googleSpreadsheetWorksheet": false
},
"yAxis": [{
"title": {}
}],
"navigator": {
"adaptToUpdatedData": true,
"enabled": false
},
"pane": {
"background": []
},
"responsive": {
"rules": []
},
"plotOptions": {
"series": {
"animation": false
}
}
};
new Highcharts.StockChart("highcharts-aaf432a9-4966-4429-b3eb-d35fe01e2924", options);
}
}
})();
I've created the graphs but I can't connect them using the highcharts events or hairlines.
Any assistance would be appreciated.

First of all, you should look at the console, you have a few error there, related with the location of the scripts. Next, you need to change highlight method to onMouseOver:
$('#container').bind('mousemove touchmove touchstart', function(e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i++) {
chart = Highcharts.charts[i];
event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.onMouseOver(e);
}
}
});
API: https://api.highcharts.com/class-reference/Highcharts.Point#onMouseOver
Live demo: http://jsfiddle.net/BlackLabel/0gmrf64y/

Related

Javascript File tree Problem Testing issue

Here is a part of an application that creates a file tree data structure from JSON input. However, there are one or more bugs in this code. It seems that for some data sets this code creates an incorrect tree structure.
'use strict';
function FileTreeNode(nodeId, name, type) {
const children = [];
this.nodeId = nodeId;
this.name = name;
this.type = type;
this.parentNode = null;
this.setParent = function(parentNode) {
this.parentNode = parentNode;
};
this.addChild = function(node){
if (this.type !== 'DIRECTORY') {
throw "Cannot add child node to a non-directory node";
}
else{
children.push(node);
node.setParent(this);
}
};
this.getChildren = function() {
return children;
};
};
function FileTree() {
this.nodes = [];
this.getRootNodes = function() {
const result = [];
for (let i = 0; i < this.nodes.length; i++) {
if (!this.nodes[i].parentNode) {
result.push(this.nodes[i]);
}
}
return result;
};
this.findNodeById = function(nodeId) {
for (let i = 0; i < this.nodes.length; i++) {
if (this.nodes[i].nodeId === nodeId) {
return this.nodes[i];
}
}
return null;
};
this.createNode = function(nodeId, name, type, parentNode) {
const node = new FileTreeNode(nodeId, name, type);
if (parentNode != null) {
parentNode.addChild(node);
}
this.nodes.push(node);
}
};
export function createFileTree(input) {
const fileTree = new FileTree();
const nodenotFound = (inputNodeId,input)=>{
let result = input.filter((item) => item.id == inputNodeId);
// const fileTree2 = new FileTree();
let node=fileTree.createNode(result[0].id, result[0].name, result[0].type,fileTree.findNodeById(result[0].parentId));
return node;
}
for (const inputNode of input) {
var parentNode = null;
if(inputNode.parentId != undefined){
if(fileTree.findNodeById(inputNode.parentId)!=null){
parentNode = fileTree.findNodeById(inputNode.parentId)
}
else{
parentNode= nodenotFound(inputNode.parentId,input)
}
}
else{
parentNode=null
}
fileTree.createNode(inputNode.id, inputNode.name, inputNode.type, parentNode);
}
return fileTree;
}
and my test file is as follows
'use strict';
import { createFileTree } from '../src/app'
const getDataset = file =>
require(`../src/dataset/${file}`)
describe('fileTree', function () {
var traverseTreeAndFindNode = function(inputNode, nodes) {
if (!nodes) {
return undefined;
}
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (node.nodeId === inputNode.id) {
return node;
}
var nodeFoundAtChildren = traverseTreeAndFindNode(inputNode, node.getChildren());
if (nodeFoundAtChildren) {
return nodeFoundAtChildren;
}
}
return undefined;
};
function testTreeNode (inputNode, foundNode) {
it('tree node ' + inputNode.id + ' should have correct data', function() {
expect(foundNode.nodeId).toEqual(inputNode.id);
expect(foundNode.name).toEqual(inputNode.name);
expect(foundNode.type).toEqual(inputNode.type);
});
it('tree node ' + inputNode.id + ' should have correct parent', function () {
if (inputNode.parentId) {
expect(foundNode.parentNode).not.toBeNull();
expect(foundNode.parentNode.nodeId).toEqual(inputNode.parentId);
} else {
expect(foundNode.parentNode).toBeNull();
}
});
}
function testTreeContentsWithDataSet(dataSet) {
describe('created from ' + dataSet + ' dataSet', function() {
var inputData = getDataset(dataSet);
var fileTree = createFileTree(inputData);
for (var i = 0; i < inputData.length; i++) {
var inputNode = inputData[i];
var foundNode = traverseTreeAndFindNode(inputNode, fileTree.getRootNodes());
testTreeNode(inputNode, foundNode);
}
it('should contain all nodes from dataset', function () {
for (var i = 0; i < inputData.length; i++) {
expect(traverseTreeAndFindNode(inputData[i], fileTree.getRootNodes())).toBeDefined();
}
});
});
}
testTreeContentsWithDataSet('simple-data.json');
testTreeContentsWithDataSet('data-for-bug.json');
});
There are two JSON files used in the testing.
1.simple-data.json
[
{
"id": 877234010,
"name": "project",
"type": "DIRECTORY"
},
{
"id": 877234002,
"name": "src",
"type": "DIRECTORY",
"parentId": 877234010
},
{
"id": 877234003,
"name": "app",
"type": "DIRECTORY",
"parentId": 877234002
},
{
"id": 877234004,
"name": "app.js",
"type": "FILE",
"parentId": 877234003
}
]
the second one is data-for-bug.json
[
{
"id": 7832454551,
"name": "usr",
"type": "DIRECTORY"
},
{
"id": 7832454554,
"name": "applications",
"type": "DIRECTORY",
"parentId": 7832454553
},
{
"id": 7832454555,
"name": "mimeinfo.cache",
"type": "FILE",
"parentId": 7832454554
},
{
"id": 7832454553,
"name": "share",
"type": "DIRECTORY",
"parentId": 7832454552
},
{
"id": 7832454552,
"name": "local",
"type": "DIRECTORY",
"parentId": 7832454551
}
]
The result of the test run is
Using Jasmine version: 3.5.0
Started
............F...F...
Failures:
1) fileTree created from data-for-bug.json dataSet tree node 7832454554 should have correct parent
Message:
Expected null not to be null.
Stack:
Error: Expected null not to be null.
at <Jasmine>
at UserContext.<anonymous> (C:\Users\hp\Downloads\devskiller-code-PTQG-EEWG-46UW-S1F\test\/app.spec.js:39:42)
at <Jasmine>
Message:
TypeError: Cannot read property 'nodeId' of null
Stack:
at <Jasmine>
at UserContext.<anonymous> (C:\Users\hp\Downloads\devskiller-code-PTQG-EEWG-46UW-S1F\test\/app.spec.js:40:37)
at <Jasmine>
at processImmediate (internal/timers.js:464:21)
2) fileTree created from data-for-bug.json dataSet tree node 7832454553 should have correct parent
Message:
Expected null not to be null.
Stack:
Error: Expected null not to be null.
at <Jasmine>
at UserContext.<anonymous> (C:\Users\hp\Downloads\devskiller-code-PTQG-EEWG-46UW-S1F\test\/app.spec.js:39:42)
at <Jasmine>
Message:
TypeError: Cannot read property 'nodeId' of null
Stack:
at <Jasmine>
at UserContext.<anonymous> (C:\Users\hp\Downloads\devskiller-code-PTQG-EEWG-46UW-S1F\test\/app.spec.js:40:37)
at <Jasmine>
at processImmediate (internal/timers.js:464:21)
20 specs, 2 failures
Finished in 0.117 seconds
I couldn't notice what is wrong with the code.pls help

Expand flat object into hierarchical structure

I'm trying to find best approach to expand this flat structure
var input = [
{
"path":"/",
"size":1111
},
{
"path":"/test1",
"size":2222
},
{
"path":"/test1/folder2",
"size":3333
},
{
"path":"/test1/folder2",
"size":4444
},
{
"path":"/test7/folder1",
"size":5555
}
]
into this hierarchical structure
var expectedoutput = [{
"path": "/",
"size": 1111
},
{
"path": "/test1",
"size": 2222,
"items": [{
"path": "/test1/folder2",
"size": 3333,
},
{
"path": "/test1/folder2",
"size": 4444
}
]
},
{
"path": "/test7",
"items": [{
"path": "/test7/folder1",
"size": 5555
}]
}
]
Any ideas? please.
Not so bad approach, it work's but there is one scenario which it cannot handle
Scenario when parent node doesn't exists (should be created) i've commented this part.
Updated version with missing intermediate paths support
function expand_object(list) {
var map = {}, node, roots = [], i;
for (i = 0; i < list.length; i += 1) {
map[list[i].path] = i; // map
list[i].items = []; // place for children
}
for (i = 0; i < list.length; i += 1) {
node = list[i];
//find parent, example "path":"test1/folder2" parent= "test1"
var lastSlash = node.path.lastIndexOf('/');
if (lastSlash > 1) {
lastSlash = lastSlash == -1 ? node.path.length : lastSlash;
parentNode = node.path.substring(0, lastSlash);
}
else {
parentNode = "/";
}
if (parentNode !== "/") {
// creat missing nodes
if (!list[map[parentNode]]) {
list.push({ "name": parentNode ,"path": parentNode, "items": [] })
map[list[list.length-1].path] = list.length-1;
}
var c = list[map[parentNode]];
list[map[parentNode]].items.push(node);
} else {
roots.push(node);
}
}
return roots;
}
var input = [
{
"path":"/",
"size":1111
},
{
"path":"/",
"size":2222
},
{
"path":"/test1",
"size":2222
},
{
"path":"/test1/folder2",
"size":3333
},
{
"path":"/test1/folder2",
"size":4444
}
,
{ //Missing node
"path":"/test7/folder1",
"size":5555
}
]
console.log(expand_object(input));

compare two different arrays in javascript

can any one help in this i am trying to compare two different arrays for pushing values when comparision is equal. below are my two(imageslide.therapy),totalValues arrays and i want compare names like cats and dogs. if condition is true then i need to push their images urls.
var imageslide = {
"therapy": [
{
"name": "cats",
"images": [
{ "url": "cat/firstimg.jpg" },
{ "url": "cat/secondimg.jpg" },
{ "url": "cat/thirdimg.jpg" },
{ "url": "cat/fourthimg.jpg" }
]
},
{
"name": "dogs",
"images": [
{ "url": "dog/firstdog.jpeg" },
{ "url": "dog/seconddog.jpg" },
{ "url": "dog/thirddog.jpg" },
{ "url": "dog/fourthdog.jpg" }
]
},
]
}
var totalValues = ["cats","dogs"];
and i tried like below
var imageArray = imageslide.therapy
function compare(imageArray,totalValues ){
imageArray.forEach((e1)=>totalValues.forEach((e2)=>{
if(e1.name==e2){
console.log(e1.name,",",e2)
}
})
For what I understand from your question here is the answer. Please forgive me I don't know much about arrow function so I wrote it in simple javascript.
var imageslide = {
"therapy": [
{
"name": "cats",
"images": [
{ "url": "cat/firstimg.jpg" },
{ "url": "cat/secondimg.jpg" },
{ "url": "cat/thirdimg.jpg" },
{ "url": "cat/fourthimg.jpg" }
]
},
{
"name": "dogs",
"images": [
{ "url": "dog/firstdog.jpeg" },
{ "url": "dog/seconddog.jpg" },
{ "url": "dog/thirddog.jpg" },
{ "url": "dog/fourthdog.jpg" }
]
},
]
}
var totalValues = ["cats","dogs"];
var imageArray = imageslide.therapy
function compare(imageArray,totalValues ){
for(var i=0;i<imageArray.length;i++){
for(var j=0;j<totalValues.length;j++){
if(totalValues[j]=imageArray[i].name){
console.log(imageArray[i].name+"=="+totalValues[j]);
//imageArray[i].images.push({"url": "https://hexasoft.io"});
//break;
return imageArray[i].images;
}
}
}
//printResult(imageArray);
return [];
}
function printResult(resultArray){
for(var i=0;i<resultArray.length;i++) {
console.log(resultArray[i].name);
for(var j=0;j<resultArray[i].images.length;j++){
console.log(resultArray[i].images[j]);
}
}
}
images = compare(imageArray, totalValues);
if(images.length > 0){
for(var i=0;i<images.length; i++){
images[i].push({"url": "your url"});
}
}
Check out the javascript filter function (Link for the docs).
In your case, you want to do something like this:
function getImagesByAnimalName(animal_name){
var imageArray = imageslide.therapy;
var animalImages = imageArray.filter(animalData => {
return animalData.name === animal_name;
})
return animalImages[0].images;
}
Try it like this. The function will return URLs for each element in totalValues array.
var totalValues = ["cats"];
var slides = imageslide.therapy;
function comp(slides, totalValues ){
let retVal;
for( val of totalValues ) {
for( thisTh of slides ) {
if( thisTh.name == val ){
retVal = thisTh.images;
}
}
}
return retVal;
}
The following will create pics, a flat array of image URLs, if this is what you want:
var pics=[].concat(...imageslide.therapy.map(el=>{
if (totalValues.indexOf(el.name)>-1)
return el.images.map(e=>e.url)}))
console.log(pics);
function compare(imageArray, totalValues) {
for (var a = 0; a < imageArray.length; a++) {
for (var j = 0; j < totalValues.length; j++) {
if (totalValues[j] == imageArray[a].name) {
allValues.push(imageArray[a].images);
for (var i = 0; i < allValues.length; i++) {
for(var j = 0; j < allValues[i].length; j++){
buildSlide(allValues[i][j].url);
}
}
}
}
}
displaySlides(slide_index);
}

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.

Get the unique items - Handlebars

My JSON looks like this:
{
"features": [
{
"id": "belly",
"scenarios": [
{
"id": "belly;a-few-cukes",
"tags": [
{
"name": "#tag1"
}
],
"steps": [
{
"name": "I have 42 cukes in my belly"
},
{
"name": "I wait 1 hour"
},
{
"name": "my belly should growls"
}
]
},
{
"id": "belly;a-few-cukes-with-new-test",
"tags": [
{
"name": "#tag2"
}
],
"steps": [
{
"name": "I have 42 cukes in my belly"
},
{
"name": "I wait 1 hour"
},
{
"name": "my belly should growl"
}
]
}
]
},
{
"id": "newbelly",
"scenarios": [
{
"id": "newbelly;a-few-cukes-with-new-feature",
"tags": [
{
"name": "#tag1"
}
],
"steps": [
{
"name": "I have 42 cukes in my belly"
},
{
"name": "I wait 1 hour"
},
{
"name": "my belly should growls"
}
]
}
]
}
]
}
I would like to retrieve all the unique tag names: i.e., #tag1, #tag2. If you notice, the #tag1 is repeated twice.
My template:
{{#getTags features}}
{{#scenarios}}
{{#tags}}
<p>{{name}}</p>
{{/tags}}
{{/scenarios}}
{{/getTags}}
Custom Helper that I created so far:
Handlebars.registerHelper('getTags', function(context, block) {
var ret = "";
for (var i = 0; i < context.length; i++) {
ret += block.fn(context[i]);
};
return ret;
});
The above custom helper returns all the tags, but I want unique ones.
Something along these lines may work:
Handlebars.registerHelper('getTags', function(context, block) {
var ret = "";
var got = [];
function contains(obj, a) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
for (var i = 0; i < context.length; i++) {
if (!this.contains(context[i],got)) {
got.addObject(context[i]);
ret += block.fn(context[i]);
}
}
return ret;
});
Code used for testing, all javascript:
var ret = "";
var got = [];
var data = ["tag1", "tag1", "tag2", "tag3"]
function contains(obj, a) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
for (var i = 0; i < data.length; i++) {
if (!contains(data[i],got)) {
got.push(data[i]);
ret += data[i];
}
}
console.log( ret);

Categories