提交 364720ba 编写于 作者: S sushuang

Support large bar for some cases (to the data amount of 2e5).

上级 df46e28e
import * as echarts from '../echarts';
import * as zrUtil from 'zrender/src/core/util';
import { layout } from '../layout/barGrid';
import {layout, largeLayout} from '../layout/barGrid';
import '../coord/cartesian/Grid';
import './bar/BarSeries';
......@@ -10,11 +10,13 @@ import '../component/gridSimple';
echarts.registerLayout(zrUtil.curry(layout, 'bar'));
// Should after normal bar layout, otherwise it is blocked by normal bar layout.
echarts.registerLayout(largeLayout);
// Visual coding for legend
echarts.registerVisual(function (ecModel) {
ecModel.eachSeriesByType('bar', function (seriesModel) {
var data = seriesModel.getData();
data.setVisual('legendSymbol', 'roundRect');
});
echarts.registerVisual({
seriesType: 'bar',
reset: function (seriesModel) {
// Visual coding for legend
seriesModel.getData().setVisual('legendSymbol', 'roundRect');
}
});
......@@ -6,5 +6,29 @@ export default BaseBarSeries.extend({
dependencies: ['grid', 'polar'],
brushSelector: 'rect'
brushSelector: 'rect',
/**
* @override
*/
getProgressive: function () {
// Do not support progressive in normal mode.
return this.get('large')
? this.get('progressive')
: false;
},
/**
* @override
*/
getProgressiveThreshold: function () {
// Do not support progressive in normal mode.
var progressiveThreshold = this.get('progressiveThreshold');
var largeThreshold = this.get('largeThreshold');
if (largeThreshold > progressiveThreshold) {
progressiveThreshold = largeThreshold;
}
return progressiveThreshold;
}
});
......@@ -5,7 +5,7 @@ import * as graphic from '../../util/graphic';
import {setLabel} from './helper';
import Model from '../../model/Model';
import barItemStyle from './barItemStyle';
import Path from 'zrender/src/graphic/Path';
var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'barBorderWidth'];
......@@ -18,12 +18,16 @@ export default echarts.extendChartView({
type: 'bar',
render: function (seriesModel, ecModel, api) {
this._updateDrawMode(seriesModel);
var coordinateSystemType = seriesModel.get('coordinateSystem');
if (coordinateSystemType === 'cartesian2d'
|| coordinateSystemType === 'polar'
) {
this._render(seriesModel, ecModel, api);
this._isLargeDraw
? this._renderLarge(seriesModel, ecModel, api)
: this._renderNormal(seriesModel, ecModel, api);
}
else if (__DEV__) {
console.warn('Only cartesian2d and polar supported for bar.');
......@@ -32,9 +36,25 @@ export default echarts.extendChartView({
return this.group;
},
dispose: zrUtil.noop,
incrementalPrepareRender: function (seriesModel, ecModel, api) {
this._clear();
this._updateDrawMode(seriesModel);
},
incrementalRender: function (params, seriesModel, ecModel, api) {
// Do not support progressive in normal mode.
this._incrementalRenderLarge(params, seriesModel);
},
_updateDrawMode: function (seriesModel) {
var isLargeDraw = seriesModel.pipelineContext.large;
if (this._isLargeDraw == null || isLargeDraw ^ this._isLargeDraw) {
this._isLargeDraw = isLargeDraw;
this._clear();
}
},
_render: function (seriesModel, ecModel, api) {
_renderNormal: function (seriesModel, ecModel, api) {
var group = this.group;
var data = seriesModel.getData();
var oldData = this._data;
......@@ -114,10 +134,25 @@ export default echarts.extendChartView({
this._data = data;
},
remove: function (ecModel, api) {
_renderLarge: function (seriesModel, ecModel, api) {
this._clear();
createLarge(seriesModel, this.group);
},
_incrementalRenderLarge: function (params, seriesModel) {
createLarge(seriesModel, this.group, true);
},
dispose: zrUtil.noop,
remove: function (ecModel) {
this._clear(ecModel);
},
_clear: function (ecModel) {
var group = this.group;
var data = this._data;
if (ecModel.get('animation')) {
if (ecModel && ecModel.get('animation')) {
if (data) {
data.eachItemGraphicEl(function (el) {
if (el.type === 'sector') {
......@@ -132,7 +167,9 @@ export default echarts.extendChartView({
else {
group.removeAll();
}
this._data = null;
}
});
var elementCreator = {
......@@ -282,3 +319,53 @@ function getLineWidth(itemModel, rawLayout) {
var lineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0;
return Math.min(lineWidth, Math.abs(rawLayout.width), Math.abs(rawLayout.height));
}
var LargePath = Path.extend({
type: 'largeBar',
shape: {points: []},
buildPath: function (ctx, shape) {
// Drawing lines is more efficient than drawing
// a whole line or drawing rects.
var points = shape.points;
var startPoint = this.__startPoint;
var valueIdx = this.__valueIdx;
for (var i = 0; i < points.length; i += 2) {
startPoint[this.__valueIdx] = points[i + valueIdx];
ctx.moveTo(startPoint[0], startPoint[1]);
ctx.lineTo(points[i], points[i + 1]);
}
}
});
function createLarge(seriesModel, group, incremental) {
// TODO support polar
var data = seriesModel.getData();
var startPoint = [];
var valueIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0;
startPoint[1 - valueIdx] = data.getLayout('valueAxisStart');
var el = new LargePath({
shape: {points: data.getLayout('largePoints')},
incremental: !!incremental,
__startPoint: startPoint,
__valueIdx: valueIdx
});
group.add(el);
setLargeStyle(el, seriesModel, data);
}
function setLargeStyle(el, seriesModel, data) {
var borderColor = data.getVisual('borderColor') || data.getVisual('color');
var itemStyle = seriesModel.getModel('itemStyle').getItemStyle(['color', 'borderColor']);
el.useStyle(itemStyle);
el.style.fill = null;
el.style.stroke = borderColor;
el.style.lineWidth = data.getLayout('barWidth');
}
......@@ -41,6 +41,11 @@ export default SeriesModel.extend({
barMinAngle: 0,
// cursor: null,
large: false,
largeThreshold: 400,
progressive: 5e3,
progressiveChunkMode: 'mod',
// barMaxWidth: null,
// 默认自适应
// barWidth: null,
......
......@@ -26,4 +26,4 @@ function fixPosition(style, labelPositionOutside) {
if (style.textPosition === 'outside') {
style.textPosition = labelPositionOutside;
}
}
\ No newline at end of file
}
......@@ -103,11 +103,8 @@ var CandlestickView = ChartView.extend({
},
_renderLarge: function (seriesModel) {
var group = this.group;
group.removeAll();
createLarge(seriesModel, group);
this._clear();
createLarge(seriesModel, this.group);
},
_incrementalRenderNormal: function (params, seriesModel) {
......@@ -264,15 +261,13 @@ function createLarge(seriesModel, group, incremental) {
}
function setLargeStyle(sign, el, seriesModel, data) {
var normalItemStyleModel = seriesModel.getModel(NORMAL_ITEM_STYLE_PATH);
var suffix = sign > 0 ? 'P' : 'N';
var color = data.getVisual('color' + suffix);
var borderColor = data.getVisual('borderColor' + suffix) || color;
var borderColor = data.getVisual('borderColor' + suffix)
|| data.getVisual('color' + suffix);
// Color must be excluded.
// Because symbol provide setColor individually to set fill and stroke
var itemStyle = normalItemStyleModel.getItemStyle(SKIP_PROPS);
var itemStyle = seriesModel.getModel(NORMAL_ITEM_STYLE_PATH).getItemStyle(SKIP_PROPS);
el.useStyle(itemStyle);
el.style.fill = null;
......
......@@ -4,7 +4,11 @@ import OrdinalScale from '../scale/Ordinal';
import IntervalScale from '../scale/Interval';
import Scale from '../scale/Scale';
import * as numberUtil from '../util/number';
import {calBarWidthAndOffset} from '../layout/barGrid';
import {
prepareLayoutBarSeries,
makeColumnLayout,
retrieveColumnLayout
} from '../layout/barGrid';
import BoundingRect from 'zrender/src/core/BoundingRect';
import '../scale/Time';
......@@ -120,26 +124,26 @@ export function getScaleExtent(scale, model) {
// is base axis
// FIXME
// (1) Consider support value axis, where below zero and axis `onZero` should be handled properly.
// (2) Refactor the logic with `barGrid`. Is it not need to `calBarWidthAndOffset` twice with different extent?
// (2) Refactor the logic with `barGrid`. Is it not need to `makeBarWidthAndOffsetInfo` twice with different extent?
// Should not depend on series type `bar`?
// (3) Fix that might overlap when using dataZoom.
// (4) Consider other chart types using `barGrid`?
// See #6728, #4862, `test/bar-overflow-time-plot.html`
var ecModel = model.ecModel;
if (ecModel && (scaleType === 'time' /*|| scaleType === 'interval' */)) {
var barSeriesModels = [];
var barSeriesModels = prepareLayoutBarSeries('bar', ecModel);
var isBaseAxisAndHasBarSeries;
ecModel.eachSeriesByType('bar', function (seriesModel) {
if (seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d') {
barSeriesModels.push(seriesModel);
isBaseAxisAndHasBarSeries |= seriesModel.getBaseAxis() === model.axis;
}
zrUtil.each(barSeriesModels, function (seriesModel) {
isBaseAxisAndHasBarSeries |= seriesModel.getBaseAxis() === model.axis;
});
if (isBaseAxisAndHasBarSeries) {
// Calculate placement of bars on axis
var barWidthAndOffset = makeColumnLayout(barSeriesModels);
// Adjust axis min and max to account for overflow
var adjustedScale = adjustScaleForOverflow(min, max, model, barSeriesModels);
var adjustedScale = adjustScaleForOverflow(min, max, model, barWidthAndOffset);
min = adjustedScale.min;
max = adjustedScale.max;
}
......@@ -148,18 +152,14 @@ export function getScaleExtent(scale, model) {
return [min, max];
}
function adjustScaleForOverflow(min, max, model, barSeriesModels) {
function adjustScaleForOverflow(min, max, model, barWidthAndOffset) {
// Get Axis Length
var axisExtent = model.axis.getExtent();
var axisLength = axisExtent[1] - axisExtent[0];
// Calculate placement of bars on axis
var barWidthAndOffset = calBarWidthAndOffset(barSeriesModels);
// Get bars on current base axis and calculate min and max overflow
var baseAxisKey = model.axis.dim + model.axis.index;
var barsOnCurrentAxis = barWidthAndOffset[baseAxisKey];
var barsOnCurrentAxis = retrieveColumnLayout(barWidthAndOffset, model.axis);
if (barsOnCurrentAxis === undefined) {
return {min: min, max: max};
}
......
......@@ -791,14 +791,17 @@ var updateMethods = {
scheduler.performDataProcessorTasks(ecModel, payload);
coordSysMgr.update(ecModel, api);
// Current stream render is not supported in data process. So we can update
// stream modes after data processing, where the filtered data is used to
// deteming whether use progressive rendering. And we update stream modes
// after coordinate system updated, then full coord info can be fetched.
// deteming whether use progressive rendering.
updateStreamModes(this, ecModel);
// We update stream modes before coordinate system updated, then the modes info
// can be fetched when coord sys updating (consider the barGrid extent fix). But
// the drawback is the full coord info can not be fetched. Fortunately this full
// coord is not requied in stream mode updater currently.
coordSysMgr.update(ecModel, api);
clearColorPalette(ecModel);
scheduler.performVisualTasks(ecModel, payload);
......
import * as zrUtil from 'zrender/src/core/util';
import {parsePercent} from '../util/number';
import {isDimensionStacked} from '../data/helper/dataStackHelper';
import createRenderPlanner from '../chart/helper/createRenderPlanner';
var STACK_PREFIX = '__ec_stack_';
var LARGE_BAR_MIN_WIDTH = 0.5;
var LargeArr = typeof Float32Array !== 'undefined' ? Float32Array : Array;
function getSeriesStackId(seriesModel) {
return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
......@@ -22,7 +26,7 @@ function getAxisKey(axis) {
* @param {number} [opt.barCategoryGap]
* @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined.
*/
export function getLayoutOnAxis(opt, api) {
export function getLayoutOnAxis(opt) {
var params = [];
var baseAxis = opt.axis;
var axisKey = 'axis0';
......@@ -39,7 +43,7 @@ export function getLayoutOnAxis(opt, api) {
stackId: STACK_PREFIX + i
}, opt));
}
var widthAndOffsets = doCalBarWidthAndOffset(params, api);
var widthAndOffsets = doCalBarWidthAndOffset(params);
var result = [];
for (var i = 0; i < opt.count; i++) {
......@@ -51,8 +55,20 @@ export function getLayoutOnAxis(opt, api) {
return result;
}
export function calBarWidthAndOffset(barSeries, api) {
var seriesInfoList = zrUtil.map(barSeries, function (seriesModel) {
export function prepareLayoutBarSeries(seriesType, ecModel) {
var seriesModels = [];
ecModel.eachSeriesByType(seriesType, function (seriesModel) {
// Check series coordinate, do layout for cartesian2d only
if (isOnCartesian(seriesModel) && !isInLargeMode(seriesModel)) {
seriesModels.push(seriesModel);
}
});
return seriesModels;
}
export function makeColumnLayout(barSeries) {
var seriesInfoList = [];
zrUtil.each(barSeries, function (seriesModel) {
var data = seriesModel.getData();
var cartesian = seriesModel.coordinateSystem;
var baseAxis = cartesian.getBaseAxis();
......@@ -70,7 +86,7 @@ export function calBarWidthAndOffset(barSeries, api) {
var barGap = seriesModel.get('barGap');
var barCategoryGap = seriesModel.get('barCategoryGap');
return {
seriesInfoList.push({
bandWidth: bandWidth,
barWidth: barWidth,
barMaxWidth: barMaxWidth,
......@@ -78,13 +94,13 @@ export function calBarWidthAndOffset(barSeries, api) {
barCategoryGap: barCategoryGap,
axisKey: getAxisKey(baseAxis),
stackId: getSeriesStackId(seriesModel)
};
});
});
return doCalBarWidthAndOffset(seriesInfoList, api);
return doCalBarWidthAndOffset(seriesInfoList);
}
function doCalBarWidthAndOffset(seriesInfoList, api) {
function doCalBarWidthAndOffset(seriesInfoList) {
// Columns info on each category axis. Key is cartesian name
var columnsMap = {};
......@@ -197,22 +213,29 @@ function doCalBarWidthAndOffset(seriesInfoList, api) {
return result;
}
/**
* @param {Object} barWidthAndOffset The result of makeColumnLayout
* @param {module:echarts/coord/Axis} axis
* @param {module:echarts/model/Series} [seriesModel] If not provided, return all.
* @return {Object} {stackId: {offset, width}} or {offset, width} if seriesModel provided.
*/
export function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) {
if (barWidthAndOffset && axis) {
var result = barWidthAndOffset[getAxisKey(axis)];
if (result != null && seriesModel != null) {
return result[getSeriesStackId(seriesModel)];
}
}
}
/**
* @param {string} seriesType
* @param {module:echarts/model/Global} ecModel
* @param {module:echarts/ExtensionAPI} api
*/
export function layout(seriesType, ecModel, api) {
export function layout(seriesType, ecModel) {
var seriesModels = [];
ecModel.eachSeriesByType(seriesType, function (seriesModel) {
// Check series coordinate, do layout for cartesian2d only
if (seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d') {
seriesModels.push(seriesModel);
}
});
var barWidthAndOffset = calBarWidthAndOffset(seriesModels);
var seriesModels = prepareLayoutBarSeries(seriesType, ecModel);
var barWidthAndOffset = makeColumnLayout(seriesModels);
var lastStackCoords = {};
var lastStackCoordsOrigin = {};
......@@ -244,12 +267,7 @@ export function layout(seriesType, ecModel, api) {
var stacked = isDimensionStacked(data, valueDim, baseDim);
var isValueAxisH = valueAxis.isHorizontal();
var valueAxisStart = (
zrUtil.indexOf(baseAxis.getAxesOnZeroOf(), valueAxis) >= 0
|| stacked
)
? valueAxis.toGlobalCoord(valueAxis.dataToCoord(0))
: valueAxis.getGlobalExtent()[0];
var valueAxisStart = getValueAxisStart(baseAxis, valueAxis, stacked);
for (var idx = 0, len = data.count(); idx < len; idx++) {
var value = data.get(valueDim, idx);
......@@ -318,4 +336,76 @@ export function layout(seriesType, ecModel, api) {
}, this);
}
// TODO: Do not support stack in large mode yet.
export var largeLayout = {
seriesType: 'bar',
plan: createRenderPlanner(),
reset: function (seriesModel) {
if (!isOnCartesian(seriesModel) || !isInLargeMode(seriesModel)) {
return;
}
var data = seriesModel.getData();
var cartesian = seriesModel.coordinateSystem;
var baseAxis = cartesian.getBaseAxis();
var valueAxis = cartesian.getOtherAxis(baseAxis);
var valueDim = data.mapDimension(valueAxis.dim);
var baseDim = data.mapDimension(baseAxis.dim);
var valueAxisHorizontal = valueAxis.isHorizontal();
var valueDimIdx = valueAxisHorizontal ? 0 : 1;
var barWidth = retrieveColumnLayout(
makeColumnLayout([seriesModel]), baseAxis, seriesModel
).width;
if (!(barWidth > LARGE_BAR_MIN_WIDTH)) { // jshint ignore:line
barWidth = LARGE_BAR_MIN_WIDTH;
}
return {progress: progress};
function progress(params, data) {
var largePoints = new LargeArr(params.count * 2);
var dataIndex;
var coord = [];
var valuePair = [];
var offset = 0;
while ((dataIndex = params.next()) != null) {
valuePair[valueDimIdx] = data.get(valueDim, dataIndex);
valuePair[1 - valueDimIdx] = data.get(baseDim, dataIndex);
coord = cartesian.dataToPoint(valuePair, null, coord);
largePoints[offset++] = coord[0];
largePoints[offset++] = coord[1];
}
data.setLayout({
largePoints: largePoints,
barWidth: barWidth,
valueAxisStart: getValueAxisStart(baseAxis, valueAxis, false),
valueAxisHorizontal: valueAxisHorizontal
});
}
}
};
function isOnCartesian(seriesModel) {
return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d';
}
function isInLargeMode(seriesModel) {
return seriesModel.pipelineContext && seriesModel.pipelineContext.large;
}
function getValueAxisStart(baseAxis, valueAxis, stacked) {
return (
zrUtil.indexOf(baseAxis.getAxesOnZeroOf(), valueAxis) >= 0
|| stacked
)
? valueAxis.toGlobalCoord(valueAxis.dataToCoord(0))
: valueAxis.getGlobalExtent()[0];
}
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="lib/esl.js"></script>
<script src="lib/config.js"></script>
<script src="lib/jquery.min.js"></script>
<script src="lib/facePrint.js"></script>
<script src="lib/testHelper.js"></script>
<link rel="stylesheet" href="lib/reset.css" />
</head>
<body>
<style>
.test-title {
background: #146402;
color: #fff;
}
</style>
<div id="main0"></div>
<script>
function ValueGenerator(baseValue) {
this._baseValue = baseValue;
}
ValueGenerator.prototype.next = function () {
var value = this._baseValue += Math.random() * 20 - 10;
return Math.max(0, Math.round(value) + 3000);
}
require([
'echarts'
], function (echarts) {
var count = 5e5;
// var count = 1e6;
var xAxisData = [];
var data1 = [];
var data2 = [];
var generator1 = new ValueGenerator(Math.random() * 1000);
// var generator2 = new ValueGenerator(Math.random() * 5000);
for (var i = 0; i < count; i++) {
xAxisData.push('category' + i);
data1.push(generator1.next().toFixed(2));
// data2.push(generator2.next().toFixed(2));
}
var option = {
title: {
text: echarts.format.addCommas(count) + ' Bars',
left: 10
},
legend: {
data: ['bar', 'bar2', 'bar3', 'bar4'],
align: 'left'
},
toolbox: {
// y: 'bottom',
feature: {
magicType: {
type: ['line', 'bar', 'stack', 'tiled']
},
dataZoom: {
yAxisIndex: false
},
dataView: {},
saveAsImage: {
pixelRatio: 2
}
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
dataZoom: [{
// startValue: 48,
// endValue: 99,
type: 'inside'
}, {
// startValue: 48,
// endValue: 99,
type: 'slider'
}],
xAxis: {
data: xAxisData,
silent: false,
splitLine: {
show: false
},
splitArea: {
show: false
}
},
yAxis: {
splitArea: {
show: false
}
},
series: [{
name: 'bar',
type: 'bar',
// stack: 'one',
data: data1,
itemStyle: {
color: 'green'
// borderColor: 'yellow'
},
large: true
// progressiveChunkMode: 'sequential'
// }, {
// show: false,
// name: 'bar2',
// type: 'bar',
// stack: 'one',
// data: data[1]
}]
};
testHelper.create(echarts, 'main0', {
option: option
});
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -34,6 +34,7 @@
// The data count is from a real requirement.
var rawDataCount = 2e5;
// var rawDataCount = 2e2;
function run() {
var data = generateOHLC(rawDataCount);
......@@ -47,16 +48,16 @@
var xValue = +new Date(2011, 0, 1);
var minute = 60 * 1000;
var baseValue = Math.random() * 12000;
var tmpVals = new Array(4);
var boxVals = new Array(4);
var dayRange = 12;
for (var i = 0; i < count; i++) {
baseValue = baseValue + Math.random() * 20 - 10;
for (var j = 0; j < 4; j++) {
tmpVals[j] = (Math.random() - 0.5) * dayRange + baseValue;
boxVals[j] = (Math.random() - 0.5) * dayRange + baseValue;
}
tmpVals.sort();
boxVals.sort();
var idxRandom = Math.random();
var openIdx = Math.round(Math.random() * 3);
......@@ -64,15 +65,17 @@
if (closeIdx === openIdx) {
closeIdx++;
}
var volumn = boxVals[3] * (1000 + Math.random() * 500);
// ['open', 'close', 'lowest', 'highest']
// ['open', 'close', 'lowest', 'highest', 'volumn']
// [1, 4, 3, 2]
data.push([
echarts.format.formatTime('yyyy-MM-dd hh:mm:ss', xValue += minute),
+tmpVals[openIdx].toFixed(2), // open
+tmpVals[3].toFixed(2), // highest
+tmpVals[0].toFixed(2), // lowest
+tmpVals[closeIdx].toFixed(2) // close
+boxVals[openIdx].toFixed(2), // open
+boxVals[3].toFixed(2), // highest
+boxVals[0].toFixed(2), // lowest
+boxVals[closeIdx].toFixed(2), // close
volumn.toFixed(0)
]);
}
......@@ -99,6 +102,11 @@
frameInsight.init(echarts, 'duration');
var upColor = '#ec0000';
var upBorderColor = '#8A0000';
var downColor = '#00da3c';
var downBorderColor = '#008F28';
var option = {
dataset: {
source: rawData
......@@ -137,12 +145,12 @@
right: '10%',
height: 300
},
// {
// left: '10%',
// right: '10%',
// height: 70,
// bottom: 80
// }
{
left: '10%',
right: '10%',
height: 70,
bottom: 80
}
],
xAxis: [
{
......@@ -156,20 +164,19 @@
min: 'dataMin',
max: 'dataMax'
},
// {
// type: 'category',
// gridIndex: 1,
// data: data.categoryData,
// scale: true,
// boundaryGap : false,
// axisLine: {onZero: false},
// axisTick: {show: false},
// splitLine: {show: false},
// axisLabel: {show: false},
// splitNumber: 20,
// min: 'dataMin',
// max: 'dataMax'
// }
{
type: 'category',
gridIndex: 1,
scale: true,
boundaryGap : false,
axisLine: {onZero: false},
axisTick: {show: false},
splitLine: {show: false},
axisLabel: {show: false},
splitNumber: 20,
min: 'dataMin',
max: 'dataMax'
}
],
yAxis: [
{
......@@ -178,26 +185,26 @@
show: true
}
},
// {
// scale: true,
// gridIndex: 1,
// splitNumber: 2,
// axisLabel: {show: false},
// axisLine: {show: false},
// axisTick: {show: false},
// splitLine: {show: false}
// }
{
scale: true,
gridIndex: 1,
splitNumber: 2,
axisLabel: {show: false},
axisLine: {show: false},
axisTick: {show: false},
splitLine: {show: false}
}
],
dataZoom: [
{
type: 'inside',
// xAxisIndex: [0, 1],
xAxisIndex: [0, 1],
start: 10,
end: 100
},
{
show: true,
// xAxisIndex: [0, 1],
xAxisIndex: [0, 1],
type: 'slider',
bottom: 10,
start: 10,
......@@ -210,25 +217,19 @@
type: 'candlestick',
// progressiveMode: 'linear',
// data: data,
itemStyle: {
color: upColor,
color0: downColor,
borderColor: upBorderColor,
borderColor0: downBorderColor
},
encode: {
x: 0,
y: [1, 4, 3, 2]
},
// progressive: false
// progressive: progressive
// tooltip: {
// formatter: function (param) {
// var param = param[0];
// return [
// 'Date: ' + param.name + '<hr size=1 style="margin: 3px 0">',
// 'Open: ' + param.data[0] + '<br/>',
// 'Close: ' + param.data[1] + '<br/>',
// 'Lowest: ' + param.data[2] + '<br/>',
// 'Highest: ' + param.data[3] + '<br/>'
// ].join('')
// }
// }
} //,
},
// {
// name: 'MA5',
// type: 'line',
......@@ -265,13 +266,17 @@
// normal: {opacity: 0.5}
// }
// },
// {
// name: 'Volumn',
// type: 'bar',
// xAxisIndex: 1,
// yAxisIndex: 1,
// data: data.volumns
// }
{
name: 'Volumn',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
large: true,
encode: {
x: 0,
y: 5
}
}
]
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册