123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- /*
- * <<
- * Davinci
- * ==
- * Copyright (C) 2016 - 2017 EDP
- * ==
- * Licensed 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 { IChartProps } from 'containers/Widget/components/Chart'
- import {
- decodeMetricName,
- metricAxisLabelFormatter
- } from 'containers/Widget/components/util'
- import {
- getLegendOption,
- getGridPositions,
- getDimetionAxisOption,
- getCartesianChartReferenceOptions
- } from './util'
- import { getFormattedValue } from 'containers/Widget/components/Config/Format'
- import { getFieldAlias } from 'containers/Widget/components/Config/Field'
- import ChartTypes from 'containers/Widget/config/chart/ChartTypes'
- import { getMetricsExtendMinAndMax } from './helper'
- export default function (chartProps: IChartProps, drillOptions) {
- const {
- data,
- cols,
- metrics,
- chartStyles,
- // color,
- // tip,
- references
- } = chartProps
- const { legend, spec, doubleYAxis, xAxis, splitLine } = chartStyles
- const { stack, smooth, step, symbol, label } = spec
- const { yAxisLeft, yAxisRight, yAxisSplitNumber } = doubleYAxis
- const { showLabel } = xAxis
- const {
- showVerticalLine,
- verticalLineColor,
- verticalLineSize,
- verticalLineStyle
- } = splitLine
- const labelOption = {
- label: {
- normal: {
- show: label,
- position: 'top'
- }
- }
- }
- const { selectedItems } = drillOptions
- const { secondaryMetrics } = chartProps
- const xAxisData = showLabel ? data.map((d) => d[cols[0].name]) : []
- const seriesData = secondaryMetrics
- ? getAixsMetrics(
- 'metrics',
- metrics,
- data,
- stack,
- labelOption,
- references,
- selectedItems,
- { key: 'yAxisLeft', type: yAxisLeft }
- ).concat(
- getAixsMetrics(
- 'secondaryMetrics',
- secondaryMetrics,
- data,
- stack,
- labelOption,
- references,
- selectedItems,
- { key: 'yAxisRight', type: yAxisRight }
- )
- )
- : getAixsMetrics(
- 'metrics',
- metrics,
- data,
- stack,
- labelOption,
- references,
- selectedItems,
- { key: 'yAxisLeft', type: yAxisLeft }
- )
- const seriesObj = {
- series: seriesData.map((series) => {
- if (series.type === 'line') {
- return {
- ...series,
- symbol: symbol ? 'emptyCircle' : 'none',
- smooth,
- step
- }
- } else {
- return series
- }
- })
- }
- let legendOption
- let gridOptions
- if (seriesData.length > 1) {
- const seriesNames = seriesData.map((s) => s.name)
- legendOption = {
- legend: getLegendOption(legend, seriesNames)
- }
- gridOptions = {
- grid: getGridPositions(
- legend,
- seriesNames,
- 'doubleYAxis',
- false,
- null,
- xAxis,
- xAxisData
- )
- }
- }
- const xAxisSplitLineConfig = {
- showLine: showVerticalLine,
- lineColor: verticalLineColor,
- lineSize: verticalLineSize,
- lineStyle: verticalLineStyle
- }
- const allMetrics = secondaryMetrics
- ? [].concat(metrics).concat(secondaryMetrics)
- : metrics
- const { leftY, rightY } = getMetricsExtendMinAndMax(
- metrics,
- secondaryMetrics,
- data,
- stack,
- yAxisSplitNumber
- )
- const [leftExtentMin, leftExtentMax, leftInterval] = leftY
- const [rightExtentMin, rightExtentMax, rightInterval] = rightY
- const option = {
- tooltip: {
- trigger: 'axis',
- axisPointer: { type: 'cross' },
- formatter(params) {
- const tooltipLabels = [
- getFormattedValue(params[0].name, cols[0].format),
- '<br/>'
- ]
- params.reduce((acc, param) => {
- const { color, value, seriesIndex } = param
- if (color) {
- acc.push(
- `<span class="widget-tooltip-circle" style="background: ${color}"></span>`
- )
- }
- acc.push(
- getFieldAlias(allMetrics[seriesIndex].field, {}) ||
- decodeMetricName(allMetrics[seriesIndex].name)
- )
- acc.push(
- ': ',
- getFormattedValue(value, allMetrics[seriesIndex].format),
- '<br/>'
- )
- return acc
- }, tooltipLabels)
- return tooltipLabels.join('')
- }
- },
- xAxis: getDimetionAxisOption(xAxis, xAxisSplitLineConfig, xAxisData),
- yAxis: [
- {
- type: 'value',
- key: 'yAxisIndex0',
- min: rightExtentMin,
- max: rightExtentMax,
- interval: +rightInterval,
- position: 'right',
- showTitleAndUnit: true,
- name: getYAxisName(secondaryMetrics),
- nameLocation: 'middle',
- nameGap: 50,
- nameRotate: 90,
- nameTextStyle: {
- color: '#666',
- fontFamily: 'PingFang SC',
- fontSize: 12
- },
- ...getDoubleYAxis(doubleYAxis)
- },
- {
- type: 'value',
- key: 'yAxisIndex1',
- min: leftExtentMin,
- max: leftExtentMax,
- interval: +leftInterval,
- position: 'left',
- showTitleAndUnit: true,
- name: getYAxisName(metrics),
- nameLocation: 'middle',
- nameGap: 50,
- nameRotate: 90,
- nameTextStyle: {
- color: '#666',
- fontFamily: 'PingFang SC',
- fontSize: 12
- },
- ...getDoubleYAxis(doubleYAxis)
- }
- ],
- ...seriesObj,
- ...gridOptions,
- ...legendOption
- }
- return option
- }
- export function getAixsMetrics(
- type,
- axisMetrics,
- data,
- stack,
- labelOption,
- references,
- selectedItems,
- axisPosition?: { key: string; type: string }
- ) {
- const seriesNames = []
- const seriesAxis = []
- const referenceOptions = getCartesianChartReferenceOptions(
- references,
- ChartTypes.DoubleYAxis,
- axisMetrics,
- data
- )
- axisMetrics.forEach((m, amIndex) => {
- const decodedMetricName = decodeMetricName(m.name)
- seriesNames.push(decodedMetricName)
- const stackOption =
- stack && axisPosition.type === 'bar' && axisMetrics.length > 1
- ? { stack: axisPosition.key }
- : null
- const itemData = data.map((g, index) => {
- const itemStyle =
- selectedItems &&
- selectedItems.length &&
- selectedItems.some((item) => item === index)
- ? { itemStyle: { normal: { opacity: 1, borderWidth: 6 } } }
- : null
- return {
- value: g[`${m.agg}(${decodedMetricName})`],
- ...itemStyle
- }
- })
- seriesAxis.push({
- name: decodedMetricName,
- type:
- axisPosition && axisPosition.type
- ? axisPosition.type
- : type === 'metrics'
- ? 'line'
- : 'bar',
- ...stackOption,
- yAxisIndex: type === 'metrics' ? 1 : 0,
- data: itemData,
- ...labelOption,
- ...(amIndex === axisMetrics.length - 1 && referenceOptions),
- itemStyle: {
- normal: {
- opacity: selectedItems && selectedItems.length > 0 ? 0.25 : 1
- }
- }
- })
- })
- return seriesAxis
- }
- export function getYAxisName(metrics) {
- return metrics
- .map((m) => (m.field.alias ? m.field.alias : decodeMetricName(m.name)))
- .join(` / `)
- }
- export function getDoubleYAxis(doubleYAxis) {
- const {
- inverse,
- showLine,
- lineStyle,
- lineSize,
- lineColor,
- showLabel,
- labelFontFamily,
- labelFontSize,
- labelColor
- } = doubleYAxis
- return {
- inverse,
- axisLine: {
- show: showLine,
- lineStyle: {
- color: lineColor,
- width: Number(lineSize),
- type: lineStyle
- }
- },
- axisLabel: {
- show: showLabel,
- color: labelColor,
- fontFamily: labelFontFamily,
- fontSize: Number(labelFontSize),
- formatter: metricAxisLabelFormatter
- }
- }
- }
|