rawgit.com/CodeYellowBV/chartist-plugin-legend/master/chartist-plugin-legend.js VS unpkg.com/chartist-plugin-legend@0.6.2/chartist-plugin-legend.js

Created Diff never expires
167 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
237 lines
133 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
217 lines
(function (root, factory) {
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
// AMD. Register as an anonymous module.
define(['chartist'], function (chartist) {
define(['chartist'], function (chartist) {
return (root.returnExportsGlobal = factory(chartist));
return (root.returnExportsGlobal = factory(chartist));
});
});
} else if (typeof exports === 'object') {
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// only CommonJS-like enviroments that support module.exports,
// like Node.
// like Node.
module.exports = factory(require('chartist'));
module.exports = factory(require('chartist'));
} else {
} else {
root['Chartist.plugins.legend'] = factory(root.Chartist);
root['Chartist.plugins.legend'] = factory(root.Chartist);
}
}
}(this, function (Chartist) {
}(this, function (Chartist) {
/**
/**
* This Chartist plugin creates a legend to show next to the chart.
* This Chartist plugin creates a legend to show next to the chart.
*
*
*/
*/
'use strict';
'use strict';


var defaultOptions = {
var defaultOptions = {
className: '',
className: '',
classNames: false,
classNames: false,
removeAll: false,
removeAll: false,
legendNames: false,
legendNames: false,
clickable: true,
clickable: true,
onClick: null,
onClick: null,
position: 'top'
position: 'top'
};
};


Chartist.plugins = Chartist.plugins || {};
Chartist.plugins = Chartist.plugins || {};


Chartist.plugins.legend = function (options) {
Chartist.plugins.legend = function (options) {


function compareNumbers(a, b) {
return a - b;
}

// Catch invalid options
// Catch invalid options
if (options && options.position) {
if (options && options.position) {
if (!(options.position === 'top' || options.position === 'bottom' || options.position instanceof HTMLElement)) {
if (!(options.position === 'top' || options.position === 'bottom' || options.position instanceof HTMLElement)) {
throw Error('The position you entered is not a valid position');
throw Error('The position you entered is not a valid position');
}
}
if (options.position instanceof HTMLElement) {
if(options.position instanceof HTMLElement){
// Detatch DOM element from options object, because Chartist.extend
// Detatch DOM element from options object, because Chartist.extend currently chokes on circular references present in HTMLElements
// currently chokes on circular references present in HTMLElements
var cachedDOMPosition = options.position;
var cachedDOMPosition = options.position;
delete options.position;
delete options.position;
}
}
}
}


options = Chartist.extend({}, defaultOptions, options);
options = Chartist.extend({}, defaultOptions, options);


if (cachedDOMPosition) {
if(cachedDOMPosition){
// Reattatch the DOM Element position if it was removed before
// Reattatch the DOM Element position if it was removed before
options.position = cachedDOMPosition
options.position = cachedDOMPosition
}
}


return function legend(chart) {
return function legend(chart) {

var existingLegendElement = chart.container.querySelector('.ct-legend');
function removeLegendElement() {
if (existingLegendElement) {
var legendElement = chart.container.querySelector('.ct-legend');
// Clear legend if already existing.
if (legendElement) {
existingLegendElement.parentNode.removeChild(existingLegendElement);
legendElement.parentNode.removeChild(legendElement);
}
}
}


// Set a unique className for each series so that when a series is removed,
// Set a unique className for each series so that when a series is removed,
// the other series still have the same color.
// the other series still have the same color.
function setSeriesClassNames() {
if (options.clickable) {
chart.data.series = chart.data.series.map(function (series, seriesIndex) {
var newSeries = chart.data.series.map(function (series, seriesIndex) {
if (typeof series !== 'object') {
if (typeof series !== 'object') {
series = {
series = {
value: series
value: series
};
};
}
}

series.className = series.className || chart.options.classNames.series + '-' + Chartist.alphaNumerate(seriesIndex);
series.className = series.className || chart.options.classNames.series + '-' + Chartist.alphaNumerate(seriesIndex);
return series;
return series;
});
});
chart.data.series = newSeries;
}
}


function createLegendElement() {
var legendElement = document.createElement('ul'),
var legendElement = document.createElement('ul');
isPieChart = chart instanceof Chartist.Pie;
legendElement.className = 'ct-legend';
legendElement.className = 'ct-legend';
if (chart instanceof Chartist.Pie) {
if (chart instanceof Chartist.Pie) {
legendElement.classList.add('ct-legend-inside');
legendElement.classList.add('ct-legend-inside');
}
if (typeof options.className === 'string' && options.className.length > 0) {
legendElement.classList.add(options.className);
}
if (chart.options.width) {
legendElement.style.cssText = 'width: ' + chart.options.width + 'px;margin: 0 auto;';
}
return legendElement;
}
}

if (typeof options.className === 'string' && options.className.length > 0) {
// Get the right array to use for generating the legend.
legendElement.classList.add(options.className);
function getLegendNames(useLabels) {
return options.legendNames || (useLabels ? chart.data.labels : chart.data.series);
}
}


// Initialize the array that associates series with legends.
if (chart.options.width) {
// -1 indicates that there is no legend associated with it.
legendElement.style.cssText = 'width: ' + chart.options.width + 'px;margin: 0 auto;';
function initSeriesMetadata(useLabels) {
var seriesMetadata = new Array(chart.data.series.length);
for (var i = 0; i < chart.data.series.length; i++) {
seriesMetadata[i] = {
data: chart.data.series[i],
label: useLabels ? chart.data.labels[i] : null,
legend: -1
};
}
return seriesMetadata;
}
}


function createNameElement(i, legendText, classNamesViable) {
var removedSeries = [],
var li = document.createElement('li');
originalSeries = chart.data.series.slice(0);
li.classList.add('ct-series-' + i);

// Append specific class to a legend element, if viable classes are given
// Get the right array to use for generating the legend.
if (classNamesViable) {
var legendNames = chart.data.series,
li.classList.add(options.classNames[i]);
useLabels = isPieChart && chart.data.labels && chart.data.labels.length;
}
if (useLabels) {
li.setAttribute('data-legend', i);
var originalLabels = chart.data.labels.slice(0);
li.textContent = legendText;
legendNames = chart.data.labels;
return li;
}
}
legendNames = options.legendNames || legendNames;


// Append the legend element to the DOM
// Check if given class names are viable to append to legends
function appendLegendToDOM(legendElement) {
var classNamesViable = (Array.isArray(options.classNames) && (options.classNames.length === legendNames.length));
if (!(options.position instanceof HTMLElement)) {
switch (options.position) {
case 'top':
chart.container.insertBefore(legendElement, chart.container.childNodes[0]);
break;


case 'bottom':
// Loop through all legends to set each name in a list item.
chart.container.insertBefore(legendElement, null);
legendNames.forEach(function (legend, i) {
break;
var li = document.createElement('li');
}
li.className = 'ct-series-' + i;
} else {
// Append specific class to a legend element, if viable classes are given
// Appends the legend element as the last child of a given HTMLElement
if (classNamesViable) {
options.position.insertBefore(legendElement, null);
li.className += ' ' + options.classNames[i];
}
}
}
li.setAttribute('data-legend', i);
li.textContent = legend.name || legend;
legendElement.appendChild(li);
});


function addClickHandler(legendElement, legends, seriesMetadata, useLabels) {
chart.on('created', function (data) {
legendElement.addEventListener('click', function(e) {
// Append the legend element to the DOM
if(!(options.position instanceof HTMLElement))
{
switch (options.position) {
case 'top':
chart.container.insertBefore(legendElement, chart.container.childNodes[0]);
break;

case 'bottom':
chart.container.insertBefore(legendElement, null);
break;
}
}
else {
// Appends the legend element as the last child of a given HTMLElement
options.position.insertBefore(legendElement, null);
}
Text moved from lines 226-228
});

if (options.clickable) {
legendElement.addEventListener('click', function (e) {
var li = e.target;
var li = e.target;
if (li.parentNode !== legendElement || !li.hasAttribute('data-legend'))
if (li.parentNode !== legendElement || !li.hasAttribute('data-legend'))
return;
return;
e.preventDefault();
e.preventDefault();


var legendIndex = parseInt(li.getAttribute('data-legend'));
var seriesIndex = parseInt(li.getAttribute('data-legend')),
var legend = legends[legendIndex];
removedSeriesIndex = removedSeries.indexOf(seriesIndex);


if (!legend.active) {
if (removedSeriesIndex > -1) {
legend.active = true;
// Add to series again.
removedSeries.splice(removedSeriesIndex, 1);
li.classList.remove('inactive');
li.classList.remove('inactive');
} else {
} else {
legend.active = false;
if (!options.removeAll) {
li.classList.add('inactive');
// Remove from series, only if a minimum of one series is still visible.

if ( chart.data.series.length > 1) {
var activeCount = legends.filter(function(legend) { return legend.active; }).length;
removedSeries.push(seriesIndex);
if (!options.removeAll && activeCount == 0) {
li.classList.add('inactive');
// If we can't disable all series at the same time, let's
}
// reenable all of them:
// Set all series as active.
for (var i = 0; i < legends.length; i++) {
else {
legends[i].active = true;
removedSeries = [];
legendElement.childNodes[i].classList.remove('inactive');
var seriesItems = Array.prototype.slice.call(legendElement.childNodes);
}
seriesItems.forEach(function (item) {
}
item.classList.remove('inactive');
}
});

}
var newSeries = [];
}
var newLabels = [];
else {

// Remove series unaffected if it is the last or not
for (var i = 0; i < seriesMetadata.length; i++) {
removedSeries.push(seriesIndex);
if (seriesMetadata[i].legend != -1 && legends[seriesMetadata[i].legend].active) {
li.classList.add('inactive');
newSeries.push(seriesMetadata[i].data);
}
newLabels.push(seriesMetadata[i].label);
}
}
}


chart.data.series = newSeries;
// Reset the series to original and remove each series that
// is still removed again, to remain index order.
var seriesCopy = originalSeries.slice(0);
if (useLabels) {
if (useLabels) {
chart.data.labels = newLabels;
var labelsCopy = originalLabels.slice(0);
}
}


chart.update();
// Reverse sort the removedSeries to prevent removing the wrong index.
removedSeries.sort(compareNumbers).reverse();

removedSeries.forEach(function (series) {
seriesCopy.splice(series, 1);
if (useLabels) {
labelsCopy.splice(series, 1);
}
});


if (options.onClick) {
if (options.onClick) {
options.onClick(chart, e);
options.onClick(chart, e);
}
}

chart.data.series = seriesCopy;
if (useLabels) {
chart.data.labels = labelsCopy;
}

chart.update();
});
});
}
}


removeLegendElement();

var legendElement = createLegendElement();
var useLabels = chart instanceof Chartist.Pie && chart.data.labels && chart.data.labels.length;
var legendNames = getLegendNames(useLabels);
var seriesMetadata = initSeriesMetadata(useLabels);
var legends = [];

// Check if given class names are viable to append to legends
var classNamesViable = Array.isArray(options.classNames) && options.classNames.length === legendNames.length;

// Loop through all legends to set each name in a list item.
legendNames.forEach(function (legend, i) {
var legendText = legend.name || legend;
var legendSeries = legend.series || [i];

var li = createNameElement(i, legendText, classNamesViable);
legendElement.appendChild(li);

legendSeries.forEach(function(seriesIndex) {
seriesMetadata[seriesIndex].legend = i;
});

legends.push({
text: legendText,
series: legendSeries,
active: true
});
});

chart.on('created', function (data) {
appendLegendToDOM(legendElement);
Text moved to lines 142-144
});

if (options.clickable) {
setSeriesClassNames();
addClickHandler(legendElement, legends, seriesMetadata, useLabels);
}
};
};

};
};


return Chartist.plugins.legend;
return Chartist.plugins.legend;


}));
}));