flotを使用して描画しているチャートがあります。誰かがテキストにカーソルを合わせたときに、データプロットの色を変更したいと思います。現在、何かを強調表示する必要があるたびにチャート全体を再描画することでこれを行っています。これはかなり遅いです(単純なグラフの場合は約30ミリ秒、より複雑なグラフの場合は100ミリ秒)。色を変えるだけなので、もっと速い解決策はありますか?
質問する
5070 次
1 に答える
12
Flotの描画プロセスを最適化するために実行できる即時の手順があります。グラフ上でポイントをオフにする必要がない場合は、これにより描画時間を大幅に短縮できます。shadowSize
また、速度を向上させるために、オプションを0に設定して、シャドウをオフにする必要があります。
これらの2つの調整に加えて、シリーズを個別に強調表示できるように、flotソースコードを変更する必要があります。シリーズを自動または手動で強調表示できる小さなプラグインとともに、まさにそれを実行するパッチを作成しました。パッチとプラグインは、グラフ全体を再描画するよりも最大3倍高速である可能性があります。また、flotの「オーバーレイ」機能を使用するため、シリーズのハイライトを解除するのにかかる時間を実質的に排除します。
以下にjquery.flot.jsのパッチとhighlightSeriesプラグインのソースコードがあり、さまざまな設定の違いやパッチとプラグインの組み合わせを確認できるデモページを作成しました。
フロットパッチ
--- .\jquery.flot.js
+++ .\jquery.flot.js
@@ -147,6 +147,7 @@
plot.setData = setData;
plot.setupGrid = setupGrid;
plot.draw = draw;
+ plot.drawSeries = drawSeries;
plot.getPlaceholder = function() { return placeholder; };
plot.getCanvas = function() { return canvas; };
plot.getPlotOffset = function() { return plotOffset; };
@@ -164,6 +165,7 @@
plot.highlight = highlight;
plot.unhighlight = unhighlight;
plot.triggerRedrawOverlay = triggerRedrawOverlay;
+ plot.drawOverlay = drawOverlay;
plot.pointOffset = function(point) {
return { left: parseInt(axisSpecToRealAxis(point, "xaxis").p2c(+point.x) + plotOffset.left),
top: parseInt(axisSpecToRealAxis(point, "yaxis").p2c(+point.y) + plotOffset.top) };
@@ -1059,7 +1061,7 @@
drawGrid();
for (var i = 0; i < series.length; ++i)
- drawSeries(series[i]);
+ drawSeries(series[i], ctx);
executeHooks(hooks.draw, [ctx]);
@@ -1265,16 +1267,16 @@
placeholder.append(html.join(""));
}
- function drawSeries(series) {
+ function drawSeries(series, ctx) {
if (series.lines.show)
- drawSeriesLines(series);
+ drawSeriesLines(series, ctx);
if (series.bars.show)
- drawSeriesBars(series);
+ drawSeriesBars(series, ctx);
if (series.points.show)
- drawSeriesPoints(series);
+ drawSeriesPoints(series, ctx);
}
- function drawSeriesLines(series) {
+ function drawSeriesLines(series, ctx) {
function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
var points = datapoints.points,
ps = datapoints.pointsize,
@@ -1522,7 +1524,7 @@
ctx.restore();
}
- function drawSeriesPoints(series) {
+ function drawSeriesPoints(series, ctx) {
function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) {
var points = datapoints.points, ps = datapoints.pointsize;
@@ -1675,7 +1677,7 @@
}
}
- function drawSeriesBars(series) {
+ function drawSeriesBars(series, ctx) {
function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
var points = datapoints.points, ps = datapoints.pointsize;
@@ -1942,7 +1944,7 @@
if (hi.series.bars.show)
drawBarHighlight(hi.series, hi.point);
- else
+ else if (hi.series.points.show)
drawPointHighlight(hi.series, hi.point);
}
octx.restore();
ハイライトシリーズプラグイン
/*
Flot plugin for highlighting series.
highlightSeries: {
autoHighlight: true (default) or false
, color: color
}
If "autoHighlight" is true (the default) and the plot's "hoverable" setting is true
series are highlighted when the mouse hovers near an item.
"color" is the color of the highlighted series (default is "red").
The plugin also adds two public methods that allow you to highlight and
unhighlight a series manually by specifying a series by label, index or object.
- highlightSeries(series, [color])
- unHighlightSeries(series)
*/
(function ($) {
var log = (function () {
var out = $("#out");
return function () {
if (!arguments) { return; }
var msg = Array.prototype.slice.call(arguments).join(" ");
if (!out.length) {
out = $("#out");
}
if (out.length) {
out.text(msg);
}
};
})();
var options = {
highlightSeries: {
autoHighlight: true
, color: "black"
, _optimized: true
, _debug: false
}
};
function init(plot) {
var highlightedSeries = {};
var originalColors = {};
function highlightSeries(series, color) {
var
seriesAndIndex = getSeriesAndIndex(series)
, options = plot.getOptions().highlightSeries;
series = seriesAndIndex[1];
highlightedSeries[seriesAndIndex[0]] = series;
originalColors[seriesAndIndex[0]] = series.color;
series.color = color || options.color;
if (options._debug) { var start = new Date(); }
if (options._optimized) {
if (plot.drawOverlay && options._debug) {
plot.drawOverlay();
}
else {
plot.triggerRedrawOverlay();
}
}
else {
plot.draw();
}
if (options._debug) {
log("Time taken to highlight:", (new Date()).getTime() - start.getTime(), "ms");
}
};
plot.highlightSeries = highlightSeries;
function unHighlightSeries(series) {
var
seriesAndIndex = getSeriesAndIndex(series)
, options = plot.getOptions().highlightSeries;
seriesAndIndex[1].color = originalColors[seriesAndIndex[0]];
if (options._debug) { var start = new Date(); }
if (options._optimized) {
delete highlightedSeries[seriesAndIndex[0]];
if (plot.drawOverlay && options._debug) {
plot.drawOverlay();
}
else {
plot.triggerRedrawOverlay();
}
}
else {
plot.draw();
}
if (options._debug) {
log("Time taken to un-highlight:", (new Date()).getTime() - start.getTime(), "ms");
}
};
plot.unHighlightSeries = unHighlightSeries;
plot.hooks.bindEvents.push(function (plot, eventHolder) {
if (!plot.getOptions().highlightSeries.autoHighlight) {
return;
}
var lastHighlighted = null;
plot.getPlaceholder().bind("plothover", function (evt, pos, item) {
if (item && lastHighlighted !== item.series) {
for(var seriesIndex in highlightedSeries) {
delete highlightedSeries[seriesIndex];
}
if (lastHighlighted) {
unHighlightSeries(lastHighlighted);
}
lastHighlighted = item.series;
highlightSeries(item.series);
}
else if (!item && lastHighlighted) {
unHighlightSeries(lastHighlighted);
lastHighlighted = null;
}
});
});
function getSeriesAndIndex(series) {
var allPlotSeries = plot.getData();
if (typeof series == "number") {
return [series, allPlotSeries[series]];
}
else {
for (var ii = 0; ii < allPlotSeries.length; ii++) {
var plotSeries = allPlotSeries[ii];
if (
plotSeries === series
|| plotSeries.label === series
|| plotSeries.label === series.label
) {
return [ii, plotSeries];
}
}
}
}
plot.hooks.drawOverlay.push(function (plot, ctx) {
for(var seriesIndex in highlightedSeries) {
plot.drawSeries(highlightedSeries[seriesIndex], ctx);
}
});
}
$.plot.plugins.push({
init: init,
options: options,
name: "highlightSeries",
version: "1.0"
});
})(jQuery);
于 2010-05-12T06:39:04.293 に答える