json 世界银行指标测试01

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了json 世界银行指标测试01相关的知识,希望对你有一定的参考价值。

d3.helper = {};

d3.helper.tooltip = function(){
    var tooltipDiv;
    var bodyNode = d3.select('body').node();
    var attrs = {};
    var text = '';
    var styles = {};

    function tooltip (selection) {

        selection.on('mouseover.tooltip', function(pD, pI){
            var name, value;
            // Clean up lost tooltips
            d3.select('body').selectAll('div.tooltip').remove();
            // Append tooltip
            tooltipDiv = d3.select('body').append('div');
            tooltipDiv.attr(attrs);
            tooltipDiv.style(styles);
            var absoluteMousePos = d3.mouse(bodyNode);
            var leftPos = (absoluteMousePos[0] - 50) + 'px';
            var topPos = (absoluteMousePos[1] - 45) + 'px';

            tooltipDiv.style({
                left: leftPos,
                top: topPos,
                position: 'absolute',
                'z-index': 1001,
                width: '200px'
            });
            // Add text using the accessor function, Crop text arbitrarily
            tooltipDiv.style('width', function(d, i){ return (text(pD, pI).length > 80) ? '300px' : null; })
                .html(function(d, i){return text(pD, pI);});
        })
        .on('mousemove.tooltip', function(pD, pI){
            // Move tooltip
            var absoluteMousePos = d3.mouse(bodyNode);
            var leftPos = (absoluteMousePos[0] - 50) + 'px';
            var topPos = (absoluteMousePos[1] - 45) + 'px';
            tooltipDiv.style({
                left: leftPos,
                top: topPos
            });
            // Keep updating the text, it could change according to position
            tooltipDiv.html(function(d, i){ return text(pD, pI); });
        })
        .on('mouseout.tooltip', function(pD, pI){
            // Remove tooltip
            tooltipDiv.remove();
        });

    }

    tooltip.attr = function (_x) {
        if (!arguments.length) return attrs;
        attrs = _x;
        return this;
    };

    tooltip.style = function (_x) {
        if (!arguments.length) return styles;
        styles = _x;
        return this;
    };

    tooltip.text = function (_x) {
        if (!arguments.length) return text;
        text = d3.functor(_x);
        return this;
    };

    return tooltip;
};
iVBORw0KGgoAAAANSUhEUgAABRQAAACgCAIAAADy53d7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpiNTc1OTIzOS1mNGIzLTRhMjAtYWE0MS01Njk3YTI3MTZlMzMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTgyOTk1RTZDM0VFMTFFMzhFMUZBNkMyMzQ0NzMxMjgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTgyOTk1RTVDM0VFMTFFMzhFMUZBNkMyMzQ0NzMxMjgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6M2MxMDI1YWMtZDczZC00ZGY1LThmMzYtMTJlNWM5YjlkZTg5IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOmI1NzU5MjM5LWY0YjMtNGEyMC1hYTQxLTU2OTdhMjcxNmUzMyIvPiA8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
<!DOCTYPE html>
<head>
    <title>World Bank Indicator Viz Test 01</title>
    <link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600' rel='stylesheet' type='text/css'>
    <style type='text/css'>

    body {
        font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
        font-size: 0.8em;
        line-height: 1.6em;
    }

    .container {
        width: 695px;
    }

    .row {
        margin-bottom: 20px;
    }

    .column {
        display: inline-block;
    }
    .column:not(:first-of-type) {
        margin-left: 10px;
    }

    h2 {
        font-size: 22px;
    }

    label {
        display: block;
    }

    select {
        margin-left: 0;
    }

    svg {
        /* force Firefox to display properly - why is this bug occurring? */
        overflow: visible;

        /* TEMP: HARD CODE */
        height: 350px;
    }

    .axis path, .axis line {
        fill: none;
        stroke: #aaa;
        shape-rendering: crispEdges;
    }

    .axis line {
        stroke: #e6e7e8;
    }

    .tick:nth-of-type(2n+1) line {
        stroke: #aaa;
    }

    .tick text {
        font-size: 0.9em;
        fill: #999;
    }

    g.indicator.active {
        cursor: pointer;
    }

    .background {
        fill: white;
        fill-opacity: 0;
    }

    g.indicator.active .background {
        fill: whitesmoke;
        fill-opacity: 1;
    }

    .indicator {
        cursor: pointer;
    }

    text.label {
        /* cursor: pointer; */
        text-align: right;
    }
    text.value {
    }

    .label-today {
        font-size: 0.7em;
        font-weight: bold;
        fill: #888;
        display: none;
    }

    svg .circle-measured, svg .circle-baseline {
        stroke-width: 1;
        stroke: white;
    }

    svg circle:hover {
        cursor: pointer;
    }

    svg circle.highlight {
    }

    svg .circle-targeted {
        fill: white;
        fill-opacity: 0;
        stroke-width: 1.5;
        stroke-opacity: 1;
        stroke: white;
    }

    svg .circle-subtargets {
        fill-opacity: 0;
        stroke-width: 1;
        stroke-opacity: 0.3;
        stroke: white;
        display: none;
    }

    svg .circle-latest {
        fill-opacity: 0.5;
        display: none;
    }

    svg .circle-subtargets.show,
    svg .circle-latest.show,
    g.indicator.active circle {
        display: block;
    }

    svg .today line {
        stroke: red;
        stroke-width: 1;
        stroke-opacity: 0.2;
        stroke-dasharray: 5, 4;
    }

    rect.hoverable {
        cursor: pointer;
        fill: white;
        fill-opacity: 0;
    }

    .indicator-line {
        stroke: #e1e1e1;
        stroke-width: 1;
    }

    .tooltip {
        border-radius: 3px;
        box-shadow: 0 0 5px rgba(0,0,0,0.2);
        padding: 5px;
        color: #333;
        background-color: white;
        text-align: center;
    }
    .tooltip .date {
        font-size: 0.85em;
        color: gray;
    }

    </style>
