morrisjs / morris.js

Pretty time-series line graphs
http://morrisjs.github.com/morris.js/
6.92k stars 1.23k forks source link

Style donut chart text #228

Open JessicaStiles opened 11 years ago

JessicaStiles commented 11 years ago

Is there any way you can control the font-size, font-family and font-weight of the donut chart text? When one sections label text is much longer than anothers, the different in font size causes a poor user experience.

tiraeth commented 11 years ago

Not possible in oesmith/master. Somehow standarized in my fork but also not able to change the styling on-the-fly.

There was an idea of providing hovers built with HTML (like line charts) so users could style them and even display in the donut's hole. But it's not (and probably won't be) implemented.

carrascomedina commented 10 years ago

I could control the font-weight by adding attributes and values to a text selector with an !important declaration.

text {
  font-weight: normal !important;
}
fabianrios commented 9 years ago

you can personalized some of them here for example.

Donut.prototype.drawEmptyDonutLabel = function(xPos, yPos, color, fontSize, fontWeight) {
  var text;
  text = this.raphael.text(xPos, yPos, '').attr('font-size', fontSize).attr('fill', "#636972").attr('font-family', "futura-pt");
  if (fontWeight != null) {
    text.attr('font-weight', fontWeight);
  }
  return text;
};
tvrajja commented 9 years ago

how to display multiline label if label length is more. if label is more is not able to read properly. Education & Vocational Rehabilitation/ Employment is displayed in one line, i want to display this label as two / three line label.

code; var TotalExp = 62; Morris.Donut({ element: 'donut-example', data: [ {label: "Download Sales", value: 12}, {label: "In-Store Sales", value: 30}, {label: "Education & Vocational Rehabilitation/ Employment", value: 20} ],

formatter: function (x) { return Math.floor(x) } });

manuchan commented 8 years ago

via jQuery right after calling Morris.Donut $("div svg text").attr("style", "font-family: Roboto").attr("font-weight, "700");

TPRAsh commented 7 years ago

For anyone still struggling to style the text inside the morris donut, adding labelColor to your Morris.Donut object does the trick.

self.some_element = Morris.Donut({ element: 'some_element', data: [{label: 'loading', value: 100}], labelColor: '#fff', colors: self.some_element, });

twobob commented 7 years ago

FWIW we emitted a var enter = '\n'; IIRC to break up long lines and pre-parsed the long string for spaces after a certain character count whilst building the labels. inserting them no less than N and no more than Ω where N and Ω are sensible defaults like say 15 and 30 (or something)

and then walk the original data reformatting. inserting \n for spaces

// Let's presume [["string","string"],[n] ] $.each(SomeUsefulArray, function( index, value ) { var entry={}; entry.value = ParseForSpacesAfterLengthButNotLessThanEvery(value[1], 15 , 30); entry.label = value[0]; datArray.push(entry); labelArray.push(value[0]); // if you want to fudge being able to switch chart types later for any reason });

et cetera.

we styled the charts guts thusly in the main css

#xProfileChart svg text {
   font-family: FontAwesome !important;
}

We found that you may have to insert an additional PREFIX of "\n" to a line broken section to get the effect you desire. Without the title overlaying the other stuff,

Here is that working image

dipalishinde94 commented 6 years ago

I am using morris donut chart but it is rendering first time as NAN and second click its coming correctly. i some one help me to solve this one.. This is my code I am using...

//Initialization for Search fields.. $scope.DriverId = null; $scope.ReportType = 'Overall'; $scope.getDriverReport = function () { showLoader(); DriverService.getDODriverReport(parseInt($localStorage.credentials.user.Company_Id), parseInt($scope.DriverId), $scope.selectedRange.dateStart, $scope.selectedRange.dateEnd, $scope.ReportType, function (err, reportResult) { hideLoader();

    if (reportResult.data.length > 0) {

      $scope.errorMsg = "";//Clearing Error Message Based On response length..
      if ($scope.ReportType == 'Overall') {
        //Block for OverAll Type Report..
        $("#driverreport-loads-donut-chart,#driverreport-amt-donut-chart").empty();//Clearing Data from Morris Charts
        $scope.overAllData = false;//Showing the OverAll Panel..
        $scope.MonthlyData = true;//Hiding the Monthly Panel..
        if (reportResult.data.length == 1) {
          $scope.DriverName = '<span class="fa fa-user"></span> Driver : <b>' + reportResult.data[0]['DriverName'] + '</b>';
        } else {
          $scope.DriverName = '';
        }
        $scope.ReportData = reportResult.data;//Assigning the Response Records to Global Scope variable..
        $scope.Advance = 0;
        $scope.AdvanceDeducted = 0;
        $scope.AdvanceNotDeducted = 0;
        $scope.DriverName = "";
        $scope.Totalmiles = 0;
        $scope.Loadedmiles = 0;
        $scope.TotalLoadCount = 0;
        $scope.TotalAmount = 0;
        $scope.TotalNetAmount = 0;
        $scope.ReimburseAmount = 0;
        $scope.ReimburseDeducted = 0;
        $scope.ReimburseNotDeducted = 0;
        $scope.DeadheadedBefore = 0;
        $scope.DeadheadedAfter = 0;
        $scope.TotalNumberofLoadsPaid = 0;
        $scope.TotalPaidAmountForPaidLoads = 0;
        $scope.TotalNumberofLoadsNotPaid = 0;
        $scope.TotalAmountNeedtoPayforNotPaidLoads = 0;
        for (i = 0; i < reportResult.data.length; i++) {
          console.log('reportResult.data', reportResult.data);
          $scope.Advance += reportResult.data[i]['Advance'];
          $scope.AdvanceDeducted += reportResult.data[i]['AdvanceDeducted'];
          $scope.AdvanceNotDeducted += reportResult.data[i]['AdvanceNotDeducted'];
          $scope.Loadedmiles += reportResult.data[i]['Loadedmiles'];
          $scope.TotalLoadCount += reportResult.data[i]['TotalLoadCount'];
          $scope.DeadheadedBefore += reportResult.data[i]['DeadheadedBefore'];
          $scope.DeadheadedAfter += reportResult.data[i]['DeadheadedAfter'];
          $scope.Totalmiles += ($scope.Loadedmiles + $scope.DeadheadedBefore + $scope.DeadheadedAfter);
          $scope.ReimburseAmount += reportResult.data[i]['ReimburseAmount'];
          $scope.ReimburseDeducted += reportResult.data[i]['ReimburseDeducted'];
          $scope.ReimburseNotDeducted += reportResult.data[i]['ReimburseNotDeducted'];
          $scope.TotalAmount += reportResult.data[i]['TotalAmount'];
          $scope.TotalNumberofLoadsPaid += reportResult.data[i]['TotalNumberofLoadsPaid'];
          $scope.TotalPaidAmountForPaidLoads += reportResult.data[i]['TotalPaidAmountForPaidLoads'];
          $scope.TotalNumberofLoadsNotPaid += reportResult.data[i]['TotalNumberofLoadsNotPaid'];
          $scope.TotalAmountNeedtoPayforNotPaidLoads += reportResult.data[i]['TotalAmountNeedtoPayforNotPaidLoads'];
          $scope.TotalNetAmount += ($scope.TotalAmount - ($scope.Advance + $scope.ReimburseAmount + $scope.TotalPaidAmountForPaidLoads + $scope.TotalAmountNeedtoPayforNotPaidLoads));
        }
        //   console.log($scope.Advance + '...'+ $scope.AdvanceDeducted + '...'+ $scope.AdvanceNotDeducted + '..'+ $scope.Loadedmiles + '..' + $scope.TotalNetAmount + 
        //   '..' + $scope.Totalmiles + '..'+ $scope.TotalLoadCount + '..' + $scope.DeadheadedBefore + '..' + $scope.DeadheadedAfter + '..' + $scope.ReimburseAmount + '..' + $scope.ReimburseDeducted +
        // '..' + $scope.ReimburseNotDeducted + '..' + $scope.TotalAmount + '..' + $scope.TotalNumberofLoadsPaid + '..' + $scope.TotalPaidAmountForPaidLoads + '..' + $scope.TotalNumberofLoadsNotPaid + '..'
        // + $scope.TotalAmountNeedtoPayforNotPaidLoads); 
        renderPieCharts();
        //Local FUnction to Render Pie charts..
        function renderPieCharts() {
          Morris.Donut({
            element: 'driverreport-loads-donut-chart',
            data: [
              {
                label: 'EmptyMiles After',
                value: ($scope.DeadheadedAfter ? $scope.DeadheadedAfter : 0)
              },
              {
                label: 'EmptyMiles Before',
                value: ($scope.DeadheadedBefore ? $scope.DeadheadedBefore : 0)
              },
              {
                label: 'LoadedMiles',
                value: ($scope.Loadedmiles ? $scope.Loadedmiles : 0)
              },
              {
                label: 'Total Loads',
                value: ($scope.TotalLoadCount ? $scope.TotalLoadCount : 0)
              },
              {
                label: 'Paid',
                value: ($scope.TotalNumberofLoadsPaid ? $scope.TotalNumberofLoadsPaid : 0)
              },
              {
                label: 'Not Paid',
                value: ($scope.TotalNumberofLoadsNotPaid ? $scope.TotalNumberofLoadsNotPaid : 0)
              }

            ], //'#b09727','#b09727', '#b09727', '#9c27b0', '#9c27b0','#9c27b0'
            colors: ['#990099', '#990099', '#990099', '#ff8308', '#ff8308', '#ff8308'],

            formatter: function (y) {
              return parseFloat(y).toLocaleString('en-US'); + "";
            }

          });

          Morris.Donut({
            element: 'driverreport-amt-donut-chart',
            data: [{
              label: 'Advance',
              value: ($scope.Advance ? $scope.Advance : 0)
            },
            {
              label: 'Deducted',
              value: ($scope.AdvanceDeducted ? $scope.AdvanceDeducted : 0)
            },
            {
              label: 'Not Deducted',
              value: ($scope.AdvanceNotDeducted ? $scope.AdvanceNotDeducted : 0)
            },
            {
              label: 'Total Amount',
              value: ($scope.TotalAmount ? $scope.TotalAmount : 0)
            },

            {
              label: 'ReimburseAmount',
              value: ($scope.ReimburseAmount ? $scope.ReimburseAmount : 0)
            },
            {
              label: 'ReimburseDeducted',
              value: ($scope.ReimburseDeducted ? $scope.ReimburseDeducted : 0)
            },
            {
              label: 'ReimburseNotDeducted',
              value: ($scope.ReimburseNotDeducted ? $scope.ReimburseNotDeducted : 0)
            },

            {
              label: 'Paid (Amount)',
              value: ($scope.TotalPaidAmountForPaidLoads ? $scope.TotalPaidAmountForPaidLoads : 0)
            },
            {
              label: 'Not Paid(Amount)',
              value: ($scope.TotalAmountNeedtoPayforNotPaidLoads ? $scope.TotalAmountNeedtoPayforNotPaidLoads : 0)
            }], //'#A0D466','#A0D466,'#b06527','#b06527','#e62642'
            colors: ['#33CC33', '#33CC33', '#33CC33', '#4a1ec5', '#6826f6', '#6826f6', '#6826f6', '#ff8308', '#ff8308'],
            formatter: function (y) {
              return parseFloat(y).toLocaleString('en-US', {
                style: 'currency',
                currency: 'USD'
              }); + '';
            }
          });
        };
twobob commented 6 years ago

Have you used Firefox to visually check the data just before you draw the donut? I would check the data before I looked at the lib Total guess your data is null or rubbish from DriverService.getDODriverReport et cetera?