blob: 18197bec28acf37e5bb44baf8c70c6ebb177328b [file] [log] [blame]
/*
* 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 };
}