</head>
<body>

    <div class='container'>
        <div id='filters'>
            <form id='filter'>
                <p><strong>Filter by</strong></p>
                <div class='row'>
                    <div class='column'>
                        <label for='filter-sectors'>Sector</label>
                        <select id='filter-sectors'>
                            <option value='' default>(all sectors)</option>
                        </select>
                    </div>
                    <div class='column'>
                        <label for='filter-themes'>Theme</label>
                        <select id='filter-themes'>
                            <option value='' default>(all themes)</option>
                        </select>
                    </div>
                    <div class='column'>
                        <label for='filter-projects'>Project</label>
                        <select id='filter-projects'>
                            <option value='' default>(all projects)</option>
                        </select>
                    </div>
                    <div class='column'>
                        <button type='reset' id='filter-reset'>Clear filters</button>
                    </div>
                </div>
            </form>
        </div>
        <div id='viz'></div>
        <div id='legend'>
            <h4>Legend (placeholder)</h4>
            <img src='legend.png' width='650' height='80' style='margin-top: -10px;'>
        </div>
        <div id='info'>
            <h2 id='info-title'>More information</h2>
            <div id='info-description'>
                <p>Select an indicator to learn more.</p>
            </div>
        </div>
    </div>

    <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.js'></script>
    <script src='//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js'></script>

    <script src='//cdnjs.cloudflare.com/ajax/libs/d3/3.4.2/d3.min.js'></script>
    <script src='tooltip.js'></script>

    <script src='//cdnjs.cloudflare.com/ajax/libs/moment.js/2.6.0/moment.min.js'></script>
    <script>

        // Get data first
        var dataEndpoint = 'data.json',
            data =[];

        $.get(dataEndpoint, function (response) {

            data = response;

            // Parse dates and values
            for (var k = 0; k < data.length; k++) {
                data[k].baseline.date        = new Date(Date.parse(data[k].baseline.date));
                data[k].baseline.dateRounded = _roundDateToHalfYear(data[k].baseline.date);
                data[k].baseline.value       = parseFloat(data[k].baseline.value);

                data[k].target.date        = new Date(Date.parse(data[k].target.date));
                data[k].target.dateRounded = _roundDateToHalfYear(data[k].target.date);
                data[k].target.value       = parseFloat(data[k].target.value);

                for (var j = 0; j < data[k].measurements.length; j++) {
                    var item = data[k].measurements[j];
                    item.date        = new Date(Date.parse(item.date));
                    item.dateRounded = _roundDateToHalfYear(item.date);
                    item.value       = parseFloat(item.value);
                }
            }

            // Get dropdown options
            var themes = _getArrayOfDataType(data, 'theme');
            var projects = _getArrayOfDataType(data, 'project_name');
            var sectors = _getArrayOfDataType(data, 'sector');

            // Populate dropdowns
            for (var j = 0; j < projects.length; j++) {
                if (_.isUndefined(projects[j]) === true) continue;
                $('#filter-projects').append('<option value="' + projects[j] + '">' + projects[j] + '</option>')
            }
            for (var j = 0; j < themes.length; j++) {
                if (_.isUndefined(themes[j]) === true) continue;
                $('#filter-themes').append('<option value="' + themes[j] + '">' + themes[j] + '</option>')
            }
            for (var j = 0; j < sectors.length; j++) {
                if (_.isUndefined(sectors[j]) === true) continue;
                $('#filter-sectors').append('<option value="' + sectors[j] + '">' + sectors[j] + '</option>')
            }

            // Create SVG viz
            createViz(data)
        });

        $(document).ready(function () {

            $('#filter select').on('change', function (e) {
                var project = $('#filter-projects').val();
                var theme = $('#filter-themes').val();
                var sector = $('#filter-sectors').val();
                var filter = {};
                if (project) filter['project_name'] = project;
                if (theme) filter['theme'] = theme;
                if (sector) filter['sector'] = sector;

                var newData = _.where(data, filter);
                // If nothing is filtered, get the whole thing
                //if (newData.length < 1) newData = data;
                if (!project && !theme && !sector) newData = data;
                createViz(newData);

            })
            /*
            $('#filter-projects').on('change', function (e) {
                // Resets the other filters (hacky)
                document.getElementById('filter-themes').selectedIndex = 0;
                document.getElementById('filter-sectors').selectedIndex = 0;
                // Get the filter
                var value = $('#filter-projects').val();
                var newData = _.where(data, { project_name: value });
                // If nothing is filtered, get the whole thing
                if (newData.length < 1) newData = data;
                createViz(newData);
            });

            $('#filter-themes').on('change', function (e) {
                // Resets the other filters (hacky)
                document.getElementById('filter-projects').selectedIndex = 0;
                document.getElementById('filter-sectors').selectedIndex = 0;
                // Get the filter
                var value = $('#filter-themes').val();
                var newData = _.where(data, { theme: value });
                // If nothing is filtered, get the whole thing
                if (newData.length < 1) newData = data;
                createViz(newData);
            });

            $('#filter-sectors').on('change', function (e) {
                // Resets the other filters (hacky)
                document.getElementById('filter-projects').selectedIndex = 0;
                document.getElementById('filter-themes').selectedIndex = 0;
                // Get the filter
                var value = $('#filter-sectors').val();
                var newData = _.where(data, { sector: value });
                // If nothing is filtered, get the whole thing
                if (newData.length < 1) newData = data;
                createViz(newData);
            });
*/

            $('#filter-reset').on('click', function (e) {
                // Resets viz
                createViz(data);
            })

        });

        function _getArrayOfDataType (data, field) {
            // Uses underscore.js chaining.
            // (1) Selects all the values of a given `field`
            // (2) Sorts alphabetically - TODO: Guarantee alphabetic sort
            // (3) and filters by unique values.
            return _.chain(data)
                    .pluck(field)
                    .sort()
                    .uniq(true)
                    .value();
        }

        // Massive SVG creation function
        function createViz (data) {
            // If there is a previous SVG, remove it
            d3.select('#viz').select('svg').remove();

            // SVG overall dimensions
            var margin = {top: 25, right: 25, bottom: 0, left: 0},
                // width = 960;
                width = 695; // ARTF.af two-column layout maximum width

            var rowSpacing = 60;

            var viewportWidth = width - margin.right - margin.left,
                labelWidth = viewportWidth / 4,
                chartWidth = viewportWidth * (3/4);

            var mockupColor = '#27a9e1',
                baselineCircleColor = '#c34040',
                measuredCircleColor = mockupColor,
                targetCircleColor = baselineCircleColor;

            // color scale
            // TODO: Set colors based on category, not per line
            // c(i) where i = index -> returns a color
            var c = d3.scale.category10();

            // Set up SVG display area
            var svg = d3.select('#viz').append('svg')
                .attr('width', width)
                .append('g')
                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

            // If we don't have a data, display a notice
            if (data.length < 1) {
                // Labels for each indicator
                svg.append('text')
                    .attr('x', viewportWidth / 2)
                    .attr('y', rowSpacing)
                    .attr('text-anchor', 'middle')
                    .text('No indicators match your filter criteria.')
                    .style('fill', 'gray');
                return false;
            }

            var startDate = _getStartDate(data),
                endDate   = _getEndDate(data);

            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

            //             * * *   AXIS FORMATTING   * * *             //

            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

            // Set up the domain and range for the X-axis scale, based on the data we have
            var xScale = d3.time.scale()
                .domain([startDate, endDate])
                .nice(d3.time.year)
                .range([0, chartWidth]);

            // Set up the X-axis itself
            // Tick formatting labels only the year, with empty strings for months
            var xAxis = d3.svg.axis()
                .scale(xScale)
                .ticks(d3.time.month, 6)
                .tickFormat(d3.time.format.multi([
                    ['%Y', function (d) { return (d.getMonth() === 0) ? true : false }],
                    ['', function (d) { return true }]
                ]))
                .orient('top');

            // Further axis formatting on the SVG element
            var xAxisG = svg.append('g')
                .attr('class', 'x axis')
                .attr('transform', 'translate(' + labelWidth + ',' + 0 + ')')
                .call(xAxis)
                .selectAll('text')
                .attr('y', -14)
                .attr('x', -2)
                .style('text-anchor', 'start');

            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

            //             * * *   DATA FORMATTING   * * *             //

            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

            // Data and formatting specific to each data set
            for (var j = 0; j < data.length; j++) {

                var indicator = data[j]

                // Position and radius of circle
                var yPos = (j + 1) * rowSpacing - 5;  // The -5 is a vertical centering hack

                // Create group for each indicator
                var g = svg.append('g').attr('class', 'indicator');

                var gBg = g.append('g').append('rect')
                    .classed('background', true)
                    .attr('x', 0)
                    .attr('y', yPos - (rowSpacing / 2))
                    .attr('width', width)
                    .attr('height', rowSpacing);

                // Add horizontal line
                var gLine = g.append('line')
                    .attr('class', 'indicator-line')
                    .attr('x1', labelWidth)
                    .attr('x2', viewportWidth)
                    .attr('y1', yPos)
                    .attr('y2', yPos);

                // Special rect shape for interaction hover area
                var gHoverArea = g.append('rect')
                    .classed('hoverable', true)
                    .attr('x', 0)
                    .attr('y', yPos - (rowSpacing / 2))
                    .attr('width', viewportWidth)
                    .attr('height', rowSpacing)
                    .on('mouseover.indicator', _indicatorMouseover)
                    .on('mouseout.indicator', _indicatorMouseout)
                    .on('click.indicator', _clickToDiveDeep);

                // Baseline data group
                var gBaselineCircle = g.append('g').attr('class', 'indicator-baseline');

                var baselineCircle = gBaselineCircle.selectAll('circle')
                    .data([indicator.baseline])
                    .enter()
                    .append('circle')
                    .attr('class', 'circle-baseline')
                    .style('fill', baselineCircleColor)
                    .call(d3.helper.tooltip()
                        .attr({ class: 'tooltip' })
                        .text(function (d, i) { return '<strong>' + d.value + ' units</strong><br><span class="date">' + moment(d.date).format('MMMM D, YYYY') + '</span>'; })
                    )
                    .on('mouseover', function (d, i) { d3.select(this).classed('highlight', true); })
                    .on('mouseout', function (d, i) { d3.select(this).classed('highlight', false); })
                    .on('mouseover.indicator', _indicatorMouseover)
                    .on('mouseout.indicator', _indicatorMouseout)
                    .on('click.indicator', _clickToDiveDeep);

                // Subtarget group
                var gSubtargets = g.append('g').attr('class', 'indicator-subtargets');

                var subtargetCircles = gSubtargets.selectAll('circle')
                    .data(_makeSubtargets(indicator))
                    .enter()
                    .append('circle')
                    .classed('circle-subtargets', true)
                    .style('stroke', targetCircleColor)
                    .on('mouseover.indicator', _indicatorMouseover)
                    .on('mouseout.indicator', _indicatorMouseout)
                    .on('click.indicator', _clickToDiveDeep);

                // Measured data group
                var gValues = g.append('g').attr('class', 'indicator-measured');

                var circles = gValues.selectAll('circle')
                    .data(indicator.measurements)
                    .enter()
                    .append('circle')
                    .attr('class', 'circle-measured')
                    .style('fill', measuredCircleColor)
                    .call(d3.helper.tooltip()
                        .attr({ class: 'tooltip' })
                        .text(function (d, i) { return '<strong>' + d.value + ' units</strong><br><span class="date">' + moment(d.date).format('MMMM D, YYYY') + '</span>'; })
                    )
                    .on('mouseover', function (d, i) { d3.select(this).classed('highlight', true); })
                    .on('mouseout', function (d, i) { d3.select(this).classed('highlight', false); })
                    .on('mouseover.indicator', _indicatorMouseover)
                    .on('mouseout.indicator', _indicatorMouseout)
                    .on('click.indicator', _clickToDiveDeep);

                // Latest measured data group
                var gLatestCircle = g.append('g').attr('class', 'indicator-latest');

                var latestCircle = gLatestCircle.selectAll('circle')
                    .data([indicator.measurements[indicator.measurements.length - 1]])
                    .enter()
                    .append('circle')
                    .attr('class', 'circle-latest')
                    .style('fill', measuredCircleColor)
                    .call(d3.helper.tooltip()
                        .attr({ class: 'tooltip' })
                        .text(function (d, i) { return '<strong>' + d.value + ' units</strong><br><span class="date">' + moment(d.date).format('MMMM D, YYYY') + '</span>'; })
                    )
                    .on('mouseover', function (d, i) { d3.select(this).classed('highlight', true); })
                    .on('mouseout', function (d, i) { d3.select(this).classed('highlight', false); })
                    .on('mouseover.indicator', _indicatorMouseover)
                    .on('mouseout.indicator', _indicatorMouseout)
                    .on('click.indicator', _clickToDiveDeep);

                // Target group
                var gTarget = g.append('g').attr('class', 'indicator-targeted');

                var targetCircle = gTarget.selectAll('circle')
                    .data([indicator.target])
                    .enter()
                    .append('circle')
                    .classed('circle-targeted', true)
                    .style('stroke', targetCircleColor)
                    .call(d3.helper.tooltip()
                        .attr({ class: 'tooltip' })
                        .text(function (d, i) { return '<strong>' + d.value + ' units</strong><br><span class="date">' + moment(d.date).format('MMMM D, YYYY') + '</span>'; })
                    )
                    .on('mouseover', function (d, i) { d3.select(this).classed('highlight', true); })
                    .on('mouseout', function (d, i) { d3.select(this).classed('highlight', false); })
                    .on('mouseover.indicator', _indicatorMouseover)
                    .on('mouseout.indicator', _indicatorMouseout)
                    .on('click.indicator', _clickToDiveDeep);

                /*
                var text = g.selectAll('text')
                    .data(indicator['articles'])
                    .enter()
                    .append('text');
                */

                // Radius scale for circle
                // If baseline measurement is lower than the target, it should increase on the X-axis
                // Flip the range if baseline is higher than the target measurement.
                if (indicator.baseline.value < indicator.target.value) {
                    var rScale = d3.scale.linear()
                        .domain([indicator.baseline.value, indicator.target.value])
                        .range([4, 14]);
                } else {
                    var rScale = d3.scale.linear()
                        .domain([indicator.baseline.value, indicator.target.value])
                        .range([14, 4]);
                }

                // Baseline circle
                baselineCircle
                    .attr('cx', function (d) {
                        return labelWidth + xScale(d.dateRounded);
                    })
                    .attr('cy', yPos)
                    .attr('r', function (d) { return rScale(d.value); });

                // Measured circles
                circles
                    .attr('cx', function (d, i) {
                        return labelWidth + xScale(d.dateRounded);
                    })
                    .attr('cy', yPos)
                    .attr('r', function (d) {
                        // If the target is decreasing, and a measurement overshoots it, the
                        // linear scale could result in a r-value less than 0. This would cause
                        // an error because a radius can't be less than 0. For sake of
                        // readability, we'll clamp the minimum radius to 2 pixels.
                        return (rScale(d.value) >= 2) ? rScale(d.value) : 2;
                    });

                // Latest measurement circle
                latestCircle
                    .attr('cx', function (d, i) {
                        return labelWidth + xScale(indicator.target.dateRounded);
                    })
                    .attr('cy', yPos)
                    .attr('r', function (d) {
                        // If the target is decreasing, and a measurement overshoots it, the
                        // linear scale could result in a r-value less than 0. This would cause
                        // an error because a radius can't be less than 0. For sake of
                        // readability, we'll clamp the minimum radius to 2 pixels.
                        return (rScale(d.value) >= 2) ? rScale(d.value) : 2;
                    });

                // Target circle
                targetCircle
                    .attr('cx', function (d) {
                        return labelWidth + xScale(d.dateRounded);
                    })
                    .attr('cy', yPos)
                    .attr('r', function (d) { return rScale(d.value); });

                // Subtarget circles
                subtargetCircles
                    .attr('cx', function (d) {
                        return labelWidth + xScale(d.date);
                    })
                    .attr('cy', yPos)
                    .attr('r', function (d) { return rScale(d.value); });

                /*
                text
                    .attr('y', j*20+25)
                    .attr('x',function (d, i) { return xScale(d[0])-5; })
                    .attr('class','value')
                    .text(function (d){ return d[1]; })
                    .style('fill', mockupColor)
                    .style('display','none');
                */

                // Labels for each indicator
                g.append('text')
                    .attr('x', labelWidth - 30)
                    .attr('y', (j + 1) * rowSpacing)
                    .attr('text-anchor', 'end')
                    .text(indicator['indicator_name'])
                    .style('fill', mockupColor)
                    .on('mouseover', _indicatorMouseover)
                    .on('mouseout', _indicatorMouseout)
                    .on('click', _clickToDiveDeep);
            };

            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

            //             * * *   TODAY INDICATOR   * * *             //

            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

            var gToday = svg.append('g').attr('class', 'today');

            var todayYStart  = -30,
                todayYEnd    = 320,
                todayYHeight = todayYEnd - todayYStart

            // Create the today line
            var today     = new Date(),
                todayXPos = labelWidth + xScale(_roundDateToHalfYear(today)),
                todayLine = gToday.selectAll('line')
                    .data([today])
                    .enter()
                    .append('line')
                    .attr('x1', todayXPos)
                    .attr('x2', todayXPos)
                    .attr('y1', todayYStart)
                    .attr('y2', todayYEnd); // TODO: Don't hardcode the end point

            // Special rect shape for interaction hover area
            var todayHoverRect = gToday.append('rect')
                .classed('hoverable', true)
                .attr('x', todayXPos - 5)
                .attr('y', todayYStart)
                .attr('width', '10')
                .attr('height', todayYHeight)
                .on('mouseover.today', todayMouseover)
                .on('mouseout.today', todayMouseout);

            // Add a label for the indicator that appears on hover
            var todayLabel = gToday.append('text')
                .attr('x', todayXPos)
                .attr('y', todayYEnd)
                .attr('text-anchor', 'middle')
                .text('Now')
                .classed('label-today', true);


            $('circle').on('hover', function (e) {
                console.log('test')
            })

            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

            //                * * *   FUNCTIONS   * * *                //

            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

            function _indicatorMouseover (p) {
                var g = d3.select(this).node().parentNode.parentNode;
                d3.select(g).selectAll('.circle-subtargets').classed('show', true);
                d3.select(g).selectAll('.circle-latest').classed('show', true);
            }

            function _indicatorMouseout (p) {
                var g = d3.select(this).node().parentNode.parentNode;
                d3.select(g).selectAll('.circle-subtargets').classed('show', false);
                d3.select(g).selectAll('.circle-latest').classed('show', false);
            }

            function todayMouseover (p) {
                var g = d3.select(this).node().parentNode;
                d3.select(g).select('text').style('display', 'block');
            }
            function todayMouseout (p) {
                var g = d3.select(this).node().parentNode;
                d3.select(g).select('text').style('display', 'none');
            }

            function _clickToDiveDeep () {
                var g = d3.select(this).node().parentNode.parentNode;
                var gAll = d3.select(g).node().parentNode;

                //if ($(this).hasClas)

                // Deselect all indicators
                d3.select(gAll).selectAll('.active').classed('active', false);
                d3.select(gAll).selectAll('.circle-subtargets').classed('show', false);
                d3.select(gAll).selectAll('.circle-latest').classed('show', false);

                // Clear info box
                $('#info-title').text('');
                $('#info-description').empty();

                // Just show the one clicked
                d3.select(g).classed('active', true);
                d3.select(g).selectAll('.circle-subtargets').classed('show', true);
                d3.select(g).selectAll('.circle-latest').classed('show', true);

                // Display the infos below
                var title = $(this).closest('.indicator').find('text').text();
                $('#info-title').text(title);

                var indicator = _.findWhere(data, { indicator_name: title });
                $('#info-description').append('<p><strong>Project:</strong> ' + indicator.project_name + '</p>');
                $('#info-description').append('<p><strong>Theme:</strong> ' + indicator.theme + '</p>');
                $('#info-description').append('<p><strong>Baseline measurement:</strong> ' + indicator.baseline.value + ' ' + indicator.units + '</p>');
                $('#info-description').append('<p><strong>Target goal:</strong> ' + indicator.target.value + ' ' + indicator.units + '</p>');
                for (var i = 0; i < indicator.description.length; i++) {
                    var paragraph = indicator.description[i];
                    $('#info-description').append('<p>' + paragraph + '</p>');
                }
                $('#info-description').append('<p><a href="#">View the raw data behind this indicator</a></p>');
            }

        }

        // UTILITY FUNCTIONS

        // Gets the earliest start date for the visualization, based on earliest baseline date.
        function _getStartDate (data) {
            var date;

            for (var i = 0; i < data.length; i++) {
                var test = data[i].baseline.dateRounded;
                if (!date || test.getTime() < date.getTime()) {
                    date = test;
                }
            }

            return date;
        }

        // Gets the latest end date for the visualization, based on latest target date.
        function _getEndDate (data) {
            var date;

            // Assumes that earliest start date for visualization is a baseline date.
            for (var i = 0; i < data.length; i++) {
                var test = data[i].target.dateRounded;
                if (!date || test.getTime() > date.getTime()) {
                    date = test;
                }
            }

            return date;
        }

        // Round a given Date object to the nearest 6 months, using D3.
        function _roundDateToHalfYear (date) {
            // TODO: Verify that this is returning optimal rounding
            // TODO: What happens if a rounded date is the same as another measurement?
            var lowerRange = d3.time.month.offset(date, -3);
            var upperRange = d3.time.month.offset(date, 3);
            return d3.time.month.range(lowerRange, upperRange, 6)[0];
        }

        // Returns an object of subtarget dates and values between baseline and target
        function _makeSubtargets (indicator) {
            var baseline   = indicator.baseline;
            var target     = indicator.target;

            // Get all the dates between baseline (inclusive) and target (exclusive)
            var interval   = d3.time.month.range(baseline.dateRounded, target.dateRounded, 6);

            var subtargets = [],
                divisor    = interval.length;

            // Significant digits

            //Function: getSigFigFromNum( num ), provides the significant digits of a number.
            //@num must be a number (base 10) that is a string. example "01"
            var getSigFigFromNum = function( num ){
                if( isNaN( +num ) ){
                    throw new Error( "getSigFigFromNum(): num (" + num + ") is not a number." );
                }
                // We need to get rid of the leading zeros for the numbers.
                num = num.toString();
                num = num.replace( /^0+/, '');
                // re is a RegExp to get the numbers from first non-zero to last non-zero
                var re = /[^0](\d*[^0])?/;
                return ( /\./.test( num ) )? num.length - 1 : (num.match( re ) || [''])[0].length;
            };

            var baselineSigfig = getSigFigFromNum(baseline.value);
            var targetSigfig = getSigFigFromNum(target.value);
            var sigfig = Math.max(baselineSigfig, targetSigfig);
            // don't use sig 0
            if (sigfig < 1) sigfig = 1;

            // Start making a new subtarget array.
            // Note: we start counting at 1 because position 0 of the interval array
            // is the baseline date, which we don't need again.
            for (var i = 1; i < interval.length; i++) {
                if (target.value > baseline.value) {
                    // If target is increasing
                    var difference = target.value - baseline.value;
                    var delta      = (difference / interval.length) * i;
                    var subvalue   = baseline.value + delta;
                } else {
                    // If target is decreasing, flip the calculations
                    var difference = baseline.value - target.value;
                    var delta      = (difference / interval.length) * i;
                    var subvalue   = baseline.value - delta;
                }

                subtargets.push({
                    date:  interval[i],
                    value: parseFloat(subvalue.toPrecision(sigfig))
                });
            }

            return subtargets;

        }

    </script>

