/*
|
* Licensed to the Apache Software Foundation (ASF) under one
|
* or more contributor license agreements. See the NOTICE file
|
* distributed with this work for additional information
|
* regarding copyright ownership. The ASF licenses this file
|
* to you under the Apache License, Version 2.0 (the
|
* "License"); you may not use this file except in compliance
|
* with the License. You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing,
|
* software distributed under the License is distributed on an
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* KIND, either express or implied. See the License for the
|
* specific language governing permissions and limitations
|
* under the License.
|
*/
|
|
import SeriesModel from '../../model/Series';
|
import { trim, isArray, each, reduce } from 'zrender/src/core/util';
|
import { DimensionName, DimensionType, ColorString } from '../../util/types';
|
import {
|
retrieveVisualColorForTooltipMarker,
|
TooltipMarkupBlockFragment,
|
createTooltipMarkup,
|
TooltipMarkupSection
|
} from './tooltipMarkup';
|
import { retrieveRawValue } from '../../data/helper/dataProvider';
|
import { isNameSpecified } from '../../util/model';
|
|
|
export function defaultSeriesFormatTooltip(opt: {
|
series: SeriesModel;
|
dataIndex: number;
|
// `multipleSeries` means multiple series displayed in one tooltip,
|
// and this method only return the part of one series.
|
multipleSeries: boolean;
|
}): TooltipMarkupSection {
|
const series = opt.series;
|
const dataIndex = opt.dataIndex;
|
const multipleSeries = opt.multipleSeries;
|
|
const data = series.getData();
|
const tooltipDims = data.mapDimensionsAll('defaultedTooltip');
|
const tooltipDimLen = tooltipDims.length;
|
const value = series.getRawValue(dataIndex) as any;
|
const isValueArr = isArray(value);
|
const markerColor = retrieveVisualColorForTooltipMarker(series, dataIndex);
|
|
// Complicated rule for pretty tooltip.
|
let inlineValue;
|
let inlineValueType: DimensionType | DimensionType[];
|
let subBlocks: TooltipMarkupBlockFragment[];
|
let sortParam: unknown;
|
if (tooltipDimLen > 1 || (isValueArr && !tooltipDimLen)) {
|
const formatArrResult = formatTooltipArrayValue(value, series, dataIndex, tooltipDims, markerColor);
|
inlineValue = formatArrResult.inlineValues;
|
inlineValueType = formatArrResult.inlineValueTypes;
|
subBlocks = formatArrResult.blocks;
|
// Only support tooltip sort by the first inline value. It's enough in most cases.
|
sortParam = formatArrResult.inlineValues[0];
|
}
|
else if (tooltipDimLen) {
|
const dimInfo = data.getDimensionInfo(tooltipDims[0]);
|
sortParam = inlineValue = retrieveRawValue(data, dataIndex, tooltipDims[0]);
|
inlineValueType = dimInfo.type;
|
}
|
else {
|
sortParam = inlineValue = isValueArr ? value[0] : value;
|
}
|
|
// Do not show generated series name. It might not be readable.
|
const seriesNameSpecified = isNameSpecified(series);
|
const seriesName = seriesNameSpecified && series.name || '';
|
const itemName = data.getName(dataIndex);
|
const inlineName = multipleSeries ? seriesName : itemName;
|
|
return createTooltipMarkup('section', {
|
header: seriesName,
|
// When series name not specified, do not show a header line with only '-'.
|
// This case alway happen in tooltip.trigger: 'item'.
|
noHeader: multipleSeries || !seriesNameSpecified,
|
sortParam: sortParam,
|
blocks: [
|
createTooltipMarkup('nameValue', {
|
markerType: 'item',
|
markerColor: markerColor,
|
// Do not mix display seriesName and itemName in one tooltip,
|
// which might confuses users.
|
name: inlineName,
|
// name dimension might be auto assigned, where the name might
|
// be not readable. So we check trim here.
|
noName: !trim(inlineName),
|
value: inlineValue,
|
valueType: inlineValueType
|
})
|
].concat(subBlocks || [] as any)
|
});
|
}
|
|
function formatTooltipArrayValue(
|
value: unknown[],
|
series: SeriesModel,
|
dataIndex: number,
|
tooltipDims: DimensionName[],
|
colorStr: ColorString
|
): {
|
inlineValues: unknown[];
|
inlineValueTypes: DimensionType[];
|
blocks: TooltipMarkupBlockFragment[];
|
} {
|
// check: category-no-encode-has-axis-data in dataset.html
|
const data = series.getData();
|
const isValueMultipleLine = reduce(value, function (isValueMultipleLine, val, idx) {
|
const dimItem = data.getDimensionInfo(idx);
|
return isValueMultipleLine = isValueMultipleLine
|
|| (dimItem && dimItem.tooltip !== false && dimItem.displayName != null);
|
}, false);
|
|
const inlineValues: unknown[] = [];
|
const inlineValueTypes: DimensionType[] = [];
|
const blocks: TooltipMarkupBlockFragment[] = [];
|
|
tooltipDims.length
|
? each(tooltipDims, function (dim) {
|
setEachItem(retrieveRawValue(data, dataIndex, dim), dim);
|
})
|
// By default, all dims is used on tooltip.
|
: each(value, setEachItem);
|
|
function setEachItem(val: unknown, dim: DimensionName | number): void {
|
const dimInfo = data.getDimensionInfo(dim);
|
// If `dimInfo.tooltip` is not set, show tooltip.
|
if (!dimInfo || dimInfo.otherDims.tooltip === false) {
|
return;
|
}
|
if (isValueMultipleLine) {
|
blocks.push(createTooltipMarkup('nameValue', {
|
markerType: 'subItem',
|
markerColor: colorStr,
|
name: dimInfo.displayName,
|
value: val,
|
valueType: dimInfo.type
|
}));
|
}
|
else {
|
inlineValues.push(val);
|
inlineValueTypes.push(dimInfo.type);
|
}
|
}
|
|
return { inlineValues, inlineValueTypes, blocks };
|
}
|