Using Flot's Bar Graph in an Android WebView with Highlighting

末鹿安然 提交于 2019-12-10 12:07:27

问题


The issue is unhighlighting bars which are no longer selected in a bar graph plotted by flot in a WebView on Android. Got no other issues drawing the actual graphs (which look beautiful for something so simple btw). I am not extremely knowledgeable in terms of javascript and web design/development but it seems little should have been needed, if it would just work!! :( I believe I'm following the Flot API correctly, if not someone please scream and yell at me.

Hoping someone has done this before, but if not I've got the minimal necessary code to poke at your droids if inquiring minds would like to test. I've tested on two Nexus Ones (both 2.2.1), and have tried targeting with Andriod 1.5 and 2.2 SDKs (my intention is to target 1.5 if possible). I've been attempting to hack away at this for far to long on my own now.

What happens:
1. Graph loads fine with bars. All bars unhighlighted.
2. Select a bar in graph, gets highlighted fine (and a tooltip is placed).
3. Select a different bar in graph, old bar is unhighlighted, old tooltip removed, new bar highlighted and tooltip placed (still no problems).
4. Click in the vast darkness of the graph which should then unhighlight the last bar... but it doesn't.

I've tried disabling flot's autohighlight and manually doing it as well to no avail. Looking into flot itself and only getting down to drawOverlay() where the issue seems to begin... An even more disturbing bug(?) appears if the fill bar option is enabled in the graph, but I'd rather just forget about that for now. I've tried with the latest version of flot from their svn (r290), but made no different from last public release (v0.6). As a complete guess I'm thinking it's an issue with WebKit's javascript implementation (or something specific to Nexus Ones, which wouldn't be so bad), but if there is any ugly hack to just get it to work I'm all ears.

I've thrown the graph data directly into the html/js, rather than deal with showing all the code involved in the Java->javascript handler and callbacks.

The html is placed in 'assets/stats_graph.html' with jquery.js and jquery.flot.js (this will load just fine on its own in firefox):

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="jquery.js"></script>
    <script src="jquery.flot.js"></script>

    <script id="source" language="javascript" type="text/javascript">
        var lastItem = null;
        var plot = null;

        $(document).ready(function () {
            //window.testhandler.loadGraph();

            // bind plotclick here
            $("#graphHolder").bind("plotclick", function (event, pos, item) {
                if (item) {
                    var lastPoint = null;
                    if (lastItem != null)
                        lastPoint = lastItem.datapoint;
                    if (!pointEquals(lastPoint, item.datapoint)) {
                        //if (lastItem != null)
                        //    plot.unhighlight(lastItem.series, lastItem.datapoint);
                        lastItem = item;

                        $("#tooltip").remove();
                        //plot.highlight(item.series, item.datapoint);     
                        showTooltip(item.pageX, item.pageY, item.datapoint[1]);
                    }
                } else if (lastItem != null) {
                    plot.unhighlight(lastItem.series, lastItem.datapoint); // not unhighlighting anything
                    //plot.unhighlight(); // doesn't work either, supposed to unhighlight everything
                    lastItem = null;

                    $("#tooltip").remove();     
                }
            });

            GotGraph();
        });

        /**
         * Show a tooltip above bar in graph
         * @param {int} x Left coordinate of div 
         * @param {int} y Top coordinate of div
         * @param {String} contents text to place in div
         */
        function showTooltip(x, y, contents) {
            $('<div id="tooltip">' + contents + '</div>').css( {
                position: 'absolute',
                display: 'none',
                top: y,
                left: x,
                border: '1px solid #fdd',
                padding: '2px',
                'background-color': '#fee',
                opacity: 0.80
            }).appendTo("body").fadeIn(200);
        }

        /**
         * Draw the graph. This is a callback which will be called by Java
         * 
         * @param {Object} seriesData
         * @param {Object} seriesOptions
         */ 
        function GotGraph() { //seriesData, seriesOptions) {
            var seriesData = [{
                "bars":{"lineWidth":2,"show":true,"barWidth":86400000,"align":"center","fill":false},
                "data":[[1288569600000,10],[1288656000000,5],[1288742400000,12],[1288828800000,20],[1288915200000,14],[1289001600000,3],[1289174400000,22],[1289260800000,20],[1289347200000,10],[1289433600000,5],[1289520000000,12],[1289606400000,20],[1289692800000,14],[1289779200000,35]]}];
            var seriesOptions = {
                "xaxis":{"twelveHourClock":false,"minTickSize":[1,"day"],"tickSize":[1,"day"],"timeformat":"%d","mode":"time"},
                "yaxis":{"min":0},
                "grid":{"clickable":true,"autoHighlight":true,"hoverable":false}};

            plot = $.plot($("#graphHolder"), seriesData, seriesOptions);
        }

        function pointEquals(point1, point2) {
            if (point1 != null && point2 != null &&
                typeof(point1) == typeof(point2) &&
                point1.length == point2.length) {
                var i;
                for (i=0;i<point1.length;i++) {
                    if (point1[i] != point2[i])
                        return false;
                }
                return true;
            }
            return false;
        }
    </script>
  </head>
  <body>
    <div id="graphHolder" STYLE="height:200px;width:400px"></div>
  </body>
</html>

The minimal amount of code necessary in onCreate in startup activity:

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    WebView mytestView = new WebView(this);
    mytestView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    setContentView(mytestView);

    mytestView.setBackgroundColor(0);
    mytestView.getSettings().setJavaScriptEnabled(true);
    mytestView.setClickable(true);
    mytestView.setFocusable(false);
    mytestView.setFocusableInTouchMode(false);
    mytestView.loadUrl("file:///android_asset/stats_graph.html");
}

回答1:


Didn't tried, but looking at the code, calling unhighlight() without args should do.

The source code of my version, for reference:

     function unhighlight(s, point) {
        if (s == null && point == null) {
            highlights = [];
            triggerRedrawOverlay();
        }

        if (typeof s == "number")
            s = series[s];

        if (typeof point == "number")
            point = s.data[point];

        var i = indexOfHighlight(s, point);
        if (i != -1) {
            highlights.splice(i, 1);

            triggerRedrawOverlay();
        }
    }


来源:https://stackoverflow.com/questions/4664369/using-flots-bar-graph-in-an-android-webview-with-highlighting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!