聚合物& D3:如何将JSON从元素属性发送到模板

时间:2015-07-28 13:02:51

标签: javascript html json d3.js polymer

我是聚合物的新手,我试图将D3与它结合起来。我修改了现有的Gist,但我有点难过。 我试图将HTML中的Polymer元素属性(barData)中的一些JSON传递给聚合物模板。 JSON作为String传递并解析为计算属性(data)。我已经在barData属性中放置了一些默认值,但是每次使用barData属性创建新元素时都希望覆盖这些值。这不起作用。我创建了另一个名为test的属性,它只是将一个字符串传递给一个段落中显示的测试属性。这工作正常吗?我错过了一些明显的东西吗?

index.HTML

<!DOCTYPE html>
<html>
  <head>
    <script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
    <link rel="import" href="elements/bar-chart2.html">
  </head>
  <body>
    <!--creates chart but with template data set although the test attribute does work-->
    <bar-chart2 barData='[{"letter":"C","frequency":".76"},{"letter":"D","frequency":".03"}]' test="CHEEP"></bar-chart2>
    <!--creates chart but with template data set-->
    <!--<bar-chart2 barData="http://codepen.io/superpikar/pen/kcJDf.js"></bar-chart2>-->
  </body>
</html>

bar-chart2.html

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/iron-input/iron-input.html">
<script type="text/javascript" src="../bower_components/d3/d3.min.js"></script>

<polymer-element name="bar-chart2" attributes="barData">
    <template>
        <div id="chart" class="poly-bars">{{barData}}<p>{{test}}</p></div>
<!--the chart will use the new data after input but I want it to happen on create -->
        <div>
            <input is="iron-input" bind-value="{{barData}}" placeholder="paste data here">
        </div>
    </template>

    <script>
        function Bars(opts) {
            opts = opts || {};
            var margin = opts.margin || {
              top: 20,
                right: 20,
                bottom: 30,
                left: 40
            };
            var width = 960 - margin.left - margin.right;
            var height = 500 - margin.top - margin.bottom;
            var title = opts.title || 'Bar Chart';

            var formatPercent = d3.format('.0%');

            var xValue = function(d) {
                    return d.letter;
                }, // data -> value
                xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1), // value -> display
                xMap = function(d) {
                    return xScale(xValue(d));
                }, // data -> display
                xAxis = d3.svg.axis().scale(xScale).orient('bottom');

            var yValue = function(d) {
                    return d.frequency;
                }, // data -> value
                yScale = d3.scale.linear().range([height, 0]), // value -> display
                yMap = function(d) {
                    return yScale(yValue(d));
                }, // data -> display
                yAxis = d3.svg.axis().scale(yScale).orient('left').tickFormat(formatPercent);

            function type(d) {
                d.frequency = +d.frequency;
                return d;
            }

            function bars(selection) {
                selection.each(function(d, i) {

                    var el = d3.select(this);

                    el.selectAll('svg').remove();

                    var svg = el.append('svg')
                        .attr('title', title)
                        .attr('width', width + margin.left + margin.right)
                        .attr('height', height + margin.top + margin.bottom)
                        .append('g')
                        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

                    xScale.domain(d.map(xValue));
                    yScale.domain([0, d3.max(d, yValue)]);

                    svg.append('g')
                        .attr('class', 'x axis')
                        .attr('transform', 'translate(0,' + height + ')')
                        .call(xAxis);

                    svg.append('g')
                        .attr('class', 'y axis')
                        .call(yAxis)
                        .append('text')
                        .attr('transform', 'rotate(-90)')
                        .attr('y', 6)
                        .attr('dy', '.71em')
                        .style('text-anchor', 'end')
                        .text('Frequency');

                    svg.selectAll('.bar')
                        .data(d)
                        .enter().append('rect')
                        .attr('class', 'bar')
                        .attr('x', xMap)
                        .attr('width', xScale.rangeBand)
                        .attr('y', yMap)
                        .attr('height', function(d) {
                            return height - yMap(d);
                        });
                });
            }

            return bars;
        }

        Polymer({
            is: 'bar-chart2',
            properties: {
                test: {
                    type: String,
                    value: "BOOM"
                },
                barData: {
                    type: String,
                    value: '[{"letter":"A","frequency":".08167"},{"letter":"B","frequency":".01492"}]',
                    reflect: true,
                    notify: true
                },
                width: Number,
                height: {
                    type: Number,
                    value: 400
                },
                data: {
                    type: Array,
                    computed: '_parse(barData)'
                }
            },
            _parse: JSON.parse,

            observers: [
                'dataChanged(data)'
            ],

            created: function() {
                this.bars = new Bars(this);
            },

            dataChanged: function() {
                this._draw();
            },

            _draw: function() {
                if (!this.data) {
                    return;
                }
                if (!this.elem) {
                    return;
                }

                d3.select(this.elem)
                    .datum(this.data).call(this.bars);
            },

            ready: function() {
                this.elem = this.$.chart;
                this._draw();
            }
        });
    </script>
</polymer-element>

2 个答案:

答案 0 :(得分:2)

barData更改为bar-data;

  

将属性名称映射到属性名称时:

     
      
  1. 属性名称将转换为小写属性名称。例如,属性firstName映射到firstname

  2.   
  3. 带有破折号的属性名称通过将每个破折号后面的字符大写,然后删除破折号来转换为camelCase属性名称。例如,属性first-name映射到firstName

  4.   

请查看Polymer doc here

答案 1 :(得分:1)

随处更改barDatabardata(小写),它会起作用。