plotly.js
Version:
The open source javascript graphing library that powers plotly
182 lines (145 loc) • 5.07 kB
JavaScript
/**
* Copyright 2012-2020, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var isNumeric = require('fast-isnumeric');
var tinycolor = require('tinycolor2');
var Color = require('../../components/color');
var extendedColorWayList = {};
function calc(gd, trace) {
var cd = [];
var fullLayout = gd._fullLayout;
var hiddenLabels = fullLayout.hiddenlabels || [];
var labels = trace.labels;
var colors = trace.marker.colors || [];
var vals = trace.values;
var len = trace._length;
var hasValues = trace._hasValues && len;
var i, pt;
if(trace.dlabel) {
labels = new Array(len);
for(i = 0; i < len; i++) {
labels[i] = String(trace.label0 + i * trace.dlabel);
}
}
var allThisTraceLabels = {};
var pullColor = makePullColorFn(fullLayout['_' + trace.type + 'colormap']);
var vTotal = 0;
var isAggregated = false;
for(i = 0; i < len; i++) {
var v, label, hidden;
if(hasValues) {
v = vals[i];
if(!isNumeric(v)) continue;
v = +v;
if(v < 0) continue;
} else v = 1;
label = labels[i];
if(label === undefined || label === '') label = i;
label = String(label);
var thisLabelIndex = allThisTraceLabels[label];
if(thisLabelIndex === undefined) {
allThisTraceLabels[label] = cd.length;
hidden = hiddenLabels.indexOf(label) !== -1;
if(!hidden) vTotal += v;
cd.push({
v: v,
label: label,
color: pullColor(colors[i], label),
i: i,
pts: [i],
hidden: hidden
});
} else {
isAggregated = true;
pt = cd[thisLabelIndex];
pt.v += v;
pt.pts.push(i);
if(!pt.hidden) vTotal += v;
if(pt.color === false && colors[i]) {
pt.color = pullColor(colors[i], label);
}
}
}
var shouldSort = (trace.type === 'funnelarea') ? isAggregated : trace.sort;
if(shouldSort) cd.sort(function(a, b) { return b.v - a.v; });
// include the sum of all values in the first point
if(cd[0]) cd[0].vTotal = vTotal;
return cd;
}
function makePullColorFn(colorMap) {
return function pullColor(color, id) {
if(!color) return false;
color = tinycolor(color);
if(!color.isValid()) return false;
color = Color.addOpacity(color, color.getAlpha());
if(!colorMap[id]) colorMap[id] = color;
return color;
};
}
/*
* `calc` filled in (and collated) explicit colors.
* Now we need to propagate these explicit colors to other traces,
* and fill in default colors.
* This is done after sorting, so we pick defaults
* in the order slices will be displayed
*/
function crossTraceCalc(gd, plotinfo) { // TODO: should we name the second argument opts?
var desiredType = (plotinfo || {}).type;
if(!desiredType) desiredType = 'pie';
var fullLayout = gd._fullLayout;
var calcdata = gd.calcdata;
var colorWay = fullLayout[desiredType + 'colorway'];
var colorMap = fullLayout['_' + desiredType + 'colormap'];
if(fullLayout['extend' + desiredType + 'colors']) {
colorWay = generateExtendedColors(colorWay, extendedColorWayList);
}
var dfltColorCount = 0;
for(var i = 0; i < calcdata.length; i++) {
var cd = calcdata[i];
var traceType = cd[0].trace.type;
if(traceType !== desiredType) continue;
for(var j = 0; j < cd.length; j++) {
var pt = cd[j];
if(pt.color === false) {
// have we seen this label and assigned a color to it in a previous trace?
if(colorMap[pt.label]) {
pt.color = colorMap[pt.label];
} else {
colorMap[pt.label] = pt.color = colorWay[dfltColorCount % colorWay.length];
dfltColorCount++;
}
}
}
}
}
/**
* pick a default color from the main default set, augmented by
* itself lighter then darker before repeating
*/
function generateExtendedColors(colorList, extendedColorWays) {
var i;
var colorString = JSON.stringify(colorList);
var colors = extendedColorWays[colorString];
if(!colors) {
colors = colorList.slice();
for(i = 0; i < colorList.length; i++) {
colors.push(tinycolor(colorList[i]).lighten(20).toHexString());
}
for(i = 0; i < colorList.length; i++) {
colors.push(tinycolor(colorList[i]).darken(20).toHexString());
}
extendedColorWays[colorString] = colors;
}
return colors;
}
module.exports = {
calc: calc,
crossTraceCalc: crossTraceCalc,
makePullColorFn: makePullColorFn,
generateExtendedColors: generateExtendedColors
};