</body>
</html>
[
  {
    "indicator_name": "Pregnant women receiving antenatal care",
    "project_name": "AF: Strengthening Health Activities",
    "project_id": "P112446",
    "theme": "Health",
    "status": "Active",
    "units": "number",
    "baseline": {
      "date": "2009-07-01",
      "value": "70353"
    },
    "target": {
      "date": "2013-09-30",
      "value": "119127"
    },
    "measurements": [
      {
        "date": "2009-10-10",
        "value": "79146"
      },
      {
        "date": "2011-12-15",
        "value": "131911"
      }
    ],
    "description": [
      "Jujubes sesame snaps chupa chups muffin sweet cake. Liquorice gingerbread cake dragée. Danish cake chupa chups topping pudding lemon drops. Lollipop tootsie roll soufflé cotton candy. Powder caramels soufflé danish oat cake. Liquorice jujubes biscuit biscuit candy oat cake sugar plum soufflé. Soufflé chocolate caramels. Oat cake bear claw gingerbread ice cream marshmallow macaroon. Biscuit bonbon cotton candy tootsie roll toffee cheesecake.",
      "Cheesecake tiramisu cake bonbon. Lollipop applicake candy donut sugar plum wafer icing wafer cookie. Pudding lemon drops dessert jelly muffin tootsie roll croissant marshmallow jujubes. Carrot cake danish sugar plum tootsie roll muffin cupcake biscuit tart. Jelly beans carrot cake oat cake. Croissant cupcake tart toffee topping liquorice pastry."
    ]
  },
  {
    "indicator_name": "Number of consultations (per person)",
    "project_name": "AF: Strengthening Health Activities",
    "project_id": "P112446",
    "theme": "Health",
    "status": "Active",
    "units": "per person per year",
    "baseline": {
      "date": "2007-12-31",
      "value": "0.9"
    },
    "target": {
      "date": "2013-09-30",
      "value": "1.4"
    },
    "measurements": [
      {
        "date": "2011-05-22",
        "value": "1.2"
      },
      {
        "date": "2011-12-15",
        "value": "1.23"
      },
      {
        "date": "2012-10-15",
        "value": "1.5"
      },
      {
        "date": "2013-06-05",
        "value": "1.55"
      }
    ],
    "description": [
      "Dragée tootsie roll chocolate cake chocolate gingerbread. Marzipan tart cake lemon drops marshmallow topping. Cupcake jelly gummi bears cheesecake icing sweet roll jelly topping tart. Pudding cheesecake oat cake biscuit toffee bonbon apple pie candy canes bonbon. Croissant powder chocolate bar chocolate cake. Sweet dessert topping liquorice marshmallow pie sugar plum.",
      "Dessert pie muffin lemon drops toffee donut. Icing cheesecake chocolate bar cupcake oat cake gummi bears gummi bears bonbon. Icing jujubes fruitcake croissant. Donut cheesecake croissant. Sugar plum candy canes tiramisu biscuit jujubes. Dragée gummies wafer bonbon carrot cake bonbon. Lollipop liquorice halvah halvah liquorice. Candy cake donut gummi bears cotton candy gummies fruitcake gummies."
    ]
  },
  {
    "indicator_name": "Number of female scholarship recipients in Teacher Training Colleges",
    "project_name": "Second Education Quality Improvement Program",
    "project_id": "P106259",
    "theme": "Education",
    "status": "Active",
    "units": "number",
    "baseline": {
      "date": "2008-01-31",
      "value": "0"
    },
    "target": {
      "date": "2014-08-15",
      "value": "5000"
    },
    "measurements": [
      {
        "date": "2010-10-01",
        "value": "584"
      },
      {
        "date": "2011-04-30",
        "value": "1500"
      },
      {
        "date": "2012-06-27",
        "value": "3328"
      },
      {
        "date": "2013-09-06",
        "value": "6234"
      }
    ],
    "description": [
      "Pudding liquorice donut wafer cake macaroon sugar plum. Chupa chups biscuit bear claw topping pastry muffin jujubes brownie pastry. Sesame snaps cotton candy jujubes. Candy halvah marshmallow dragée muffin lollipop apple pie sweet tootsie roll. Jujubes tiramisu macaroon pastry sesame snaps pie marshmallow powder. Tart liquorice gummies tart chocolate bar sugar plum candy canes soufflé donut. Sesame snaps chocolate cake applicake candy canes tootsie roll chocolate cookie bear claw.",
      "Pudding marshmallow gummi bears. Dessert powder muffin donut gummi bears. Biscuit chocolate powder cotton candy icing powder. Powder jujubes chupa chups chocolate cake sweet roll bear claw marshmallow biscuit. Halvah gummies cookie apple pie gingerbread bear claw tiramisu powder. Chocolate bar candy canes cake cupcake tiramisu. Applicake jelly powder. Topping sugar plum dragée tiramisu oat cake wafer lollipop."
    ]
  },
  {
    "indicator_name": "Percentage of active female clients",
    "project_name": "Microfinance for Poverty Reduction",
    "project_id": "P091264",
    "theme": "Livelihood",
    "status": "Active",
    "units": "percentage",
    "baseline": {
      "date": "2006-12-06",
      "value": "70"
    },
    "target": {
      "date": "2010-06-30",
      "value": "65"
    },
    "measurements": [
      {
        "date": "2007-12-31",
        "value": "68"
      },
      {
        "date": "2010-06-30",
        "value": "60"
      }
    ],
    "description": [
      "Cake pudding sweet pie fruitcake marzipan chocolate cake. Cookie tootsie roll apple pie jelly beans oat cake jelly beans soufflé jelly-o candy. Sweet roll gummies pie lollipop halvah gummies candy. Marshmallow caramels chocolate cake donut pastry caramels brownie dragée. Toffee halvah topping donut. Cake toffee donut jelly beans. Wafer pudding carrot cake jujubes jelly beans. Danish cheesecake jelly-o liquorice.",
      "Gingerbread cookie croissant. Pastry ice cream chocolate cake. Liquorice soufflé macaroon. Wafer applicake lemon drops gingerbread halvah tootsie roll apple pie. Liquorice jujubes gingerbread pastry gingerbread. Muffin chocolate bar ice cream jujubes oat cake tiramisu lollipop chocolate cake. Pastry cake tootsie roll jelly beans cotton candy cake cupcake brownie. Croissant croissant sweet jelly beans. Gummi bears dessert gummies powder carrot cake halvah halvah."
    ]
  },
  {
    "indicator_name": "Number of female owned Enterprise groups",
    "project_name": "AF: Rural Enterprise Devt Program",
    "project_id": "P110407",
    "theme": "Livelihood",
    "status": "Active",
    "units": "number",
    "baseline": {
      "date": "2010-06-14",
      "value": "0"
    },
    "target": {
      "date": "2015-01-01",
      "value": "2275"
    },
    "measurements": [
      {
        "date": "2011-05-22",
        "value": "40"
      },
      {
        "date": "2012-05-22",
        "value": "60"
      },
      {
        "date": "2013-12-04",
        "value": "440"
      }
    ],
    "description": [
      "Chocolate bar chocolate bar halvah cheesecake dessert sugar plum powder oat cake marshmallow. Sugar plum sugar plum chupa chups jujubes pie. Ice cream marshmallow powder apple pie gummies cheesecake topping marzipan chupa chups. Sweet roll powder sweet roll. Oat cake jelly-o muffin marshmallow apple pie tart muffin cotton candy dessert. Marshmallow muffin tiramisu dessert marzipan pudding dragée powder tiramisu. Powder gummi bears lollipop powder dragée jujubes bear claw chocolate bar gummies.",
      "Tart jelly beans topping applicake. Jujubes marzipan pudding. Soufflé bonbon marshmallow. Sweet roll icing liquorice pie fruitcake cheesecake. Cookie pudding pudding jelly-o jujubes lemon drops biscuit. Brownie sesame snaps sweet. Wafer brownie lollipop cotton candy soufflé chupa chups pie danish apple pie. Biscuit pastry carrot cake jelly-o tiramisu. Tart gummies marshmallow jujubes. Tart danish pie cotton candy caramels soufflé."
    ]
  }
]

以上是关于json 世界银行指标测试01的主要内容,如果未能解决你的问题,请参考以下文章

普罗米修斯 json 指标

01- 系统性能监控概述

运维监控系统 PIGOSS BSM 为银行运维监控提供全力保障

运维监控系统 PIGOSS BSM 为银行运维监控提供全力保障

性能测试指标

什么是性能测试性能测试目的?