Как передать данные из клиента websocket на диаграмму d3 и привязку нокаута - PullRequest
0 голосов
/ 26 марта 2020

Я работаю над графиком в реальном времени, используя pnet core, d3 и knockout. js, и у меня нет большого опыта работы с технологиями. Я получаю полуфункциональный результат, потому что, хотя данные передаются через dataviewmodel в файл привязки, значения y не отображаются на гистограмме. Я добавил несколько примеров данных в viewmodel, просто для отладки. Также в консоли я могу отслеживать массив, и кажется, что файл привязки или dataviewmodel имеют ошибку.

Это мой js код клиента в представлении:

<script language="javascript" type="text/javascript">

        var D3KD = this.D3KD || {};

        (function () {
            var dataViewModel = new D3KD.dataViewModel();
            var protocol = location.protocol === "https:" ? "wss:" : "ws:";
            var wsUri = protocol + "//" + window.location.host + "/ws";
            var socket = new WebSocket(wsUri);  

            socket.onmessage = (event) => {
               ...
                var batteries = randomDataSet(10, 0, 5);

                dataViewModel.addDataPoint(batteries);
}
ko.applyBindings(dataViewModel);
    }());

    </script> 

Это дата-модель:

var D3KD = this.D3KD || {};

(function (namespace) {
  "use strict";
  namespace.dataViewModel = function () {
    var self = this;


    self.barChartData = ko.observableArray([{ name: "er", value: 5 }, { name: "err", value: 6 }, { name: "errr", value: 2 }]);


    self.addDataPoint = function (points) {

      for (var i = 0; i <= points.length; i++) {
        self.barChartData.push({ name: i, value: points[i]});
      }      
    };

  };

}(D3KD));

И это привязка к выбыванию:

ko.bindingHandlers.barChart = {
  init: function (element, valueAccessor) {
    "use strict";

    var margin = { top: 20, right: 20, bottom: 30, left: 40 },
      elementWidth = parseInt(d3.select(element).style("width"), 10),
      elementHeight = parseInt(d3.select(element).style("height"), 10),
      width = elementWidth - margin.left - margin.right,
      height = elementHeight - margin.top - margin.bottom,

      data = ko.unwrap(valueAccessor()),

      svg = d3.select(element)
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

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

    svg.append("g")
      .attr("class", "y axis");

    svg.selectAll(".bar")
      .data(data)
      .enter().append("rect")
      .attr("class", "bar");
    //return { controlsDescendantBindings: true };
  },
  update: function (element, valueAccessor) {
    "use strict";

    var margin = { top: 20, right: 20, bottom: 30, left: 40 },

      elementWidth = parseInt(d3.select(element).style("width"), 10),
      elementHeight = parseInt(d3.select(element).style("height"), 10),

      width = elementWidth - margin.left - margin.right,
      height = elementHeight - margin.top - margin.bottom,
      animationDuration = 750,

      // parsin the data from the data-view-model
      data = ko.unwrap(valueAccessor()),

      svg = d3.select(element).select("svg g"),

      // set the range of the x axis.
      x = d3.scale.ordinal()
        .rangeRoundBands([0, width], 0.1),

      // set the range of the y axis.
      y = d3.scale.linear()
        .range([height, 0]),

      // scale the x axis with the width of the canvas
      xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom"),

      // scale the y axis with the height of the canvas
      yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")

        .ticks(10, "%");

    // setting the domain
    x.domain(data.map(function (d) { return d.name; }));
    y.domain([0, d3.max(data, function (d) { return d.value; })]);

    // drawing the x axis to the canvas
    svg.select("g.x.axis")
      .transition()
      .duration(animationDuration)
      .call(xAxis);

    // drawing the y axis to the canvas
    svg.select("g.y.axis")
      .transition()
      .duration(animationDuration)
      .call(yAxis);

    // drawing the bar rectangles to the canvas.
    svg.selectAll("rect.bar")
      .data(data)
      .transition()
      .duration(animationDuration)
      .attr("x", function (d) { return x(d.name); })
      .attr("width", x.rangeBand())
      .attr("y", function (d) { return y(d.value); })
      .attr("height", function (d) { return height - y(d.value); });
    //return { controlsDescendantBindings: true };
  }
};

В результате получается, что отображается только ось x, но не y (значение):

enter image description here

...